Page MenuHomePhabricator

Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline

bionic_unwind_test.cpp

bionic_unwind_test.cpp

_Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx __unused, void* arg) {
int* count_ptr = reinterpret_cast<int*>(arg);
++*count_ptr;
return _URC_NO_REASON;
}
static void verify_unwind_data(const UnwindData& unwind_data) {
// In order to avoid a false positive, the caller must have at least 2 frames
// outside of the signal handler. This avoids a case where the only frame
// right after the signal handler winds up being garbage.
EXPECT_GT(unwind_data.handler_frame_count, unwind_data.expected_frame_count + 1);
EXPECT_EQ(unwind_data.handler_frame_count + 1, unwind_data.handler_one_deeper_frame_count);
}
struct UnwindData {
volatile bool signal_handler_complete = false;
int expected_frame_count = 0;
int handler_frame_count = 0;
int handler_one_deeper_frame_count = 0;
};
static UnwindData g_unwind_data;
static void noinline UnwindSignalHandler(int) {
_Unwind_Backtrace(FrameCounter, &g_unwind_data.handler_frame_count);
g_unwind_data.handler_one_deeper_frame_count = unwind_one_frame_deeper();
g_unwind_data.signal_handler_complete = true;
}
static void noinline SignalUnwindTest() {
g_unwind_data = {};
_Unwind_Backtrace(FrameCounter, &g_unwind_data.expected_frame_count);
ASSERT_LE(2, g_unwind_data.expected_frame_count)
<< "The current call must contain at least 2 frames for the test to be valid.";
ASSERT_EQ(0, kill(getpid(), SIGUSR1));
while (!g_unwind_data.signal_handler_complete) {}
verify_unwind_data(g_unwind_data);
}
TEST(stack_unwinding, unwind_through_signal_frame) {
ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler);
SignalUnwindTest();
}

File Metadata

Mime Type
text/x-c
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
19343167

Event Timeline