common gdb commands: gdb --args, finish, where, frame 0, list, break ..., info breakpoints, del <BREAK_NUM>, break ... if <COND> (break if <COND> is true), until, <TAB> for auto-completion
debugging fork syscall: set follow-fork-mode child/parent
debugging exec, excvp, etc.: Add delay loop to second program (into which we will exec): {static int xxx=1; while(xxx >= 1); x++;} to target source code. Then run the original program. After it execs into the second program, use gdb attach: gdb <PROGRAM> `pgrep -n <PROGRAM>`
debugging threads: info threads, thread <THREAD_NUM>, thread apply all where, break ... thread <THREAD_NUM>, set scheduler-locking on/off (default: 'off'; 'on' means that single-stepping steps only the current thread, while other threads remain stopped; in some unusual circumstances, this can lead to deadlock)
WILL FILL IN MORE
Note: display/5i $pc WILL FILL IN
You can find out if your system has debug symbols for the various libraries by looking in: /usr/lib/debug/lib or possibly: /usr/lib/debug/*/lib
The gdb debugger has been set up to automatically detect debug libraries if they are present. If they are present, you can immediately skip to setting up the gdb source directory to point to the source. (cd /tmp/gene; tar xf /usr/src/glibc/eglibc-2.13.tar.xz ) Create the following program as tmp.c:
int main() { sleep(2); return 0; }Then compile it with debugging:
gcc -g -O0 tmp.cIf you don't have a debug library for libc, you will see the following. (This is using gdb-7.3. Note that 'step' does not allow you to step inside the 'sleep' function in libc.so.)
gdb a.out ... (gdb) break main (gdb) run Starting program: /tmp/gene/a.out Breakpoint 1, main () at tmp.c:2 warning: Source file is more recent than executable. 2 sleep(2); (gdb) step 3 return 0;Next, install the debug version of libc:
sudo apt-get install libc6-dbgNow, we can step inside the 'sleep' function and see the line number. But we can't yet see the source code of sleep.s.
(gdb) where #0 __sleep (seconds=2) at ../sysdeps/unix/sysv/linux/sleep.c:43 #1 0x0000000000400507 in main () at tmp.c:2 (gdb) frame 0 #0 __sleep (seconds=2) at ../sysdeps/unix/sysv/linux/sleep.c:43 43 in ../sysdeps/unix/sysv/linux/sleep.c (gdb) list 38 ../sysdeps/unix/sysv/linux/sleep.c: No such file or directory. in ../sysdeps/unix/sysv/linux/sleep.cThe Debian package eglibc-source contains the source code for the glibc used in Debian (libc.so.6). Install that first. (For other libraries, there are ways to get the source code, as modified by Debian.) Next, unpack it. I'll unpack it into /tmp/gene.
sudo apt-get install eglibc-source (cd /tmp/gene; tar xf /usr/src/glibc/eglibc-2.13.tar.xz )So, we set the gdb search path for directoriss containing source code. Note that we are looking for the relative path ../sysdeps/unix/sysv/linux/sleep.c. So, the search path must contain a prefix consistent with
../sysdeps/...
:
(gdb) dir /tmp/gene/eglibc-2.13/sysdeps/ Source directories searched: /tmp/gene/eglibc-2.13/sysdeps:/tmp/gene/eglibc-2.13:$cdir:$cwd (gdb) frame 0 #0 __sleep (seconds=2) at ../sysdeps/unix/sysv/linux/sleep.c:43 43 { (gdb) list 38 /* We are going to use the `nanosleep' syscall of the kernel. But the 39 kernel does not implement the stupid SysV SIGCHLD vs. SIG_IGN 40 behaviour for this syscall. Therefore we have to emulate it here. */ 41 unsigned int 42 __sleep (unsigned int seconds) 43 { 44 const unsigned int max 45 = (unsigned int) (((unsigned long int) (~((time_t) 0))) >> 1); 46 struct timespec ts; 47 sigset_t set, oset;Note that in the dir command above, tab completion works as you type the directory pathname.
For further information, try: