inspecting hotspot code using gdb

Ben Cheng bccheng at google.com
Fri Oct 19 11:53:54 PDT 2007


Actually the signature information is in the .so file, as I was able to set
such breakpoints in other programs. A colleague showed me the command
"sharedlibrary libjvm" to force gdb to reload the symbol table, and gdb
happily acknowledges with the following message:

(gdb) sharedlibrary libjvm
Reading symbols from
/usr/local/google/home/bccheng/java-6-sun_64/jre/lib/amd64/server/libjvm.so...done.

We think the automatic symbol loading is disabled after a certain size
threshold is hit.

However, yet a new failure pops up as gdb crashes with a segmentation fault
once the break point is hit. So more digging is required.

-Ben

On 10/19/07, Neo Jia <neojia at gmail.com> wrote:
>
> 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!
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-dev/attachments/20071019/29bc7281/attachment.html 


More information about the hotspot-dev mailing list