inspecting hotspot code using gdb

Neo Jia neojia at gmail.com
Fri Oct 19 01:23:35 PDT 2007


Ben,

gdb cannot break on your code because you do not provide function
signature information for it. The simplest way is to use the filename
and line number.

This is what I got from a old jdk7 build code:

722 // ------------------------------------------------------------------
723 // ciEnv::register_method
724 void ciEnv::register_method(ciMethod* target,
725                 int entry_bci,
726                             CodeOffsets* offsets,
727                 int orig_pc_offset,
728                 CodeBuffer* code_buffer,
729                 int frame_words,
730                 OopMapSet* oop_map_set,
731                 ExceptionHandlerTable* handler_table,
732                 ImplicitExceptionTable* inc_table,
733                             AbstractCompiler* compiler,
734                             bool has_debug_info,
735                             bool has_unsafe_access) {

Obviously, gdb cannot locate the symbols only by giving ciEnv::register_method.

Thanks,
Neo

On 10/18/07, Ben Cheng <bccheng at google.com> wrote:
> 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.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!
> >
>
>


-- 
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