Integrated: 8277948: AArch64: Print the correct native stack if -XX:+PreserveFramePointer when crash
Denghui Dong
ddong at openjdk.java.net
Fri Jan 28 00:52:14 UTC 2022
On Mon, 29 Nov 2021 17:40:43 GMT, Denghui Dong <ddong at openjdk.org> wrote:
> Hi,
>
> I found that the native stack frames in the hs log are not accurate sometimes on AArch64, not sure if this is a known issue or an issue worth fixing.
>
> The following steps can quick reproduce the problem:
>
> 1. apply the diff(comment the dtrace_object_alloc call in interpreter and make a crash on SharedRuntime::dtrace_object_alloc)
>
> index 39e99bdd5ed..4fc768e94aa 100644
> --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
> +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
> @@ -3558,6 +3558,7 @@ void TemplateTable::_new() {
> __ store_klass_gap(r0, zr); // zero klass gap for compressed oops
> __ store_klass(r0, r4); // store klass last
>
> +/**
> {
> SkipIfEqual skip(_masm, &DTraceAllocProbes, false);
> // Trigger dtrace event for fastpath
> @@ -3567,6 +3568,7 @@ void TemplateTable::_new() {
> __ pop(atos); // restore the return value
>
> }
> +*/
> __ b(done);
> }
>
> diff --git a/src/hotspot/cpu/x86/templateTable_x86.cpp b/src/hotspot/cpu/x86/templateTable_x86.cpp
> index 19530b7c57c..15b0509da4c 100644
> --- a/src/hotspot/cpu/x86/templateTable_x86.cpp
> +++ b/src/hotspot/cpu/x86/templateTable_x86.cpp
> @@ -4033,6 +4033,7 @@ void TemplateTable::_new() {
> Register tmp_store_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
> __ store_klass(rax, rcx, tmp_store_klass); // klass
>
> +/**
> {
> SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0);
> // Trigger dtrace event for fastpath
> @@ -4041,6 +4042,7 @@ void TemplateTable::_new() {
> CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), rax);
> __ pop(atos);
> }
> +*/
>
> __ jmp(done);
> }
> diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp
> index a5de65ea5ab..60b4bd3bcc8 100644
> --- a/src/hotspot/share/runtime/sharedRuntime.cpp
> +++ b/src/hotspot/share/runtime/sharedRuntime.cpp
> @@ -1002,6 +1002,7 @@ jlong SharedRuntime::get_java_tid(Thread* thread) {
> * 6254741. Once that is fixed we can remove the dummy return value.
> */
> int SharedRuntime::dtrace_object_alloc(oopDesc* o) {
> + *(int*)0 = 1;
> return dtrace_object_alloc(Thread::current(), o, o->size());
> }
>
>
> 2. `java -XX:+DTraceAllocProbes -Xcomp -XX:-PreserveFramePointer -version`
>
> On x86_64, the native stack in hs log is complete, but on AArch64, the native stack is incorrect.
>
> In the beginning, I thought it might be the influence of PreserveFramePointer. Later, I found that no matter whether PreserveFramePointer is enabled or not, in the hs log of x86_64, the native stack is always correct, and aarch64 is wrong.
>
> After some investigation, I found that this problem is related to the layout of the stack.
>
> On x86_64, whether it is C/C++, interpreter, or JIT, `callee` will always put the `return address` and `fp` of the `caller` at the bottom of the stack.
> Hence, `callee` can always get the `caller sp`(aka `sender sp`) by `fp + 2`, and if `caller` is a compiled method, `caller sp` is the key to getting the `caller`'s `caller` since `caller fp` may be invalid.(see frame::sender_for_compiled_frame).
>
>
> push %rbp
> mov %rsp,%rbp
>
> _ _ _ _ _ _
> | |
> | | |
> |_ _ _ _ _ _| |
> | | |
> caller | | <- caller sp |
> _ _ _ |_ _ _ _ _ _| | expand
> | | |
> | ret addr | | direction
> callee |_ _ _ _ _ _| |
> | | V
> | caller fp | <- fp
> |_ _ _ _ _ _|
>
>
>
> But for AArch64, the C/C++ code doesn't put the `return address` and `fp` of the `caller` at the bottom of the stack.
> Hence, we cannot use `fp + 2` to calculate the proper `caller sp`(although it is still implemented this way).
>
> When `caller` is a C1/C2 method A, and `callee` is a C/C++ method B, we cannot get the `caller` of A since we cannot get the proper sp value of it.
>
>
> stp x29, x30, [sp, #-N]!
> mov x29, sp
>
> _ _ _ _ _ _
> | |
> | | |
> |_ _ _ _ _ _| |
> | | |
> caller | | <- caller sp |
> _ _ _ |_ _ _ _ _ _| - | expand
> | |
> . . . . . | | direction
> _ _ _ _ _ _ | |
> | | | N |
> | ret addr | | |
> callee |_ _ _ _ _ _| | |
> | | - V
> | caller fp | <- fp
> |_ _ _ _ _ _|
>
>
>
> I am not very familiar with AArch64 and have no idea how to fix this issue perfectly at current.
>
> Based on my understanding of the implementation, we can get the correct stack trace when PreserveFramePointer is enabled.
>
> Although PreserveFramePointer is disabled by default, I found that some real applications will enable it in the production environment.
> Therefore, in my opinion, this fix can help troubleshoot crash issues in applications that enable PreserveFramePointer on AArch64 platform.
>
> This patch changes the logic of l_sender_sp calculation, uses sender_sp() as the value of l_sender_sp when PreserveFramePointer is enabled.
>
> Any input is appreciated.
>
> Thanks,
> Denghui
This pull request has now been integrated.
Changeset: 094db1a3
Author: Denghui Dong <ddong at openjdk.org>
URL: https://git.openjdk.java.net/jdk/commit/094db1a3eeb3709c8218d8d26f13699024ec2943
Stats: 32 lines in 4 files changed: 23 ins; 0 del; 9 mod
8277948: AArch64: Print the correct native stack if -XX:+PreserveFramePointer when crash
Reviewed-by: aph, adinn
-------------
PR: https://git.openjdk.java.net/jdk/pull/6597
More information about the hotspot-dev
mailing list