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

Friday, August 13, 2010

gdb: source code location mapping on startup

When you run gdb, you usually have to add source code directories using the “dir” command. This is okay if your code lies within a single directory, but if the code you’re debugging jumps across files in various directories, you’ll end up running “dir” several times, and this can be quite cumbersome.
The solution isn’t as simple as specifying the top-level (root) directory where your source code is checked out, because gdb won’t try to find matching source files recursively in the directory tree. gdb only checks the current directory (i.e. where you launched gdb from), and other directories specified via “dir” for matching source files.
Fortunately, there’s an elegant and simple solution to this problem:
To add directories to gdb automatically, so that you don't have to point out the source code dirs manually each time you start gdb, just specify the “substitute-path” like this in your .gdbinit file:
set substitute-path 
/sandbox/builds/appframework_dev/  /data/source/branches/appframework_dev

This tells gdb that the source files that it was initially expecting at “/sandbox/builds/appframework_dev” (which is the location of the source code on the build machine, where you got the binaries that you are debugging), are mapped to the local directory (on your test machine) at “/data/source/branches/appframework_dev”

see this relevant discussion on stackoverflow for this and other approaches to this problem

EDIT: it appears that I had already blogged this little nugget of gdb goodness last year, along with a few more interesting gdb tidbits

Thursday, March 4, 2010

gdb: set a conditional breakpoint

(gdb) break LinkedList<int>::remove
Breakpoint 1 at 0x29fa0: file main.cc, line 52.
(gdb)
(gdb) condition 1 item_to_remove==1


Another way to accomplish this:

break LinkedList<int>::remove if (item_to_remove==1)


source:
http://www.cs.cmu.edu/~gilpin/tutorial/#3.4

Wednesday, February 3, 2010

linux:debugging with gdb uses sigtrap internally

SIGTRAP is used as a mechanism for a debugger to be notified when the
process it's debugging hits a breakpoint.

A typical way for something like GDB to use it would be something like
this:

- The user asks gdb to set a breakpoint at a certain address in the
  target process.  gdb uses ptrace to replace the instruction at that
  address with the "int3" instruction, which generates a debug
  exception.  It also uses ptrace to ask that the process be stopped
  when SIGTRAP is raised.
- When the target process hits that address, the exception is
  generated.  The kernel treats this as raising a SIGTRAP signal.  The
  process is stopped and gdb is notified.
- gdb lets the user examine the state of the target process.  When the
  user is ready to continue, gdb replaces the int3 with the instruction
  that had originally been there, and uses ptrace to tell the kernel to
  restart the target process from that instruction.  AFAIK it would also
  normally tell the kernel not to deliver the SIGTRAP signal to the
  process, since by default that would kill it.  
So it would normally be
  irrelevant how you are handling SIGTRAP (SIG_IGN or SIG_DFL or a
  handler) because the target will never know it occurred.

(Discovered this information thanks to bug 31715)

source

Thursday, October 22, 2009

gdb: incredibly useful stuff!

For ages, I'd wanted gdb to search for the source file recursively inside a given "dir". Now I finally figured out how to accomplish this. Not by a 'recursive dir search', but by setting a 'substitute path' in gdb. This makes life so much easier now! Woohoo! :D

Much much thanks to this source for setting substitute-paths for gdb:

You know, by using a set substitute-path <library-source-path>
installed-source-path
in the $HOME/.gdbinit file it is possible to
install the library source somewhere and have gdb replace the path
where the library's debug info says the source should be with where
you've installed the library's source.

On my system, for example, by using the 'strings' command, I'm able
to see that glibmm's debug info says that the source should be found
in /build/buildd/glibmm2.4-2.14.2/. I actually installed glibmm's
source in /usr/src/glibmm2.4-2.14.2. So by including the line set
substitute-path /build/buildd /usr/src
in ~/.gdbinit, gdb has no
problems finding glibmm's source any more.

This works with all debuggers (even nemiver) as long as ~/.gdbinit is
processed by gdb when it starts up. :-)


So this is my current ~/.gdbinit file:
set substitute-path /sandbox/builds/appframework_dev /data/source/branches/appframework_dev
And I tested it on piidentity.net right away. IT'S AWESOME! Works right outta da box!

You can now automatically "list" code immedidately after attaching gdb to an httpd process - totally painlessly. This is so much better than having to set each "dir" in gdb for each source directory you wanted to "list" as you debugged it. I love "set substitute-path" - it rocks!


Some more cool gdb stuff I learnt today:
  • interpreter-exec mi "-file-list-exec-source-files"
    (which is equivalent to "info sources")
  • interpreter-exec mi "-file-list-exec-source-file"
    (which is equivalent to "info source")
  • GDB has a ncurses-based GUI called TUI mode! Whoa!
    http://sources.redhat.com/gdb/current/onlinedocs/gdb_26.html