AndWass C++
dark theme

Debugging QEMU

Feb 13, 2019

In Hello eppOS I got a basic Hello World going with stdout via UART. This allows us to print messages and have them appear in the console in much the same as a normal program. Now we should add debugging capabilities to the mix as well.

GDB and QEMU

The command we haved used so far to launch QEMU has been qemu-system-arm -M lm3s811evb -s -kernel build/eppos. This simply starts the emulator and immediately starts running the code. This is less than ideal when we want to debug our code since we might miss what we actually want to look at. So when debugging we should use the following command instead: qemu-system-arm -M lm3s811evb -s -S -kernel build/eppos. Notice the extra -S (capital S), which will freeze the MCU at startup. This allows us to attach a debugger before any code is being run.

The option -s (lowercase s) tells QEMU to allow gdb connections on TCP port 1234. So these two options together is all we need to start debugging.

First connection

For this you will need two terminals available. Start the emulator with the command qemu-system-arm -M lm3s811evb -s -S -kernel build/eppos in the first terminal. After this, use the second terminal and run the command arm-none-eabi-gdb build/eppos. This will open a GDB shell. Now to connect to the emulator enter the following command in the GDB shell: target remote localhost:1234.

You should now be connected to the program running inside QEMU.

QEMU GDB

The program can be controlled and inspected as usual via the GDB terminal.

VSCode integration

Now being able to use the GDB terminal for debugging is nice and all, but I like to debug using a GUI. And since I chose VSCode as an “IDE” for eppOS, we should integrate with this. The only thing we have to do to integrate with VSCode is to add a launch configuration to the project-local .vscode/launch.json.

My entire launch.json file looks like this

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "C++ Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceRoot}/build/eppos",
            "miDebuggerServerAddress": "localhost:1234",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceRoot}",
            "environment": [],
            "externalConsole": true,
            "launchCompleteCommand": "exec-run",
            "windows": {
                "MIMode": "gdb",
                "miDebuggerPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\8 2018-q4-major\\bin\\arm-none-eabi-gdb.exe"
            }
        }
    ]
}

The important configurations is "miDebuggerServerAddress": "localhost:1234" and

"windows": {
    "MIMode": "gdb",
    "miDebuggerPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\8 2018-q4-major\\bin\\arm-none-eabi-gdb.exe"
}

If you are using Linux you will obviously have to change "windows" to "linux" and change the "miDebuggerPath" value and so on.

With this simple launch configuration we can again launch QEMU for debugging, but instead of running GDB in a terminal simply start debugging in VSCode. Pretty nifty!

Note thought that we are compiling with -Os (set in the toolchain file) which means optimize for size, so even though we have debug symbols available and everything, you might get some weird debug results, like lines being skipped etc.

AndWass C++ — C++ in an embedded world

Last updated: 2019-03-17 16:25:48 +0000