[unwinder] Update tests that starting unwinding from JSEntry frame

As a drive-by, enable tests that are safe for Arm32/64 to run.

Bug: v8:10833
Change-Id: I8fed5651399852f9ce8ba7d5acdb7ed27ca28e89
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2467841
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70491}
This commit is contained in:
Santiago Aboy Solanes 2020-10-13 15:09:49 +01:00 committed by Commit Bot
parent 4d4f716b9c
commit 6094c2e421
2 changed files with 16 additions and 56 deletions

View File

@ -483,11 +483,7 @@
# Arm. They are disabled because the stack is not being set up the way it does
# in the wild.
['arch == arm64 or arch == arm', {
'test-unwinder-code-pages/Unwind_CodeObjectPCInMiddle_Success_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_JSEntryBeforeFrame_Fail_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_OneJSFrame_Success_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_TwoJSFrames_Success_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_StackBounds_Basic_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_StackBounds_WithUnwinding_CodePagesAPI': [SKIP],
}],

View File

@ -282,54 +282,6 @@ TEST(Unwind_JSEntryBeforeFrame_Fail_CodePagesAPI) {
CHECK_EQ(jsentry_pc_value, register_state.pc);
}
TEST(Unwind_OneJSFrame_Success_CodePagesAPI) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
JSEntryStubs entry_stubs = isolate->GetJSEntryStubs();
MemoryRange code_pages[1];
size_t pages_length = 1;
RegisterState register_state;
// Use a fake code range so that we can initialize it to 0s.
const size_t code_length = 40;
uintptr_t code[code_length] = {0};
code_pages[0].start = code;
code_pages[0].length_in_bytes = code_length * sizeof(uintptr_t);
// Our fake stack has two frames - one C++ frame and one JS frame (on top).
// The stack grows from high addresses to low addresses.
uintptr_t stack[10];
void* stack_base = stack + arraysize(stack);
stack[0] = 101;
stack[1] = 111;
stack[2] = 121;
stack[3] = 131;
stack[4] = 141;
// Index on the stack for the topmost fp (i.e the one right before the C++
// frame).
const int topmost_fp_index = 5;
stack[5] = reinterpret_cast<uintptr_t>(stack + 9); // saved FP.
stack[6] = 100; // Return address into C++ code.
stack[7] = reinterpret_cast<uintptr_t>(stack + 7); // saved SP.
stack[8] = 404;
stack[9] = 505;
register_state.sp = stack;
register_state.fp = stack + 5;
// Put the current PC inside of the code range so it looks valid.
register_state.pc = code + 30;
bool unwound = v8::Unwinder::TryUnwindV8Frames(
entry_stubs, pages_length, code_pages, &register_state, stack_base);
CHECK(unwound);
CHECK_EQ_STACK_REGISTER(stack[topmost_fp_index], register_state.fp);
CHECK_EQ_STACK_REGISTER(stack[topmost_fp_index + 1], register_state.pc);
CHECK_EQ_STACK_REGISTER(stack[topmost_fp_index + 2], register_state.sp);
}
// Creates a fake stack with two JS frames on top of a C++ frame and checks that
// the unwinder correctly unwinds past the JS frames and returns the C++ frame's
// details.
@ -356,7 +308,8 @@ TEST(Unwind_TwoJSFrames_Success_CodePagesAPI) {
stack[1] = 111;
stack[2] = reinterpret_cast<uintptr_t>(stack + 5); // saved FP.
// The fake return address is in the JS code range.
stack[3] = reinterpret_cast<uintptr_t>(code + 10);
const void* jsentry_pc = code + 10;
stack[3] = reinterpret_cast<uintptr_t>(jsentry_pc);
stack[4] = 141;
// Index on the stack for the topmost fp (i.e the one right before the C++
// frame).
@ -373,6 +326,10 @@ TEST(Unwind_TwoJSFrames_Success_CodePagesAPI) {
// Put the current PC inside of the code range so it looks valid.
register_state.pc = code + 30;
// Put the PC in the JSEntryRange.
entry_stubs.js_entry_stub.code.start = jsentry_pc;
entry_stubs.js_entry_stub.code.length_in_bytes = sizeof(uintptr_t);
bool unwound = v8::Unwinder::TryUnwindV8Frames(
entry_stubs, pages_length, code_pages, &register_state, stack_base);
@ -409,6 +366,8 @@ TEST(Unwind_JSEntry_Fail_CodePagesAPI) {
CHECK_EQ(start + 10, register_state.pc);
}
// Tries to unwind a middle frame (i.e not a JSEntry frame) first with a wrong
// stack base, and then with the correct one.
TEST(Unwind_StackBounds_Basic_CodePagesAPI) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@ -425,7 +384,7 @@ TEST(Unwind_StackBounds_Basic_CodePagesAPI) {
uintptr_t stack[3];
stack[0] = reinterpret_cast<uintptr_t>(stack + 2); // saved FP.
stack[1] = 202; // Return address into C++ code.
stack[1] = 202; // saved PC.
stack[2] = 303; // saved SP.
register_state.sp = stack;
@ -471,8 +430,9 @@ TEST(Unwind_StackBounds_WithUnwinding_CodePagesAPI) {
stack[3] = 131;
stack[4] = 141;
stack[5] = reinterpret_cast<uintptr_t>(stack + 9); // saved FP.
stack[6] = reinterpret_cast<uintptr_t>(code + 20); // JS code.
stack[7] = 303; // saved SP.
const void* jsentry_pc = code + 20;
stack[6] = reinterpret_cast<uintptr_t>(jsentry_pc); // JS code.
stack[7] = 303; // saved SP.
stack[8] = 404;
stack[9] = reinterpret_cast<uintptr_t>(stack) +
(12 * sizeof(uintptr_t)); // saved FP (OOB).
@ -484,6 +444,10 @@ TEST(Unwind_StackBounds_WithUnwinding_CodePagesAPI) {
// Put the current PC inside of the code range so it looks valid.
register_state.pc = code + 30;
// Put the PC in the JSEntryRange.
entry_stubs.js_entry_stub.code.start = jsentry_pc;
entry_stubs.js_entry_stub.code.length_in_bytes = sizeof(uintptr_t);
// Unwind will fail because stack[9] FP points outside of the stack.
bool unwound = v8::Unwinder::TryUnwindV8Frames(
entry_stubs, pages_length, code_pages, &register_state, stack_base);