RFR(S): 8058345: Refactor native stack printing from vmError.cpp to debug.cpp to make it available in gdb as well

David Holmes david.holmes at oracle.com
Tue Sep 16 06:51:47 UTC 2014


Hi Volker,

On 13/09/2014 5:15 AM, Volker Simonis wrote:
> Hi,
>
> could you please review and sponsor the following small change which
> should make debugging a little more comfortabel (at least on Linux for
> now):
>
> http://cr.openjdk.java.net/~simonis/webrevs/8058345/
> https://bugs.openjdk.java.net/browse/JDK-8058345
>
> In the hs_err files we have a nice mixed stack trace which contains
> both, Java and native frames.
> It would be nice if we could make this functionality available from
> within gdb during debugging sessions (until now we can only print the
> pure Java stack with the "ps()" helper function from debug.cpp).
>
> This new feature can be easily achieved by refactoring the
> corresponding stack printing code from VMError::report() in
> vmError.cpp into its own method in debug.cpp. This change extracts
> that code into the new function 'print_native_stack()' in debug.cpp
> without changing anything of the functionality.

Why does it need to move to debug.cpp to allow this ?

David
-----

> It also adds some helper functions which make it easy to call the new
> 'print_native_stack()' method from within gdb. There's the new helper
> function 'pns(frame f)'  which takes a frame argument and calls
> 'print_native_stack()'. We need the frame argument because gdb inserts
> a dummy frame for every call and we can't easily walk over this dummy
> frame from our stack printing routine.
>
> To simplify the creation of the frame object, I've added the helper functions:
>
> extern "C" frame make_frame(intptr_t* sp, intptr_t* fp, address pc) {
>    return frame(sp, fp, pc);
> }
>
> for x86 (in frame_x86.cpp) and
>
> extern "C" frame make_frame(intptr_t* sp, address pc) {
>    return frame(sp, pc);
> }
>
> for ppc64 in frame_ppc.cpp. With these helper functions we can now
> easily get a mixed stack trace of a Java thread in gdb (see below).
>
> All the helper functions are protected by '#ifndef PRODUCT'
>
> Thank you and best regards,
> Volker
>
>
> (gdb) call pns(make_frame($sp, $rbp, $pc))
>
> "Executing pns"
> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
> C  [libpthread.so.0+0xc0fe]  pthread_cond_timedwait+0x13e
> V  [libjvm.so+0x96c4c1]  os::sleep(Thread*, long, bool)+0x1a1
> V  [libjvm.so+0x75f442]  JVM_Sleep+0x312
> j  java.lang.Thread.sleep(J)V+0
> j  CrashNative.crashIt(Lsun/misc/Unsafe;I)V+10
> j  CrashNative.doIt()V+45
> v  ~StubRoutines::call_stub
> V  [libjvm.so+0x71599f]  JavaCalls::call_helper(JavaValue*,
> methodHandle*, JavaCallArguments*, Thread*)+0xf8f
> V  [libjvm.so+0x9eab75]  Reflection::invoke(instanceKlassHandle,
> methodHandle, Handle, bool, objArrayHandle, BasicType, objArrayHandle,
> bool, Thread*) [clone .constprop.218]+0xa25
> V  [libjvm.so+0x9eb838]  Reflection::invoke_method(oopDesc*, Handle,
> objArrayHandle, Thread*)+0x1c8
> V  [libjvm.so+0x7637ae]  JVM_InvokeMethod+0xfe
> j  sun.reflect.NativeMethodAccessorImpl.invoke0(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+0
> j  sun.reflect.NativeMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+100
> j  sun.reflect.DelegatingMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+6
> j  java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+56
> j  CrashNative.mainJava()V+32
> v  ~StubRoutines::call_stub
> V  [libjvm.so+0x71599f]  JavaCalls::call_helper(JavaValue*,
> methodHandle*, JavaCallArguments*, Thread*)+0xf8f
> V  [libjvm.so+0x7384f5]  jni_invoke_static(JNIEnv_*, JavaValue*,
> _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)
> [clone .isra.238] [clone .constprop.250]+0x385
> V  [libjvm.so+0x73b3d7]  jni_CallStaticVoidMethodV+0xe7
> C  [libCrashNative.so+0x9a9]  JNIEnv_::CallStaticVoidMethod(_jclass*,
> _jmethodID*, ...)+0xb9
> C  [libCrashNative.so+0xa10]  step3(JNIEnv_*, _jobject*)+0x65
> C  [libCrashNative.so+0xa69]  step2(JNIEnv_*, _jobject*)+0x57
> C  [libCrashNative.so+0xa37]  step2(JNIEnv_*, _jobject*)+0x25
> C  [libCrashNative.so+0xa37]  step2(JNIEnv_*, _jobject*)+0x25
> C  [libCrashNative.so+0xa37]  step2(JNIEnv_*, _jobject*)+0x25
> C  [libCrashNative.so+0xa37]  step2(JNIEnv_*, _jobject*)+0x25
> C  [libCrashNative.so+0xa37]  step2(JNIEnv_*, _jobject*)+0x25
> C  [libCrashNative.so+0xa8e]  step1(JNIEnv_*, _jobject*)+0x23
> C  [libCrashNative.so+0x87f]  Java_CrashNative_nativeMethod+0x23
> j  CrashNative.nativeMethod()V+0
> j  CrashNative.main([Ljava/lang/String;)V+9
> v  ~StubRoutines::call_stub
> V  [libjvm.so+0x71599f]  JavaCalls::call_helper(JavaValue*,
> methodHandle*, JavaCallArguments*, Thread*)+0xf8f
> V  [libjvm.so+0x7384f5]  jni_invoke_static(JNIEnv_*, JavaValue*,
> _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)
> [clone .isra.238] [clone .constprop.250]+0x385
> V  [libjvm.so+0x73b2b0]  jni_CallStaticVoidMethod+0x170
> C  [libjli.so+0x742a]  JavaMain+0x65a
> C  [libpthread.so.0+0x7e9a]  start_thread+0xda
>


More information about the hotspot-dev mailing list