inspecting hotspot code using gdb
Neo Jia
neojia at gmail.com
Thu Oct 18 22:21:23 PDT 2007
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.path property
> 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!
More information about the hotspot-dev
mailing list