Tuesday, December 17, 2013

Resource Management : GDB

Debugging is a very important aspect for a Developer. A developer once in his life time will do a debugging for his code.The debugging range from a printing a messages or using a debugger to get more insight into the code and what it does at a specific point.

Before a bug can be fixed, the source of the bug must be located. For example, with segmentation faults, it is useful to know on which line of code the seg fault is occuring. Once the line of code in question has been found, it is useful to know about the values in that method, who called the method, and why (specifically) the error is occuring. Using a debugger makes finding all of this information very simple.

Most linux versions come with a GNU debugger, gdb.  Gdb lets you see the internal structure of a program, print out variable values, set breakpoints and single step through source code. It makes an extremely powerful tool for fixing problems in program code.

In this article we will see how we can debug using GDB and various ways of doing that. This article is purely a introduction article (since I don’t even got complete control on the tool J)

Here is a Sample Java Program

public class Crash {
      public static void main(String[] args) {
              Object[] o = null;

              while (true) {
                       o = new Object[] {o};
                            }
              }
}

This sample Program Crashes the JVM.

1. Start GDB
To Start Gdb execute,

The important gdb command include
(gdb) where ("shows a summary of the stack")
(gdb) thr ("switch among threads or show the current thread")
(gdb) info thr ("inquire about existing threads")
(gdb) thread apply 1 bt ("apply a command to a list of threads, specifically the backtrace to thread #1") or we can use ‘backtrace’
(gdb) quit

So lets start,

Dev: vx1379:djbs002-~ $ gdb --args java Crash

In the above command we started the gdb command passing args , the java command to start the javaCrash class. Even though we started gdb passing the ‘java Crash’ as an argument it wont start the java class until we execute the command ‘run’ in gdb.

Dev:vx1379:djbs002-~ $ gdb --args java Crash
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-45.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /software/java32/jdk1.6.0_16/bin/java...(no debugging symbols found)...done.
(gdb) run
Starting program: /software/java32/jdk1.6.0_16/bin/java Crash
[Thread debugging using libthread_db enabled]
Executing new program: /software/java32/jdk1.6.0_16/bin/java
[Thread debugging using libthread_db enabled]
[New Thread 0xf74a5b90 (LWP 8855)]
[New Thread 0xaff06b90 (LWP 8856)]
[New Thread 0xafe85b90 (LWP 8857)]
[New Thread 0xafc3bb90 (LWP 8858)]
[New Thread 0xafbbab90 (LWP 8859)]
[New Thread 0xafb69b90 (LWP 8860)]
[New Thread 0xaf918b90 (LWP 8863)]
[New Thread 0xaf8c7b90 (LWP 8864)]
[New Thread 0xaf846b90 (LWP 8865)]
[New Thread 0xaf7c5b90 (LWP 8866)]
[New Thread 0xaf774b90 (LWP 8867)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xafc3bb90 (LWP 8858)]
0xf79c6eb0 in objArrayKlass::oop_follow_contents(oopDesc*) () from /software/java32/jdk1.6.0_16/jre/lib/i386/server/libjvm.so

The Program Crashed with the Segmentation fault.

(gdb) thr
[Current thread is 5 (Thread 0xafc3bb90 (LWP 8858))]

(gdb) thread apply 1 bt
Thread 1 (Thread 0xf7fe36c0 (LWP 8852)):
#0  0xffffe402 in ?? ()
#1  0x00bd0b77 in pthread_join () from /lib/libpthread.so.0
#2  0x0804dd78 in ContinueInNewThread ()
#3  0x080497f6 in main ()

(gdb) info threads
  12 Thread 0xaf774b90 (LWP 8867)  0xffffe402 in ?? ()
  11 Thread 0xaf7c5b90 (LWP 8866)  0xffffe402 in ?? ()
  10 Thread 0xaf846b90 (LWP 8865)  0xffffe402 in ?? ()
  9 Thread 0xaf8c7b90 (LWP 8864)  0xffffe402 in ?? ()
  8 Thread 0xaf918b90 (LWP 8863)  0xffffe402 in ?? ()
  7 Thread 0xafb69b90 (LWP 8860)  0xffffe402 in ?? ()
  6 Thread 0xafbbab90 (LWP 8859)  0xffffe402 in ?? ()
* 5 Thread 0xafc3bb90 (LWP 8858)  0xf79c6eb0 in objArrayKlass::oop_follow_contents(oopDesc*) () from /software/java32/jdk1.6.0_16/jre/lib/i386/server/libjvm.so
  4 Thread 0xafe85b90 (LWP 8857)  0xffffe402 in ?? ()
  3 Thread 0xaff06b90 (LWP 8856)  0xffffe402 in ?? ()
  2 Thread 0xf74a5b90 (LWP 8855)  0xffffe402 in ?? ()
  1 Thread 0xf7fe36c0 (LWP 8852)  0xffffe402 in ?? ()

(gdb) thread 5
[Switching to thread 5 (Thread 0xafc3bb90 (LWP 8858))]#0  0xf79c6eb0 in objArrayKlass::oop_follow_contents(oopDesc*) ()
   from /software/java32/jdk1.6.0_16/jre/lib/i386/server/libjvm.so

(gdb) thr
[Current thread is 5 (Thread 0xafc3bb90 (LWP 8858))]

(gdb) thread apply 5 bt
Which generates the Thread Dump for the Thread 5
  
(gdb) info shared
From        To          Syms Read   Shared Object Library
0x00a417f0  0x00a5712f  Yes (*)     /lib/ld-linux.so.2
0x00bce210  0x00bd9bc4  Yes (*)     /lib/libpthread.so.0
0xf7fe5e50  0xf7feaf80  Yes (*)     /software/java32/jdk1.6.0_16/bin/../jre/lib/i386/jli/libjli.so
0x00cc7a70  0x00cc8aa4  Yes (*)     /lib/libdl.so.2
0x00a75ca0  0x00b74e30  Yes (*)     /lib/libc.so.6
0xf7541590  0xf7b15800  Yes (*)     /software/java32/jdk1.6.0_16/jre/lib/i386/server/libjvm.so
0x00cd6410  0x00cf15a4  Yes (*)     /lib/libm.so.6
0x00bc0880  0x00bc4c44  Yes (*)     /lib/librt.so.1
0xf7ff30e0  0xf7ff9e90  Yes (*)     /software/java32/jdk1.6.0_16/jre/lib/i386/libverify.so
0xf743a830  0xf7450100  Yes (*)     /software/java32/jdk1.6.0_16/jre/lib/i386/libjava.so
0xf740b140  0xf7418ca4  Yes (*)     /lib/libnsl.so.1
0xf742b260  0xf742edf0  Yes (*)     /software/java32/jdk1.6.0_16/jre/lib/i386/native_threads/libhpi.so
0xf73ee8e0  0xf73f5274  Yes (*)     /lib/libnss_files.so.2
0xf73ddc60  0xf73e8920  Yes (*)     /software/java32/jdk1.6.0_16/jre/lib/i386/libzip.so
(*): Shared library is missing debugging information.

Info Shared will provide you details about the shared library packages.

(gdb)  p (char***)&environ
$3 = (char ***) 0xbbaae4
(gdb) set print array
(gdb) p $3[0][0]@30

Which will display all the environment values passed to the command we are executing.

We can also attach the Gdb to a Process already running like

Dev:vx1379:djbs002-~ $ java Bottleneck &
[1] 13668
Dev:vx1379:djbs002-~ $ gdb --pid=13668
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-45.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Attaching to process 13668
Reading symbols from /software/java32/jdk1.6.0_16/bin/java...(no debugging symbols found)...done.
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 0xaf2fbb90 (LWP 13689)]
[New Thread 0xaf34cb90 (LWP 13688)]
[New Thread 0xaf39db90 (LWP 13687)]
[New Thread 0xaf3eeb90 (LWP 13686)]
[New Thread 0xaf43fb90 (LWP 13685)]
[New Thread 0xaf490b90 (LWP 13684)]
[New Thread 0xaf4e1b90 (LWP 13683)]
[New Thread 0xaf532b90 (LWP 13682)]
[New Thread 0xaf583b90 (LWP 13681)]
[New Thread 0xaf5d4b90 (LWP 13680)]
[New Thread 0xaf6b4b90 (LWP 13679)]
[New Thread 0xaf705b90 (LWP 13678)]
[New Thread 0xaf786b90 (LWP 13677)]
[New Thread 0xaf807b90 (LWP 13676)]
[New Thread 0xaf858b90 (LWP 13675)]
[New Thread 0xafaa9b90 (LWP 13674)]
[New Thread 0xafafab90 (LWP 13673)]
[New Thread 0xafb7bb90 (LWP 13672)]
[New Thread 0xafdc5b90 (LWP 13671)]
[New Thread 0xafe46b90 (LWP 13670)]
[New Thread 0xf73e3b90 (LWP 13669)]
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /software/java32/jdk1.6.0_16/bin/../jre/lib/i386/jli/libjli.so...(no debugging symbols found)...done.
Loaded symbols for /software/java32/jdk1.6.0_16/bin/../jre/lib/i386/jli/libjli.so
Reading symbols from /lib/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /software/java32/jdk1.6.0_16/jre/lib/i386/server/libjvm.so...(no debugging symbols found)...done.
Loaded symbols for /software/java32/jdk1.6.0_16/jre/lib/i386/server/libjvm.so
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /software/java32/jdk1.6.0_16/jre/lib/i386/libverify.so...(no debugging symbols found)...done.
Loaded symbols for /software/java32/jdk1.6.0_16/jre/lib/i386/libverify.so
Reading symbols from /software/java32/jdk1.6.0_16/jre/lib/i386/libjava.so...(no debugging symbols found)...done.
Loaded symbols for /software/java32/jdk1.6.0_16/jre/lib/i386/libjava.so
Reading symbols from /lib/libnsl.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libnsl.so.1
Reading symbols from /software/java32/jdk1.6.0_16/jre/lib/i386/native_threads/libhpi.so...(no debugging symbols found)...done.
Loaded symbols for /software/java32/jdk1.6.0_16/jre/lib/i386/native_threads/libhpi.so
Reading symbols from /lib/libnss_files.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/libnss_files.so.2
Reading symbols from /software/java32/jdk1.6.0_16/jre/lib/i386/libzip.so...(no debugging symbols found)...done.
Loaded symbols for /software/java32/jdk1.6.0_16/jre/lib/i386/libzip.so
0xffffe402 in __kernel_vsyscall ()
(gdb) where #Where the Program was
#0  0xffffe402 in __kernel_vsyscall ()
#1  0x00bd0b77 in pthread_join () from /lib/libpthread.so.0
#2  0x0804dd78 in ContinueInNewThread ()
#3  0x080497f6 in main ()
(gdb) stack #Where the Program was
Undefined command: "stack".  Try "help".
(gdb) info stack
#0  0xffffe402 in __kernel_vsyscall ()
#1  0x00bd0b77 in pthread_join () from /lib/libpthread.so.0
#2  0x0804dd78 in ContinueInNewThread ()
#3  0x080497f6 in main ()
(gdb) thr #Current Thread
[Current thread is 1 (Thread 0xf7f216c0 (LWP 13668))]
(gdb) backtrace #Thread Trace
#0  0xffffe402 in __kernel_vsyscall ()
#1  0x00bd0b77 in pthread_join () from /lib/libpthread.so.0
#2  0x0804dd78 in ContinueInNewThread ()
#3  0x080497f6 in main ()
(gdb) info threads #threads Information
  22 Thread 0xf73e3b90 (LWP 13669)  0xffffe402 in __kernel_vsyscall ()
  21 Thread 0xafe46b90 (LWP 13670)  0xffffe402 in __kernel_vsyscall ()
  20 Thread 0xafdc5b90 (LWP 13671)  0xffffe402 in __kernel_vsyscall ()
  19 Thread 0xafb7bb90 (LWP 13672)  0xffffe402 in __kernel_vsyscall ()
  18 Thread 0xafafab90 (LWP 13673)  0xffffe402 in __kernel_vsyscall ()
  17 Thread 0xafaa9b90 (LWP 13674)  0xffffe402 in __kernel_vsyscall ()
  16 Thread 0xaf858b90 (LWP 13675)  0xffffe402 in __kernel_vsyscall ()
  15 Thread 0xaf807b90 (LWP 13676)  0xffffe402 in __kernel_vsyscall ()
  14 Thread 0xaf786b90 (LWP 13677)  0xffffe402 in __kernel_vsyscall ()
  13 Thread 0xaf705b90 (LWP 13678)  0xffffe402 in __kernel_vsyscall ()
  12 Thread 0xaf6b4b90 (LWP 13679)  0xffffe402 in __kernel_vsyscall ()
  11 Thread 0xaf5d4b90 (LWP 13680)  0xffffe402 in __kernel_vsyscall ()
  10 Thread 0xaf583b90 (LWP 13681)  0xffffe402 in __kernel_vsyscall ()
  9 Thread 0xaf532b90 (LWP 13682)  0xffffe402 in __kernel_vsyscall ()
  8 Thread 0xaf4e1b90 (LWP 13683)  0xffffe402 in __kernel_vsyscall ()
  7 Thread 0xaf490b90 (LWP 13684)  0xffffe402 in __kernel_vsyscall ()
  6 Thread 0xaf43fb90 (LWP 13685)  0xffffe402 in __kernel_vsyscall ()
  5 Thread 0xaf3eeb90 (LWP 13686)  0xffffe402 in __kernel_vsyscall ()
  4 Thread 0xaf39db90 (LWP 13687)  0xffffe402 in __kernel_vsyscall ()
  3 Thread 0xaf34cb90 (LWP 13688)  0xffffe402 in __kernel_vsyscall ()
  2 Thread 0xaf2fbb90 (LWP 13689)  0xffffe402 in __kernel_vsyscall ()
* 1 Thread 0xf7f216c0 (LWP 13668)  0xffffe402 in __kernel_vsyscall ()
(gdb) x 0xf7f216c0 #Register Value
0xf7f216c0:     0xf7f216c0

We can also attach core files that are generated by a JVM crash to gdb using,
gdb --core=core.31333
  
Generate a Heap Dump from the Core File
Dev:vx1379:djbs002-~ $ echo $JAVA_HOME
/software/java32/jdk1.6.0_16

Dev:vx1379:djbs002-~ $ jmap -heap:format=b /software/java32/jdk1.6.0_16/bin/java core.31333
Attaching to core core.31333 from executable /software/java32/jdk1.6.0_16/bin/java, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 14.2-b01
Dumping heap to heap.bin...
Heap dump file created

The article presents you a brief introduction about the debugging tool ‘gdb’. I will be providing more information on the debugging tools.

Please feel free to send me the comments.
More Details to come, Happy Learning J