What's new in GDB 6.0 ===================== Michal Ludvig Notes for presentation taken at the "SuSE Labs conference" in Nuremberg, Germany, on 3rd November, 2003. Please see the final slides as well: http://www.logix.cz/michal/doc/gdb6-talk = Separate debug info - Now it's possible to ship stripped down binaries without debug symbols and add these symbols only on demand, for example when generating a backtrace from coredump. - The easiest way is to use elfutils (we have the package in SL9.0). - First compile the program with full debug information: $ gcc -g -o crash crash.c - Split it into two files: crash.stripped to be shipped to the users and crash.dbginfo with the symbol tables, etc.: $ eu-strip -g -f crash.dbginfo -o crash.stripped crash - On the place where the original binary had all debug sections is now a single section called .gnu_debuglink containing the name of the file that contains the debug tables: $ objdump -h crash [...] 22 .bss 00000008 0000000000500928 0000000000500928 00000928 2**2 ALLOC 23 .comment 000000d9 0000000000000000 0000000000000000 00000928 2**0 CONTENTS, READONLY 24 .debug_aranges 00000120 0000000000000000 0000000000000000 00000a10 2**4 CONTENTS, READONLY, DEBUGGING 25 .debug_pubnames 000000b9 0000000000000000 0000000000000000 00000b30 2**0 CONTENTS, READONLY, DEBUGGING 26 .debug_info 00000475 0000000000000000 0000000000000000 00000be9 2**0 CONTENTS, READONLY, DEBUGGING 27 .debug_abbrev 000001ab 0000000000000000 0000000000000000 0000105e 2**0 CONTENTS, READONLY, DEBUGGING 28 .debug_line 0000027e 0000000000000000 0000000000000000 00001209 2**0 CONTENTS, READONLY, DEBUGGING 29 .debug_frame 00000100 0000000000000000 0000000000000000 00001488 2**3 CONTENTS, READONLY, DEBUGGING 30 .debug_str 0000016a 0000000000000000 0000000000000000 00001588 2**0 CONTENTS, READONLY, DEBUGGING 31 .debug_ranges 00000030 0000000000000000 0000000000000000 000016f2 2**0 CONTENTS, READONLY, DEBUGGING $ objdump -h crash.stripped [...] 22 .bss 00000008 0000000000500928 0000000000500928 00000928 2**2 ALLOC 23 .comment 000000d9 0000000000000000 0000000000000000 00000928 2**0 CONTENTS, READONLY 24 .gnu_debuglink 00000014 0000000000000000 0000000000000000 000017e0 2**2 CONTENTS, READONLY All the rest was saved into crash.dbginfo. - To save some more space it is now possible to use binutils' strip: $ ls -l crash.stripped -rwxr-xr-x 1 mludvig users 8232 Oct 23 16:40 crash.stripped $ strip crash.stripped $ ls -l crash.stripped -rwxr-xr-x 1 mludvig users 4536 Oct 23 18:38 crash.stripped - GDB is clever enough to automatically load the detached debug info if it can be found easily. We will rename it for a while to avoid it: $ mv crash.dbginfo crash.dbginfo.noautoload - Generate a fresh new coredump: $ ./crash.stripped Segmentation fault (core dumped) - Loading this binary and core to GDB wouldn't tell us too much: $ gdb crash.stripped core GNU gdb 6.0 Copyright 2003 Free Software Foundation, Inc. [...] This GDB was configured as "x86_64-unknown-linux-gnu"... (no debugging symbols found)... Core was generated by `./crash.stripped'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done. Loaded symbols for /lib64/libc.so.6 Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)... done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 #0 0x0000000000400422 in ?? () (gdb) backtrace #0 0x0000000000400422 in ?? () #1 0x00000000004004a9 in ?? () #2 0x0000000000400465 in ?? () #3 0x00000000004004b8 in ?? () #4 0x0000000000400465 in ?? () #5 0x00000000004004b8 in ?? () #6 0x0000000000400465 in ?? () #7 0x00000000004004b8 in ?? () #8 0x00000000004004fa in ?? () #9 0x0000002a9568ac9e in __libc_start_main () from /lib64/libc.so.6 #10 0x000000000040036a in ?? () (gdb) - Now without quitting GDB we can load the symbols on the fly: (gdb) symbol-file crash.dbginfo.noautoload Reading symbols from crash.dbginfo.noautoload...done. (gdb) backtrace #0 0x0000000000400422 in really_crash (pttl=0x7fbffff124) at crash.c:10 #1 0x00000000004004a9 in crash_here1 (pttl=0x7fbffff144) at crash.c:32 #2 0x0000000000400465 in crash_here2 (pttl=0x7fbffff164) at crash.c:21 #3 0x00000000004004b8 in crash_here1 (pttl=0x7fbffff184) at crash.c:34 #4 0x0000000000400465 in crash_here2 (pttl=0x7fbffff1a4) at crash.c:21 #5 0x00000000004004b8 in crash_here1 (pttl=0x7fbffff1c4) at crash.c:34 #6 0x0000000000400465 in crash_here2 (pttl=0x7fbffff1e4) at crash.c:21 #7 0x00000000004004b8 in crash_here1 (pttl=0x7fbffff20c) at crash.c:34 #8 0x00000000004004fa in main () at crash.c:45 (gdb) - Or we may rename the file with debugging symbols back to it's original name and let GDB handle all the magic for us: $ mv crash.dbginfo.noautoload crash.dbginfo $ gdb crash.stripped core GNU gdb 6.0 [...] This GDB was configured as "x86_64-unknown-linux-gnu"... Core was generated by `./crash.stripped'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib64/libc.so.6...done. Loaded symbols for /lib64/libc.so.6 Reading symbols from /lib64/ld-linux-x86-64.so.2...done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 #0 0x0000000000400422 in really_crash (pttl=0x7fbffff124) at crash.c:10 10 *ptr = *pttl; (gdb) backtrace #0 0x0000000000400422 in really_crash (pttl=0x7fbffff124) at crash.c:10 #1 0x00000000004004a9 in crash_here1 (pttl=0x7fbffff144) at crash.c:32 #2 0x0000000000400465 in crash_here2 (pttl=0x7fbffff164) at crash.c:21 #3 0x00000000004004b8 in crash_here1 (pttl=0x7fbffff184) at crash.c:34 #4 0x0000000000400465 in crash_here2 (pttl=0x7fbffff1a4) at crash.c:21 #5 0x00000000004004b8 in crash_here1 (pttl=0x7fbffff1c4) at crash.c:34 #6 0x0000000000400465 in crash_here2 (pttl=0x7fbffff1e4) at crash.c:21 #7 0x00000000004004b8 in crash_here1 (pttl=0x7fbffff20c) at crash.c:34 #8 0x00000000004004fa in main () at crash.c:45 (gdb) = AMD64+i386 integrated - So far we had to use gdb32 for debugging 32 bit binaries on amd64 systems. GDB 6.0 brings support for both 32b and 64b applications in the same binary. = Native Posix Thread Library (NPTL) support - Debugging a NPTL threads requires a special support on the GDB side. - Only the background has changed - there is no difference between debugging NPTL and non-NPTL code. = New backtrace mechanism - With the new backtrace mechanism it's now possible to write specialized unwinding functions for different parts of the stack, e.g. one unwinder for dwarf2, another for sighandler, next for pure assembler functions without debug info, etc. = Java debugging - It is possible to debug Java programs compiled to native binary format by 'gcj' from the GCC suite. - Sample session: $ gcj -g -o Hello --main=Hello Hello.java $ gdb ./Hello GNU gdb 6.0 [...] This GDB was configured as "x86_64-unknown-linux-gnu"... (gdb) break 'Hello::main(JArray*)' Breakpoint 1 at 0x400b60: file Hello.java, line 2. (gdb) run Starting program: /ttt/64/tst/java/Hello [New Thread 16384 (LWP 22930)] [New Thread 32769 (LWP 22932)] [New Thread 16386 (LWP 22933)] [Switching to Thread 16384 (LWP 22930)] Breakpoint 1, 0x0000000000400b60 in Hello.main(java.lang.String[]) (arg=@501020) at Hello.java:2 2 public static void main (String arg[]) { Current language: auto; currently java (gdb) next 3 System.out.println ("Hello world"); (gdb) next Hello world 4 } (gdb) continue Continuing. Program exited normally. = Dwarf2 used more widely - Unwinding based on Dwarf2 informations along with Variable tracking lets you debug even optimized code. - Compile the example with optimizations: $ gcc -O2 -fomit-frame-pointer -g -o crash crash.c $ ./crash Segmentation fault (core dumped) - First try to examine the core with GDB 5.3: $ gdb-5.3 crash core GNU gdb 5.3 [...] This GDB was configured as "i586-suse-linux"... Core was generated by `./crash'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 #0 0x0804831b in really_crash (pttl=0xbffff4e8) at crash.c:10 10 *ptr = *pttl; (gdb) bt #0 0x0804831b in really_crash (pttl=0xbffff4e8) at crash.c:10 #1 0x00000000 in ?? () (gdb) - Now give it a try with GDB 6.0: $ gdb-6.0 crash core GNU gdb 5.3.92 [...] This GDB was configured as "i586-suse-linux"... Core was generated by `./crash'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/i686/libc.so.6...done. Loaded symbols for /lib/i686/libc.so.6 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 #0 0x0804831b in really_crash (pttl=0xbffff4e8) at crash.c:10 10 *ptr = *pttl; (gdb) bt #0 0x0804831b in really_crash (pttl=0xbffff4e8) at crash.c:10 #1 0x0804839e in crash_here1 (pttl=0xbffff4f8) at crash.c:32 #2 0x0804835d in crash_here2 (pttl=0xbffff508) at crash.c:21 #3 0x080483b0 in crash_here1 (pttl=0xbffff518) at crash.c:34 #4 0x0804835d in crash_here2 (pttl=0xbffff528) at crash.c:21 #5 0x080483b0 in crash_here1 (pttl=0xbffff538) at crash.c:34 #6 0x0804835d in crash_here2 (pttl=0xbffff548) at crash.c:21 #7 0x080483b0 in crash_here1 (pttl=0xbffff554) at crash.c:34 #8 0x080483fd in main () at crash.c:45 (gdb) = Many other new features, new architectures supported, etc.