TEST(libbacktrace, thread_level_trace) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); thread_t thread_data = { 0, 0, 0 }; pthread_t thread; ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0); // Wait up to 2 seconds for the tid to be set. ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2)); // Save the current signal action and make sure it is restored afterwards. struct sigaction cur_action; ASSERT_TRUE(sigaction(SIGURG, NULL, &cur_action) == 0); UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid)); ASSERT_TRUE(backtrace.get() != NULL); ASSERT_TRUE(backtrace->Unwind(0)); VerifyLevelDump(backtrace.get()); // Tell the thread to exit its infinite loop. android_atomic_acquire_store(0, &thread_data.state); // Verify that the old action was restored. struct sigaction new_action; ASSERT_TRUE(sigaction(SIGURG, NULL, &new_action) == 0); EXPECT_EQ(cur_action.sa_sigaction, new_action.sa_sigaction); EXPECT_EQ(cur_action.sa_flags, new_action.sa_flags); }
void VerifyLevelThread(void*) { UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid())); ASSERT_TRUE(backtrace.get() != NULL); ASSERT_TRUE(backtrace->Unwind(0)); VerifyLevelDump(backtrace.get()); }
void VerifyLevelBacktrace(void*) { UniquePtr<Backtrace> backtrace( Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD)); ASSERT_TRUE(backtrace.get() != NULL); ASSERT_TRUE(backtrace->Unwind(0)); VerifyLevelDump(backtrace.get()); }
void VerifyLevelThread(void*) { backtrace_context_t context; ASSERT_TRUE(backtrace_create_context(&context, getpid(), gettid(), 0)); VerifyLevelDump(context.backtrace); backtrace_destroy_context(&context); }
void VerifyLevelBacktrace(void*) { backtrace_context_t context; ASSERT_TRUE(backtrace_create_context(&context, -1, -1, 0)); VerifyLevelDump(context.backtrace); backtrace_destroy_context(&context); }