inspecting hotspot code using gdb
Ben Cheng
bccheng at google.com
Thu Oct 18 23:10:04 PDT 2007
Thanks guys. I am seeing improvements, but gdb still doesn't accept my
breakpoint through typing "b 'ciEnv::register_method':
(gdb) b 'ciEnv::register_method'
Can't find member of namespace, class, struct, or union named
"ciEnv::register_method"
Hint: try 'ciEnv::register_method'<TAB> or 'ciEnv::register_method'<ESC-?>
(Note leading single quote.)
I am using gdb6.6, and locally compiled libjvm.so with the -ggdb3 flag added
on linux.
After adding the various handle instructions in gdb I was able to run my
java code all the way to the end, which is a major progress! I then hacked
ciEnv::register_method() to have the following line added:
printf("ciEnv::register_method: %p\n", &ciEnv::register_method);
and in my gdb session I see a lot of invocations of it:
ciEnv::register_method: 0x2aaaaaf5326e
ciEnv::register_method: 0x2aaaaaf5326e
:
:
However, the only way to break there is using the hex address directly. The
symbolic name is still not recognized by gdb. It will be pretty dumb if I
used the wrong gdb command to set breakpoints. Just to rule out the case
could you share with me the exact command you used in gdb to set up such a
breakpoint?
Thanks,
-Ben
On 10/18/07, Neo Jia <neojia at gmail.com> wrote:
>
> Ben,
>
> I have used gdb a lot on Linux platform to debug VM, which works great
> (X86-64 and 32bit).
>
> I would suggest you to add the following to file
> hotspot/build/linux/makefiles/gcc.make
>
> DEBUG_CFLAGS += -ggdb3, which will make gdb much happier for C++ code.
>
> For the LD path problem, I think that is just a workaround for the old
> gdb version since the jvm will execve another process if it cannot
> find something expected from the LD path. But that bug is already
> fixed in gdb 6.5.
>
> Once, you build your VM first time. You may then do an incremental
> build from hotspot/build/linux, which will only create the .so you
> need.
>
> BTW, if you use ccache, it will speed up your work greatly.
>
> Thanks,
> Neo
>
>
> On 10/18/07, Tom Rodriguez <Thomas.Rodriguez at sun.com> wrote:
> > Using a debugger with the java launcher can be a little tricky since it
> normally
> > sets up the LD_LIBRARY_PATH and relaunches the VM to select the right
> libjvm.so
> > which makes debuggers unhappy. libjvm.so is also dynamically loaded so
> they
> > symbols won't be available until you've at least run it once. Your
> > LD_LIBRARY_PATH should be set to the value of the java.library.pathproperty
> > from the VM you want to run. gdb will get into various bad states if
> you don't
> > do this part. Also by default you also want to suppress a lot of
> signals that
> > the JVM uses.
> >
> > I attached the script I use for launching the VM under a debugger. It
> works for
> > dbx and gdb and has a little Java class for getting the
> java.library.path
> > property from a VM. You just prefix dbxr onto the full command line you
> want to
> > debug and it sets everything up for you. The script is a little ugly
> and has
> > some special bits to deal with getting properties from a JVM which might
> be at
> > least a little broken. Obviously if you are trying to debug a JVM which
> won't
> > even boot then it will be hard to get properties from it. It's possible
> to
> > derive the proper LD_LIBRARY_PATH setting from the location of the JDK
> but that
> > was error prone enough that I switched to using a class to read it
> out. Anyway,
> > hopefully it will be useful.
> >
> > tom
> >
> > Ben Cheng wrote:
> > > Hello,
> > >
> > > I tried to set a breakpoint in a Hotspot function, say
> > > "ciEnv::register_method", under gdb, but gdb couldn't seem to find the
> > > symbols. I am using my locally built libjvm.so so symbols should be
> > > there, so I am thinking that feeding the java launcher to gdb is the
> > > wrong thing to do here.
> > >
> > > Can someone explain the procedures to debug hotspot under gdb?
> > >
> > > Thanks,
> > > -Ben
> >
> > #!/bin/sh
> > tmpdir=/tmp/dbxr.$$
> > tmpcmd=$tmpdir/cmd
> >
> > rm -fr $tmpdir
> > mkdir -p $tmpdir
> > clean_tmp_files() {
> > rm -fr $tmpdir
> > }
> >
> > arch=
> > if [ -f /proc/cpuinfo ] ; then
> > arch=`uname -m`
> > if [ "$arch" = i686 ]; then
> > arch=i386
> > fi
> > else
> > arch=`uname -p`
> > fi
> > if [ -z "$arch" ]; then
> > echo "Unknown architecture. Exiting..."
> > exit 1
> > fi
> >
> > exe=$1
> > if [ ! -x "$1" ]; then
> > exe=`which $1`
> > fi
> > shift
> >
> > trap clean_tmp_files 2
> >
> > usage() {
> > echo "Usage: dbxr [ -dbx | -gdb ] [ -window ] [ -core ] [ -corefile
> <file> ] command ..."
> > exit
> > }
> >
> > if [ `uname` = "SunOS" ]; then
> > debugger=dbx
> > else
> > which dbx 2>&1 > /dev/null
> > if [ $? -eq 0 ]; then
> > debugger=dbx
> > else
> > debugger=gdb
> > fi
> > fi
> >
> > debugargs=
> > debugprecmd=
> > fastdebug=
> > while [ $# -gt 0 ]; do
> > if [ $1 = -core ] ; then
> > debugargs=core
> > shift
> > elif [ $1 = -corefile ] ; then
> > debugargs="$2"
> > shift 2
> > elif [ $1 = -help ] ; then
> > usage
> > elif [ $1 = -dbx ] ; then
> > debugger=dbx
> > shift
> > elif [ $1 = -gdb ] ; then
> > debugger=gdb
> > shift
> > elif [ $1 = -window ] ; then
> > if [ -x /usr/dt/bin/dtterm ]; then
> > debugprecmd="/usr/dt/bin/dtterm -e"
> > else
> > debugprecmd="xterm -e"
> > fi
> > shift
> > elif [ $1 = -echo ] ; then
> > debugprecmd="echo"
> > shift
> > else
> > break;
> > fi
> > done
> >
> > cat - > $tmpdir/props.class.uu <<'EOF'
> > begin 644 props.class
> > MROZZO@ "X )0H !P 0"0 1 !(* !$ $PH % 5"@ 6 !<' !@' !D! 8\
> > M:6YI=#X! ,H*58! 1#;V1E 0 /3&EN94YU;6)E<E1A8FQE 0 $;6%I;@$
> > M%BA;3&IA=F$O;&%N9R]3=')I;F<[*58! I3;W5R8V5&:6QE 0 *<')O<',N
> > M:F%V80P " )!P :# ; !P, !T '@< 'PP ( A!P B# C "0! 5P<F]P
> > M<P$ $&IA=F$O;&%N9R]/8FIE8W0! !!J879A+VQA;F<O4WES=&5M 0 #;W5T
> > M 0 53&IA=F$O:6\O4')I;G13=')E86T[ 0 -9V5T4')O<&5R=&EE<P$ &"@I
> > M3&IA=F$O=71I;"]0<F]P97)T:65S.P$ %&IA=F$O=71I;"]0<F]P97)T:65S
> > M 0 #9V5T 0 F*$QJ879A+VQA;F<O3V)J96-T.RE,:F%V82]L86YG+T]B:F5C
> > M=#L! !-J879A+VEO+U!R:6YT4W1R96%M 0 '<')I;G1L;@$ %2A,:F%V82]L
> > M86YG+T]B:F5C=#LI5@ A 8 !P @ ! @ "0 ! H = $ 0
> > M 4JMP !L0 $ "P 8 0 $ "0 , T 0 * 0@ $ ( >
> > M SP;*KZB !BR *X ,J&S*V 2V 6$ 0&G_^BQ 0 + $@ $
> > 7 P ( 0 %P # !T !@ ! X " ^$
> >
> > end
> > EOF
> >
> > (cd $tmpdir; uudecode props.class.uu)
> >
> > jvmver() {
> > jvmargs=
> > while [ "$#" -gt 0 ]; do
> > case "$1" in
> > "-client") jvmargs="$jvmargs $1"; shift;;
> > "-server") jvmargs="$jvmargs $1"; shift;;
> > "-d64") jvmargs="$jvmargs $1";
> > j=`basename $exe`
> > nog=`basename $exe _g`
> > d=`dirname $exe`
> > if [ -f $d/sparcv9/$j ]; then
> > exe=$d/sparcv9/$j
> > elif [ -f $d/../fastdebug/bin/sparcv9/$nog ]; then
> > exe=$d/../fastdebug/bin/sparcv9/$nog
> > fi
> > if [ -f $d/amd64/$j ]; then
> > exe=$d/amd64/$j
> > elif [ -f $d/../fastdebug/bin/amd64/$nog ]; then
> > exe=$d/../fastdebug/bin/amd64/$nog
> > fi
> > shift;;
> > -*) shift;;
> > *) break;;
> > esac
> > done
> > }
> >
> > jvmver $*
> >
> > # use -Xint in case the VM won't boot with the compiler
> > LD_LIBRARY_PATH=`$exe $jvmargs -Xint -cp $tmpdir -XX:-PrintVMOptions
> -XX:-DisplayVMOutput props java.library.path 2>/dev/null | grep -v "VM
> option"`
> > if [ $? -ne 0 ]; then
> > LD_LIBRARY_PATH=`$exe $jvmargs -Xint -cp $tmpdir -XX:-PrintVMOptions
> -XX:-DisplayVMOutput -XX:+Debugging props java.library.path 2>/dev/null |
> grep -v "VM option"`
> > fi
> > if [ $? -ne 0 ]; then
> > LD_LIBRARY_PATH=`$exe $jvmargs -Xint -cp
> $tmpdir -XX:+UnlockDiagnosticVMOptions -XX:-LogVMOutput
> -XX:-DisplayVMOutput -XX:-PrintVMOptions -XX:-DisplayVMOutput props
> java.library.path 2>/dev/null | grep -v "VM option"`
> > fi
> > if [ $? -ne 0 ]; then
> > echo "Error getting LD_LIBRARY_PATH"
> > $exe $jvmargs -Xint -cp $tmpdir -XX:+UnlockDiagnosticVMOptions
> -XX:-LogVMOutput -XX:-DisplayVMOutput props java.library.path
> > exit 1
> > fi
> > export LD_LIBRARY_PATH
> >
> > if [ $debugger = "gdb" ] ; then
> > echo "handle SIGSEGV noprint nostop pass" >> $tmpcmd
> > echo "handle SIGUSR2 noprint nostop pass" >> $tmpcmd
> > echo "handle SIGILL noprint nostop pass" >> $tmpcmd
> > echo "handle SIGFPE noprint nostop pass" >> $tmpcmd
> > echo "handle SIG32 noprint nostop pass" >> $tmpcmd
> > echo "handle SIGABRT print stop nopass" >> $tmpcmd
> > echo "shell rm -fr $tmpdir" >> $tmpcmd
> > echo "set args $*" >> $tmpcmd
> > exec $debugprecmd $debugger --command=$tmpcmd $exe
> > else
> > rm -f $tmpcmd
> > if [ "$debugargs" != "" ]; then
> > echo "debug $exe $debugargs" > $tmpcmd
> > else
> > echo "debug $exe" >> $tmpcmd
> > echo "runargs $*" >> $tmpcmd
> > fi
> > echo "if [ -f ~/.dbxr.rc ]; then source ~/.dbxr.rc; fi" >> $tmpcmd
> > echo "sh rm -fr $tmpdir" >> $tmpcmd
> > exec $debugprecmd $debugger -c "source $tmpcmd"
> > fi
> >
> >
>
>
> --
> I would remember that if researchers were not ambitious
> probably today we haven't the technology we are using!
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-dev/attachments/20071018/3ae7a507/attachment.html
More information about the hotspot-dev
mailing list