-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Establish stack frame inside CallEHFunclet #4581
Conversation
This commit revises the implementation of CallEHFunclet to establish stack frame appropriately. This commit allows libunwind to work correctly for the frame created by CallEHFunclet.
This commit tries to fix #4579 |
@@ -99,6 +99,7 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie) | |||
NESTED_ENTRY CallEHFunclet, _TEXT, NoHandler | |||
|
|||
PROLOG_PUSH "{r4-r11, lr}" | |||
PROLOG_STACK_SAVE r7 | |||
alloc_stack 4 | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the issue because alloc_stack is missing unwind codes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unw_step
(which is used inside PAL_VirtualUnwind
) failed to recognize the stack allocation, and thus all the registers are spoiled during stack unwind (e.g LR
is updated with the value of R11
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of this fix. I would experiment with the unwind annotations for alloc_stack & free_stack https://github.com/dotnet/coreclr/blob/master/src/pal/inc/unixasmmacrosarm.inc#L60 . Maybe free_stack does not need .pad annotation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is strange that the .pad
in the alloc_stack doesn't work. I wonder - should the .pad actually precede the sub sp, sp, \Size in the macro? Could you please try if that change alone fixes the problem? Looking at https://sourceware.org/binutils/docs/as/ARM-Unwinding-Tutorial.html, that tutorial uses first the .pad
and then the sub sp, sp, #nn
while our macro does the opposite.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@janvorli I reverted this change and changed code as you mentioned, but it looks like that unwind still fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.pad should have pointed r7 saved in the stack (need to add 12) or .setfp along with setting r7, pointing at r7 saved in stack is required.
You may need to manually formulate r7 and .setfp as I did in https://github.com/dotnet/coreclr/blob/master/src/pal/inc/unixasmmacrosarm.inc because r7 is not at the top of the stack. Please test gdb stack tracing at a callee of the corresponding asm function if it traces the caller of the function. Note that in the case of ThePreStub along with Roslyn issue, it seems that you need to configure .save .pad .setfp and fp register (r7) all together consistnetly. Unlike the common FP usage, R7 is supposed to point at the saved (caller's value) r7 in the stack. I will need to confirm this by looking at gnueabi doc or libunwind-arm code; however this is sort of empirical result with libunwind-arm and gdb. @parjong I am returning the day after tomorrow. I will be able to look at this issue then. |
This commit revises CallEHFilterFunclet as CallEHFunclet as both functions have the same issue. Currently, CoreCLR (on ARM32/Linux) traps into infinite loop if an exception is thrown inside any filter funclet.
@@ -124,7 +127,8 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie) | |||
// frame pointer for accessing the locals in the parent method. | |||
NESTED_ENTRY CallEHFilterFunclet, _TEXT, NoHandler | |||
|
|||
PROLOG_PUSH "{lr}" | |||
PROLOG_PUSH "{r4-r11, lr}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we simply push r7, lr instead of r4-r11, lr here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried that first, but I encountered the following assertion failure:
Assert failure(PID 4686 [0x0000124e], Thread: 4686 [0x124e]): dac_cast<DWORD>(address) & THUMB_CODE
File: /home/parjong/projects/toolchains/coreclr/src/debug/ee/controller.h Line: 727
Image: /mnt/dotnet-latest/Linux.arm.Debug/corerun
**** MessageBox invoked, title 'corerun - Assert Failure (PID 4686, Thread 4686/0x124e)' ****
dac_cast<DWORD>(address) & THUMB_CODE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll check whether it is possible only with {r4, r7, lr}.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be caused by bugs from other assembly files.
I've found FP handling issues in many places and will send patches soon there.
With such functions corrected along with the alternative patch on this file:
diff --git a/src/vm/arm/ehhelpers.S b/src/vm/arm/ehhelpers.S
index dfe1b11..c32a06b 100644
--- a/src/vm/arm/ehhelpers.S
+++ b/src/vm/arm/ehhelpers.S
@@ -47,6 +47,8 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
//
// Runtime check for 8-byte alignment.
PROLOG_STACK_SAVE r7
+ // We lose stack unwindability here by configuring fp(r7) incorrectely
+ // here.
and r0, r7, #4
sub sp, sp, r0
@@ -99,6 +101,7 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
NESTED_ENTRY CallEHFunclet, _TEXT, NoHandler
PROLOG_PUSH "{r4-r11, lr}"
+ PROLOG_STACK_SAVE_OFFSET r7, #12
alloc_stack 4
// On entry:
@@ -124,7 +127,8 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
// frame pointer for accessing the locals in the parent method.
NESTED_ENTRY CallEHFilterFunclet, _TEXT, NoHandler
- PROLOG_PUSH "{lr}"
+ PROLOG_PUSH "{r7, lr}"
+ PROLOG_STACK_SAVE r7
alloc_stack 4
// On entry:
@@ -140,6 +144,6 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
blx r2
free_stack 4
- EPILOG_POP "{pc}"
+ EPILOG_POP "{r7, pc}"
NESTED_END CallEHFilterFunclet, _TEXT
It works. For example:
bash-3.2# ./corerun seh_tests.exe
Testcase successful
bash-3.2# ./corerun csc.exe /lib:. /r:mscorlib.dll hello.cs
Microsoft (R) Visual C# Compiler version 42.42.42.42
Copyright (C) Microsoft Corporation. All rights reserved.
bash-3.2# ./corerun hello.exe
Hello World
bash-3.2#
p.s. PROLOG_STACK_SAVE_OFFSET
requires updates from #4641 .
@dotnet-bot test Linux ARM emulator |
@parjong It looks like that our codes are inter-dependent to each other. Let's refactor our codes tomorrow. |
This commit revises the stack frame layout in CallEHFunclet and CallEHFilterFunclet. The prolog of both functions makes the following layout: SP -> +-------------+ | Previous R4 | +-------------+ | Previous R5 | +-------------+ | Previous R6 | R7 -> +-------------+ | Previous R7 | +-------------+ | Previous LR | +-------------+
@parjong, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR. |
@dotnet-bot test Ubuntu x64 Checked Build and Test please |
@dotnet-bot test OSX x64 Checked Build and Test please |
@@ -124,7 +128,9 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie) | |||
// frame pointer for accessing the locals in the parent method. | |||
NESTED_ENTRY CallEHFilterFunclet, _TEXT, NoHandler | |||
|
|||
PROLOG_PUSH "{lr}" | |||
PROLOG_PUSH "{r4-r11, lr}" | |||
.setfp r7, sp, #12 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commit revises the implementation of CallEHFunclet to establish stack frame appropriately. This commit allows libunwind to work correctly for the frame created by CallEHFunclet. This revises the PR suggested by dotnet#4581, which fixes #4579 Edited-by: MyungJoo Ham <[email protected]>
Please note that #4641 has your commit included and revised. |
This commit revises the implementation of CallEHFunclet to establish stack frame appropriately. This commit allows libunwind to work correctly for the frame created by CallEHFunclet. This revises the PR suggested by dotnet#4581, which fixes #4579 Edited-by: MyungJoo Ham <[email protected]>
This commit revises the implementation of CallEHFunclet to establish stack frame appropriately. This commit allows libunwind to work correctly for the frame created by CallEHFunclet. This revises the PR suggested by dotnet#4581, which fixes #4579 Edited-by: MyungJoo Ham <[email protected]>
I'll close this PR since PR #4641 that includes all the necessary patches is merged. |
This commit revises the implementation of CallEHFunclet to establish
stack frame appropriately.
This commit allows libunwind to work correctly for the frame created by
CallEHFunclet.