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

Volker Simonis volker.simonis at gmail.com
Fri Sep 12 19:15:10 UTC 2014


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.

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