Local testing in VSC on C++ - How to use debug features

Hi !
I am starting to have a nice setup for testing on the C++ track in Visual Studio Code, using File Watcher to run make each time I save the exercise’s .cpp file or its _test.cpp file.

So I can run the tests fine, and manage to solve exercises, but sometimes I wish to use VSC’s debug features to observe what’s going on on a finer level : set breakpoints, watch variables, enter functions… (for info I configure it with LLDB in launch.json)

I am quite new to C++ development. When I started learning it, and debugging in VSC, I would have a main.cpp file, plus other .h and .cpp.
But with Exercism, since exercises don’t seem to have a main.cpp file, I don’t know where to debug from. I have tried :

  • setting up breakpoints in the exercise .cpp or _test.cpp files, which throws errors.
  • creating a main.cpp file, including my exercise header, declaring a variable I want to test, doing a basic function call and printing the result. I get linker errors.
  • looking at the existing file structure, with /test/catch.hpp, couldn’t make much sense of it.

Does anyone also use VSC to solve exercises locally on the C++ track, and if so, how to you manage to use the debug features ?

Thanks :slight_smile:

i am not using file watcher so i don’t know if this work or not but here what i do to debug c++/cmake project on vscode (linux os)
requirement:
gcc/clang, gdb/lldb, cmake
cmake tools vscode extension (microsoft)
c/c++ vscode extension (microsoft)

clone exercism project using exercism-cli
open workspace + configure cmake (usually selecting compiler)
open terminal, and type make -C build (or where your cmake Build Directory setting point to) to build project
if there is no syntax error in your code you will have binary file (exe) in your build directory usually the same as your cpp source code name, select that file and copy relative path name.
configure launch.json into something like this

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/perfect-numbers",   <- paste relative path here
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

now put break point at your project source code *.cpp or at *_test.cpp and hit f5 to debug.

cmiiw, and sorry English is not my primary language. from indonesia btw hehe

1 Like

Aaaah, thank you so much, I hadn’t modified the "program" value !

It now works, although it keeps warning me about “errors” in the catch.hpp file, but I just click “debug anyway”.

Since I am using LLDB, I thought I’d show my config file, since it’s a bit different. For info my working directory is the whole cpp dir, so the .vscode folder is at its root. I’ve also used predefined variable ${fileDirnameBasename} to avoid writing the exercise slug :

// launch.json
{
    "version": "2.0.0",
    "configurations": [
        {
            "name": "C/C++: g++ build and debug active file",
            "type": "lldb",
            "request": "launch",
            "program": "${fileDirname}/build/${fileDirnameBasename}",
            "args": [],
            "cwd": "${fileDirname}",
            "preLaunchTask": "Make"
        }
    ]
}

This is referencing a custom task “Make”, so here is my tasks config as well.
There is also a task for when I download a new exercise, creating the build folder and running cmake…, I just use the Command Palette > Run Task > Cmake init. I guess it’d be nice to automate this each time I download a new exercise but I haven’t looked into how to do this yet.

// tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Cmake init",
            "type": "shell",
            "command": "mkdir build; cd build; cmake -G 'Unix Makefiles' ..",
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": []
        },
        {
            "label": "Make",
            "type": "shell",
            "command": "/usr/bin/make",
            "options": {
                "cwd": "${fileDirname}/build"
            },
            "group": "test"
        }
    ]
}

And since I mentioned File Watcher, here is what I added to my settings file, this way Make is run each time I save a .cpp or .h file :

// settings.json
{
    "cmake.configureOnOpen": false,
    "files.associations": {
        "__bit_reference": "cpp",
        // (... so many...)
        "*.tcc": "cpp"
    },
    "filewatcher.commands": [
        {
            "match": "\\.[cpp|h]",
            "vscodeTask": ["workbench.action.tasks.runTask", "Make"],
            "event": "onFileChange"
        }
    ]
}
1 Like