RFR (S) 8022335 - (round 2) Native stack walk on Windows x64
Volker Simonis
volker.simonis at gmail.com
Fri Aug 30 07:32:27 PDT 2013
On Fri, Aug 30, 2013 at 12:37 AM, Ioi Lam <ioi.lam at oracle.com> wrote:
> Please review this fix:
>
> http://cr.openjdk.java.net/~iklam/8022335/win64_stack_walk_002/
>
> Bug: Native stack walk while generating hs_err does not work on Windows
x64
>
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8022335
> https://bugs.openjdk.java.net/browse/JDK-8022335
>
> What's new:
>
> The code is much more simplified than my last version. All interesting
> code is in a single function -- os::platform_print_native_stack
> in os_windows_x86.cpp. The rest is just busy work.
>
> Summary of fix:
>
> Windows x64 binaries are built (unconditionally) with the equivalent
of
> -fomit-frame-pointer,
Why do you think so? If I'm looking at the build logs and
make/windows/makefiles/compile.make I see that we always compile with '/O2
/Oy-' which according to
http://msdn.microsoft.com/en-us/library/2kxx5t2c%28v=vs.100%29.aspx means
'disable frame-pointer omission'. So according to that documentation, we
should have frame pointers in all functions.
Actually '/Oy-' was introduced in order to get better native stack traces
with http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6655385
Doesn’t it help or are there any other additional problem?
Currently I get the following in the hs_err file on Windows for a Java
program which crashes in Unsafe:
# JRE version: OpenJDK Runtime Environment (8.0) (build
1.8.0-internal-fastdebug-_2013_08_29_21_12-b00)
# Java VM: OpenJDK 64-Bit Server VM (25.0-b45-fastdebug mixed mode
windows-amd64 compressed oops)
# Problematic frame:
# V [jvm.dll+0x28c7a7]
...
*Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native
code)
V [jvm.dll+0x28c7a7]
J Crash.crashIt(Lsun/misc/Unsafe;I)V @ 0x0000000008e9b19c
[0x0000000008e9b140+92]
v ~StubRoutines::call_stub
V [jvm.dll+0x2c961a]
*
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j sun.misc.Unsafe.putAddress(JJ)V+0
J Crash.crashIt(Lsun/misc/Unsafe;I)V @ 0x0000000008e9b19c
[0x0000000008e9b140+92]
j Crash.doIt()V+45
v ~StubRoutines::call_stub
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;+87
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 Crash.main([Ljava/lang/String;)V+32
v ~StubRoutines::call_stub
On Linux, the same crashing program produces the following output in the
hs_err file:
# JRE version: OpenJDK Runtime Environment (8.0) (build
1.8.0-internal-jvmtests_2013_08_29_20_14-b00)
# Java VM: OpenJDK 64-Bit Server VM (25.0-b45 mixed mode linux-amd64
compressed oops)
# Problematic frame:
# V [libjvm.so+0x9b4ba7] Unsafe_SetNativeAddress+0xa7
...
*Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native
code)
V [libjvm.so+0x9b4ba7] Unsafe_SetNativeAddress+0xa7
j sun.misc.Unsafe.putAddress(JJ)V+0
J Crash.crashIt(Lsun/misc/Unsafe;I)V @ 0x00007f0b4d0f2c9c
[0x00007f0b4d0f2b80+284]
v ~StubRoutines::call_stub
V [libjvm.so+0x6174ee] JavaCalls::call_helper(JavaValue*, methodHandle*,
JavaCallArguments*, Thread*)+0x104e
V [libjvm.so+0x8c2e12] Reflection::invoke(instanceKlassHandle,
methodHandle, Handle, bool, objArrayHandle, BasicType, objArrayHandle,
bool, Thread*)+0x5e2
V [libjvm.so+0x8c63e7] Reflection::invoke_method(oopDesc*, Handle,
objArrayHandle, Thread*)+0x147
V [libjvm.so+0x66dd8e] JVM_InvokeMethod+0x25e
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;+87
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 Crash.main([Ljava/lang/String;)V+32
v ~StubRoutines::call_stub
V [libjvm.so+0x6174ee] JavaCalls::call_helper(JavaValue*, methodHandle*,
JavaCallArguments*, Thread*)+0x104e
V [libjvm.so+0x631226] jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*,
JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)+0x346
V [libjvm.so+0x63b98a] jni_CallStaticVoidMethod+0x17a
C [libjli.so+0x75ed] JavaMain+0x83d*
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j sun.misc.Unsafe.putAddress(JJ)V+0
J Crash.crashIt(Lsun/misc/Unsafe;I)V @ 0x00007f0b4d0f2c9c
[0x00007f0b4d0f2b80+284]
j Crash.doIt()V+45
v ~StubRoutines::call_stub
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;+87
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 Crash.main([Ljava/lang/String;)V+32
v ~StubRoutines::call_stub
So while the native (i.e. "mixed") stack trace is still much more accurate
on Linux, it isn't just a single line as you wrote. Maybe we could work on
improving this situation on Windows without a separate Windows stack
tracing routine or are there any fundamental problems which prevent this?
> so HotSpot's build-in native stack walking code
> will fail to find the sender frame. As a result, hs_err on Windows/x64
> will always list a single frame.
>
> I have added the os::platform_print_native_stack() function for
> Windows/x64 only. It uses the StackWalk64 API to walk the stace.
>
> Because the Win/x64 frame layout is very different than what HotSpot
> expects,
> I decided to implement os::platform_print_native_stack() as a
completely
> stand-alone function, and do not interact with the existing "frame"
C++
> class.
> See comments in os_windows_x86.cpp for details.
>
> Deficiency of fix:
>
> StackWalk64 knows nothing about the Java frames. So hs_err will
display
> only
> the native frames, and stop as soon as the first Java frame is
reached.
> It will
> also NOT display any native frames below Java frames.
>
> Printing the Java frames *may* be possible. However, at this point, I
> want
> to keep the code simple and crash proof. I will file a different bug
for
> printing the Java frames.
>
> Bonus:
>
> As a side-fix, I refactored a bunch of duplicated code in decoder.cpp
> into
> the DecoderLocker class.
>
I would really appreciate if you could do this in a separate change. I
think it is commonly agreed upon that "small unrelated fixes" (like
comments, white-space changes or single line fixes) may go into another
change but these changes are in IMHO big enough to justify a different bug
ID and change set.
> Tests:
>
> JPRT
> UTE (vm.runtime.testlist, vm.quick.testlist,
> vm.parallel_class_loading.testlist)
>
> I also manually inserted some crashes into jvm.dll and verified that
the
> native stack trace is printed as expected on Win/x64.
>
Maybe you can use/extend the WhiteBox API to write some good tests?
>
> Thanks
> - Ioi
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/attachments/20130830/26fbf9b8/attachment-0001.html
More information about the hotspot-runtime-dev
mailing list