Debugging Guide
Debugging Guide
by Brian Fraser
Last update: Oct 4, 2022
Table of Contents
1. Installing gdb-multiarch........................................................................................................................2
2. GDB......................................................................................................................................................3
3. VS Code for Graphical Debugging.......................................................................................................5
3.1 Makefile in VS Code.....................................................................................................................7
4. Eclipse for Graphical Debugging..........................................................................................................8
4.1 Eclipse Installation and Project Setup...........................................................................................8
4.2 Debugging with Eclipse................................................................................................................9
5. Core Dumps........................................................................................................................................12
6. Valgrind...............................................................................................................................................15
7. Stripping a Binary...............................................................................................................................16
Formatting
1. Commands for the host Linux’s console are show as:
(host)$ echo "Hello PC world!"
2. Commands for the target (BeagleBone) Linux’s console are shown as:
(bbg)$ echo "Hello embedded world!"
3. Commands starting with (gdb) are GDB console commands.
4. Almost all commands are case sensitive in Linux and GDB.
Revision History:
• Oct 2, 2019: Add directions to working with Ubuntu 18.04
• Jan 31, 2021: Add VS Code graphical debugging, update to Ubuntu 20.04
• Feb 16, 2021: Added directions for building via a Makefile in VS Code
• Feb 4, 2022: Added more troubleshooting to valgrind section.
• Oct 4, 2022: Updated for Debian 11.x
3. Troubleshooting:
• If you are having problems getting the correct version to install, you can double check that
apt-get is reading the correct repository to find GDB version 8.2 (or better?).
View GDB-Multiarchitecture:
(host)$ apt-cache showpkg gdb-multiarch
If the desired version of the package is not shown, double check your sources.list file,
re-run “apt-get update”
• Changing GDB multiarch version (only do if needed; older versions of Ubuntu/BBG!)
• apt-get for gdb-multiarch should normally work; however, some version
mismatches between gdbserver on the target and gdb-multiarch on the host are
possible. For example, target gdbserver 7.12.0.20016007 is incompatible with host
gdb-multiarch 8.1 (fails to execute correctly, load libraries, ...). Steps to resolve:
• Remove any existing versions of GDB and GDB multi-architecture from the host:
(host)$ sudo apt-get purge gdb gdb-multiarch
• At the end of the file, add the following lines (change ‘cosmic’ to distro you need):
## Added for GDB 8.2 (replacing 8.1)
deb http://ca.archive.ubuntu.com/ubuntu cosmic main universe
• You may need to use the “fix” option first before the above commands will work:
(host)$ sudo apt-get -f install
1 For Ubuntu 14.xx, add the utopic repository to get gdb-multiarch 7.8.1ubuntu4:
deb http://old-releases.ubuntu.com/ubuntu utopic main universe
Options:
--debug Enable general debugging output.
--remote-debug Enable remote protocol debugging output.
--version Display version information and exit.
--wrapper WRAPPER -- Run WRAPPER to start new programs.
--once Exit after the first connection has closed.
• You can ignore any errors about mapping shared library sections. At the moment we do not
need to worry about debugging these.
• If bt does not yield a meaningful stack, it may mean that you are in some library or OS code
that you do not control. Try setting a break-point in a part of your code you know to be
running and then let execution continue. It should hit your breakpoint and show you
meaningful content.
3. Install the “GDB Debug” extension in VS Code via the Extensions view on the left.
4. Create a launch.json file by Run –> Add Configurations. You may select anything when
prompted, and then overwrite launch.json with the following:2:
{
// SOURCE: https://medium.com/@karel.l.vermeiren/ \
// cross-architecture-remote-debugging-using-gdb-with-visual-studio-code-vscode-on-linux-c0572794b4ef
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// More information at: https://go.microsoft.com/fwlink/linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "GDB debug - custom",
"type": "cppdbg",
"request": "launch",
"program": "~/cmpt433/public/myApps/my_awesome_app_here",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"miDebuggerPath": "/usr/bin/gdb-multiarch",
"miDebuggerServerAddress": "192.168.7.2:2001"
}
]
}
4. Build your project via the menu Terminal → Run Build Task (Ctrl + Shift + B)
• The built-in terminal should now show the results of your build.
5. If your build has any errors you can Ctrl + click on the filename/line-number in the build output
and then press ENTER to have VS Code jump to that location in your code.
then ensure no other versions of Eclipse are installed and repeat the install:
(host)$ sudo apt-get purge eclipse
(host)$ sudo apt-get autoremove
(host)$ sudo snap remove eclipse
(host)$ sudo snap install eclipse
• Note, by default Eclipse expects a clean and all target. You can change these by right-
clicking your project, select Properties; under C/C++ Build, select the Behaviour tab.
• To do this, you must already have the compiled version of your project on the target (via
NFS works). This file must have been compiled with the -g option if you want symbols to
be available (i.e. function/variable names etc).
• Hint: To pass arguments to your program being debugged, use the command such as the
following where the arguments 10, 42, end, of, world are passed in.:
(bbg)$ gdbserver localhost:2001 helloWorld 10 42 end of world
7. On the Host, click the Debug button. It should connect to the target.
• It may ask you if you want to switch to the debug perspective; say yes.
• Use the integrated debugger to step-through and debug your application. The application is
actually run on the target, so any effects of the program will take effect on the target. For
example, printf() statements output through the console and code to flash an LED will
still flash the target's LED.
8. You can switch back to the normal perspective by clicking C/C++ button in the top-right of
Eclipse.
9. Later, to re-debug your application, you will need to:
• Re-run gdbserver on the target:
(bbg)$ gdbserver localhost:2001 helloWorld
• Re-launch the debugger in Eclipse by clicking the drop-down arrow beside the debugger
icon on the toolbar. Then select the GDB launch profile you setup.
• Note that you cannot just click the debug button, as this will launch it locally.
• If you right-click the project and through Debug as... select Local C/C++ Application, it will
not work because you cannot run the project on the local PC (host).
10. Trouble shooting:
• If Eclipse complains that it cannot find the application when you try to debug, you may
need to relaunch the Debug Configuration window, and click "Debug" from there.
• Ensure you have network connectivity between the host and target using ping.
• If the panels and tool bars inside Eclipse seem to be out of place or messed up, try:
1) Go to Window → Perspective → Reset Perspective…, and then click Yes to reset all
views to default locations.
2) If missing tool bar buttons: Window → Show Toolbar
warning: Could not load shared library symbols for 2 libraries, e.g.
/lib/arm-linux-gnueabihf/libc.so.6.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Core was generated by `./segfaulter'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x004d059a in dereferenceIt (ptr=0x0) at segfaulter.c:6
6 return *ptr;
(gdb)
• Or, instead of cross debugging from the host, one can run GDB natively on the target:
(bbg)$ cd /mnt/remote/myApps/
(bbg)$ gdb pathToApplicationThatCrashed core
7. Use the standard GDB commands to debug the application.
• Hint: Start with a back-trace (bt), and print variables (print myVarName)
3. Check Valgrind is working by running it on a simple “hello world” style application or the like:
(bbg)$ valgrind /mnt/remote/myApps/hello_world
Should exit without error. Run it on a program which seg-faults and see its output!
4. Troubleshooting
◦ You can fully remove Valgrind from the target (either the stock version, or the updated
version) using:
(bbg)$ sudo apt-get purge valgrind valgrind-dbg
(bbg)$ sudo apt-get autoremove
◦ If you try to use apt-get after installing the valgrind packages, you may get the error:
You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies:
valgrind : Depends: libc6 (>= 2.28) but 2.24-11+deb9u4 is to be installed
E: Unmet dependencies. Try 'apt --fix-broken install' with no packages
(or specify a solution).
An easy way to resolve this is to remove valgrind/valgrind-dbg (see above note), then
install the package you want with apt-get. If needed, reinstall valgrind as per this guide.
◦ If you run Valgrind and see:
valgrind: m_transtab.c:2459 (vgPlain_init_tt_tc): \
Assertion 'sizeof(TTEntryC) <= 88' failed.
It means you have the incorrect version of Valgrind install; follow directions below to get
newer version.
◦ Note that BBB image version 2018-01-28 includes a buggy version of Valgrind: Valgrind-
3.12.0.SVN. If using this version, you must upgrade it to a newer version:
- You should still use apt-get to install valgrind (above) so that most dependencies are met.
- On the target, download newer version of Valgrind (prompt truncated to fit on page):
$ mkdir ~/valgrind_update
$ cd ~/valgrind_update
$ wget http://ftp.us.debian.org/debian/pool/main/v/valgrind/valgrind_3.14.0-3_armhf.deb
$ wget http://ftp.us.debian.org/debian/pool/main/v/valgrind/valgrind-dbg_3.14.0-3_armhf.deb
- Try to install the updated packages to check what dependencies are unmet:
If it complains about missing dependencies other than those shown above, install those
dependencies. OK to have incorrect version of libc6, libc6-dbg, valgrind-dbg
- If the above step is missing no more dependencies than suggested, then force the install of
the updated Valgrind packages, in spite of missing dependencies:
(bbg)$ sudo dpkg --force-all -i valgrind*.deb
(Reading database ... 36025 files and directories currently installed.)
Preparing to unpack valgrind_3.14.0-3_armhf.deb ...
Unpacking valgrind (1:3.14.0-3) over (1:3.14.0-3) ...
Preparing to unpack valgrind-dbg_3.14.0-3_armhf.deb ...
Unpacking valgrind-dbg (1:3.14.0-3) over (1:3.14.0-3) ...
dpkg: valgrind: dependency problems, but configuring anyway as you requested:
valgrind depends on libc6 (>= 2.28); however:
Version of libc6:armhf on system is 2.24-11+deb9u4.
7. Stripping a Binary
When built with debug information (-g GCC option), the executable can be twice the size. This can
take up too much room on an embedded system, so we may want to strip the version copied to the
target if there is not much room on the target (and don't need it for debugging)..
1. Copy your application (which has debug symbols) to the shared public directory.
2. Check the file size of your application:
(host)$ ls -l helloWorld
3. Strip the binary:
(host)$ arm-linux-gnueabihf-strip helloWorld
4. Check the file size of your application; it should be (much?) smaller.
(host)$ ls -l helloWorld
5. Be careful to use the correct version of the file as needed:
• The target can run the stripped version (or the non-stripped version, if space is permitting).
• The host should debug using the non-stripped version. This way you get debug symbols,
while still having a smaller executable on the target.