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