blob: 1f5416b87536862f8434ff1690974c685c399abd [file] [log] [blame]
# Debugging Go code (a status report)
2 Nov 2010
Tags: debug, gdb
Summary: What works and what doesn't when debugging Go programs with GDB.
OldURL: /debugging-go-code-status-report
Luuk van Dijk
When it comes to debugging, nothing beats a few strategic print statements
to inspect variables or a well-placed panic to obtain a stack trace.
However, sometimes you’re missing either the patience or the source code,
and in those cases a good debugger can be invaluable.
That's why over the past few releases we have been improving the support
in Gos gc linker (6l,
8l) for GDB, the GNU debugger.
In the latest release (2010-11-02), the 6l and 8l linkers emit DWARF3 debugging
information when writing ELF (Linux,
FreeBSD) or Mach-O (Mac OS X) binaries.
The DWARF code is rich enough to let you do the following:
- load a Go program in GDB version 7.x,
- list all Go, C, and assembly source files by line (parts of the Go runtime are written in C and assembly),
- set breakpoints by line and step through the code,
- print stack traces and inspect stack frames, and
- find the addresses and print the contents of most variables.
There are still some inconveniences:
- The emitted DWARF code is unreadable by the GDB version 6.x that ships with Mac OS X.
We would gladly accept patches to make the DWARF output compatible with
the standard OS X GDB,
but until thats fixed youll need to download,
build, and install GDB 7.x to use it under OS X.
The source can be found at [](
Due to the particulars of OS X youll need to install the binary on a
local file system with `chgrp procmod` and `chmod g+s`.
- Names are qualified with a package name and,
as GDB doesn't understand Go packages, you must reference each item by its full name.
For example, the variable named `v` in package `main` must be referred to
as `'main.v'`, in single quotes.
A consequence of this is that tab completion of variable and function names does not work.
- Lexical scoping information is somewhat obfuscated.
If there are multiple variables of the same name,
the nth instance will have a suffix of the form ‘#n’.
We plan to fix this, but it will require some changes to the data exchanged
between the compiler and linker.
- Slice and string variables are represented as their underlying structure
in the runtime library.
They will look something like `{data = 0x2aaaaab3e320, len = 1, cap = 1}.` For slices,
you must dereference the data pointer to inspect the elements.
Some things don't work yet:
- Channel, function, interface, and map variables cannot be inspected.
- Only Go variables are annotated with type information; the runtime's C variables are not.
- Windows and ARM binaries do not contain DWARF debugging information and, as such, cannot be inspected with GDB.
Over the coming months we intend to address these issues,
either by changing the compiler and linker or by using the Python extensions to GDB.
In the meantime, we hope that Go programmers will benefit from having better
access to this well-known debugging tool.
P.S. The DWARF information can also be read by tools other than GDB.
For example, on Linux you can use it with the sysprof system-wide profiler.