Fix flaky signal tests.
The signal tests that send a SIGUSR1 signal to a remote process, can lead to a case where the code winds up in a location for which the unwind information is not 100% accurate. This happens near the end of the atomic functions which manipulate the stack right before returning, but do not have separate cfi instructions for those last few instructions. Add a new test type for the from_context test that will wait explicitly for the global g_finish and not piggy back on the remote test type. Bug: 122902885 Test: Ran flaky tests 1000 times without failure on a taimen. Change-Id: I7d0c9b016e3a3a2c0c0949cf74af11d7785a008c
This commit is contained in:
parent
b26b07d845
commit
bc6a7e51e4
1 changed files with 15 additions and 3 deletions
|
@ -47,6 +47,7 @@ namespace unwindstack {
|
|||
enum TestTypeEnum : uint8_t {
|
||||
TEST_TYPE_LOCAL_UNWINDER = 0,
|
||||
TEST_TYPE_LOCAL_UNWINDER_FROM_PID,
|
||||
TEST_TYPE_LOCAL_WAIT_FOR_FINISH,
|
||||
TEST_TYPE_REMOTE,
|
||||
TEST_TYPE_REMOTE_WITH_INVALID_CALL,
|
||||
};
|
||||
|
@ -79,7 +80,10 @@ static void SignalHandler(int, siginfo_t*, void* sigcontext) {
|
|||
|
||||
extern "C" void SignalInnerFunction() {
|
||||
g_signal_ready_for_remote = true;
|
||||
while (!g_finish.load()) {
|
||||
// Avoid any function calls because not every instruction will be
|
||||
// unwindable.
|
||||
// This method of looping is only used when testing a remote unwind.
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,6 +138,11 @@ static void VerifyUnwind(pid_t pid, Maps* maps, Regs* regs,
|
|||
// off. If this doesn't happen, then all of the calls will be optimized
|
||||
// away.
|
||||
extern "C" void InnerFunction(TestTypeEnum test_type) {
|
||||
if (test_type == TEST_TYPE_LOCAL_WAIT_FOR_FINISH) {
|
||||
while (!g_finish.load()) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (test_type == TEST_TYPE_REMOTE || test_type == TEST_TYPE_REMOTE_WITH_INVALID_CALL) {
|
||||
g_ready_for_remote = true;
|
||||
g_ready = true;
|
||||
|
@ -141,7 +150,10 @@ extern "C" void InnerFunction(TestTypeEnum test_type) {
|
|||
void (*crash_func)() = nullptr;
|
||||
crash_func();
|
||||
}
|
||||
while (!g_finish.load()) {
|
||||
// Avoid any function calls because not every instruction will be
|
||||
// unwindable.
|
||||
// This method of looping is only used when testing a remote unwind.
|
||||
while (true) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -271,7 +283,7 @@ TEST_F(UnwindTest, from_context) {
|
|||
std::atomic_int tid(0);
|
||||
std::thread thread([&]() {
|
||||
tid = syscall(__NR_gettid);
|
||||
OuterFunction(TEST_TYPE_REMOTE);
|
||||
OuterFunction(TEST_TYPE_LOCAL_WAIT_FOR_FINISH);
|
||||
});
|
||||
|
||||
struct sigaction act, oldact;
|
||||
|
|
Loading…
Reference in a new issue