Showing posts with label gdb. Show all posts
Showing posts with label gdb. Show all posts

Sunday, 2 February 2020

Debugging C++ program in VSCode on Linux

Let's assume we have VSCode running in Ubuntu 18.04 and the following project structure:

cpp-demo/
cpp-demo/main.cpp
cpp-demo/src/foo.cpp
cpp-demo/include/foo.hpp


Let's assume we want to name the build output cpp-demo and place it at project's root directory:

cpp-demo/cpp-demo


To build and debug it we need to have

cpp-demo/.vscode/tasks.json
cpp-demo/.vscode/launch.json


Building


tasks.json contains build instructions. From the main menu (CTRL+SHIFT+P), choose Tasks: Configure Default Build Task and then g++ build active file. This will create a /.vscode/tasks.json file and open it in the editor. A task will be created there and we need to edit it like this:


cpp-demo/.vscode/tasks.json:


{
    "tasks": [
        {
            "type": "shell",
            "label": "g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-g",
                "${workspaceFolder}/main.cpp",
                "${workspaceFolder}/src/*.cpp",
                "-I",
                "${workspaceFolder}/include",
                "-o",
                "${workspaceFolder}/cpp-demo"
            ],
            "options": {
                "cwd": "/usr/bin"
            },
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ],
    "version": "2.0.0"
}

To run the build task defined in tasks.json, press Ctrl+Shift+B or from the main menu choose Tasks: Run Build Task. This will run g++ compiler and create the output binary. To run it, open a new terminal (in VSCode) and run:

./cpp-demo

For the full list of variables used in VSCode configuration files see Visual Studio Code Variables Reference and visual studio code - VSCode environment variables besides ${workspaceRoot} - Stack Overflow.


If we want g++ to have verbose output we can add to list of arguments:

"-v"

If we want linker to create map files (where we can see all mangled names of functions):

"-Xlinker",
"-Map=${workspaceFolder}/output.map",

Debugging


launch.json contains debugger settings.  From the main menu, choose Debug: Add Configuration... and then choose C++ (GDB/LLDB). You'll then see a dropdown for various predefined debugging configurations. Choose g++ build and debug active file. This creates a launch.json file and opens it in the editor. We need to edit it a bit e.g. to set correct name of the binary in program:

cpp-demo/.vscode/launch.json:

{
    // 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": "g++ build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/cpp-demo",
            "args": [],
            "stopAtEntry": true,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "g++ build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

Current working folder (the one opened in VSCode, cpp-demo in our case) is workspace so ${workspaceFolder} contains path to it.

To start debugging, place some breakpoints in source code, press F5 or from the main menu choose Debug: Start Debugging


References:


Get Started with C++ and Mingw-w64 in Visual Studio Code
Get Started with C++ and Windows Subsystem for Linux in Visual Studio Code
Configure launch.json for C/C++ debugging in Visual Studio Code
"g++" and "c++" compiler - Stack Overflow
c++ - What is the difference between g++ and gcc? - Stack Overflow
Compiling with g++

Sunday, 9 April 2017

Building and debugging C++ code in VSCode on Ubuntu

We have "Hello, world!" example in main.cpp file and want to build it with g++ compiler and debug it with gdb debugger in VSCode on Ubuntu.

Packages


C/C++ for Visual Studio Code (ms-vscode.cpptools)
C++ Intellisense (austin.code-gnu-global) (optional)

Building


We have to create and set up a task.

Open Command Palette (CTRL+SHIFT+P).
Type in task and select Tasks: Configure Task Runner and then Others.
tasks.json gets created in workspace's .vscode directory and shows up in the editor.

VSCode defines variables that can be used in tasks.json.

We can verify what will each of them expand into if we simply change args value for echo command in the default version of the config file.

tasks.json:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "echo",
"isShellCommand": true,
"args": ["${file}"],
"showOutput": "always"
}

If we press combination CTRL+SHIFT+B, the output will be something like:
/home/user/dev/cpp/my_project/.vscode/tasks.json

Similarly, ${workspaceRoot} expands to the path to the workspace's root directory so we just have to append the name of the .cpp file to get its full path:

tasks.json:
...
"args": ["${workspaceRoot}/main.cpp"],
...

Running the task now gives the following output:
/home/user/dev/cpp/my_project/main.cpp

If we change command to g++...

tasks.json:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "g++",
"isShellCommand": true,
"args": ["${workspaceRoot}/main.cpp"],
"showOutput": "always"
}

...after hitting CTRL+SHIFT+B g++ compiler compiles main.cpp and a.out appears in the my_project directory.

Running


If we hit F5, this launches the program.

launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "C++ Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true,
"linux": {
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
"osx": {
"MIMode": "lldb"
},
"windows": {
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
},
{
"name": "C++ Attach",
"type": "cppdbg",
"request": "attach",
"program": "enter program name, for example ${workspaceRoot}/a.out",
"processId": "${command:pickProcess}",
"linux": {
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
"osx": {
"MIMode": "lldb"
},
"windows": {
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
}
]
}

Debugging


In order to enable adding breakpoints we have to enable creation of debug information when building the source code. It is enough if we add -g to g++ arguments:

tasks.json:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "g++",
"isShellCommand": true,
"args": ["-g", "${workspaceRoot}/main.cpp"],
"showOutput": "always"
}