diff options
author | Christopher Ferris <cferris@google.com> | 2014-04-29 09:35:30 -0700 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2014-04-30 16:32:47 -0700 |
commit | aa63d9f980f95718fc28ca7e222c1e8d7ca9e778 (patch) | |
tree | 98901cf725457fc80c71c6a4bede3fda4e172cb0 | |
parent | f3661cc2f124bb7ca38285f156c624dda974b4c5 (diff) | |
download | system_core-aa63d9f980f95718fc28ca7e222c1e8d7ca9e778.zip system_core-aa63d9f980f95718fc28ca7e222c1e8d7ca9e778.tar.gz system_core-aa63d9f980f95718fc28ca7e222c1e8d7ca9e778.tar.bz2 |
Use real time signal for threads instead of SIGURG.
This guarantees that any application is not also using this signal
for some other purpose.
Change-Id: I7c9bbb0ec8bb4e13322ecda951bcd43c6bf6ee1a
-rw-r--r-- | libbacktrace/BacktraceThread.cpp | 6 | ||||
-rw-r--r-- | libbacktrace/BacktraceThread.h | 9 | ||||
-rw-r--r-- | libbacktrace/backtrace_test.cpp | 13 |
3 files changed, 23 insertions, 5 deletions
diff --git a/libbacktrace/BacktraceThread.cpp b/libbacktrace/BacktraceThread.cpp index 4cda19e..e0bab24 100644 --- a/libbacktrace/BacktraceThread.cpp +++ b/libbacktrace/BacktraceThread.cpp @@ -136,7 +136,7 @@ void BacktraceThread::FinishUnwind() { bool BacktraceThread::TriggerUnwindOnThread(ThreadEntry* entry) { entry->state = STATE_WAITING; - if (tgkill(Pid(), Tid(), SIGURG) != 0) { + if (tgkill(Pid(), Tid(), THREAD_SIGNAL) != 0) { BACK_LOGW("tgkill failed %s", strerror(errno)); return false; } @@ -196,9 +196,9 @@ bool BacktraceThread::Unwind(size_t num_ignore_frames) { act.sa_sigaction = SignalHandler; act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; sigemptyset(&act.sa_mask); - if (sigaction(SIGURG, &act, &oldact) == 0) { + if (sigaction(THREAD_SIGNAL, &act, &oldact) == 0) { retval = TriggerUnwindOnThread(entry); - sigaction(SIGURG, &oldact, NULL); + sigaction(THREAD_SIGNAL, &oldact, NULL); } else { BACK_LOGW("sigaction failed %s", strerror(errno)); } diff --git a/libbacktrace/BacktraceThread.h b/libbacktrace/BacktraceThread.h index 3412d58..9310a44 100644 --- a/libbacktrace/BacktraceThread.h +++ b/libbacktrace/BacktraceThread.h @@ -18,6 +18,7 @@ #define _LIBBACKTRACE_BACKTRACE_THREAD_H #include <inttypes.h> +#include <signal.h> #include <sys/types.h> #include "BacktraceImpl.h" @@ -29,6 +30,14 @@ enum state_e { STATE_CANCEL, }; +// The signal used to cause a thread to dump the stack. +#if defined(__GLIBC__) +// GLIBC reserves __SIGRTMIN signals, so use SIGRTMIN to avoid errors. +#define THREAD_SIGNAL SIGRTMIN +#else +#define THREAD_SIGNAL (__SIGRTMIN+1) +#endif + class BacktraceThreadInterface; struct ThreadEntry { diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp index a5e141b..9744922 100644 --- a/libbacktrace/backtrace_test.cpp +++ b/libbacktrace/backtrace_test.cpp @@ -33,6 +33,9 @@ #include <backtrace/BacktraceMap.h> #include <UniquePtr.h> +// For the THREAD_SIGNAL definition. +#include "BacktraceThread.h" + #include <cutils/atomic.h> #include <gtest/gtest.h> @@ -460,9 +463,15 @@ TEST(libbacktrace, thread_level_trace) { // Wait up to 2 seconds for the tid to be set. ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2)); + // Make sure that the thread signal used is not visible when compiled for + // the target. +#if !defined(__GLIBC__) + ASSERT_LT(THREAD_SIGNAL, SIGRTMIN); +#endif + // Save the current signal action and make sure it is restored afterwards. struct sigaction cur_action; - ASSERT_TRUE(sigaction(SIGURG, NULL, &cur_action) == 0); + ASSERT_TRUE(sigaction(THREAD_SIGNAL, NULL, &cur_action) == 0); UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid)); ASSERT_TRUE(backtrace.get() != NULL); @@ -475,7 +484,7 @@ TEST(libbacktrace, thread_level_trace) { // Verify that the old action was restored. struct sigaction new_action; - ASSERT_TRUE(sigaction(SIGURG, NULL, &new_action) == 0); + ASSERT_TRUE(sigaction(THREAD_SIGNAL, NULL, &new_action) == 0); EXPECT_EQ(cur_action.sa_sigaction, new_action.sa_sigaction); EXPECT_EQ(cur_action.sa_flags, new_action.sa_flags); } |