summaryrefslogtreecommitdiffstats
path: root/libbacktrace
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2014-04-29 09:35:30 -0700
committerChristopher Ferris <cferris@google.com>2014-04-30 16:32:47 -0700
commitaa63d9f980f95718fc28ca7e222c1e8d7ca9e778 (patch)
tree98901cf725457fc80c71c6a4bede3fda4e172cb0 /libbacktrace
parentf3661cc2f124bb7ca38285f156c624dda974b4c5 (diff)
downloadsystem_core-aa63d9f980f95718fc28ca7e222c1e8d7ca9e778.tar.gz
system_core-aa63d9f980f95718fc28ca7e222c1e8d7ca9e778.tar.bz2
system_core-aa63d9f980f95718fc28ca7e222c1e8d7ca9e778.zip
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
Diffstat (limited to 'libbacktrace')
-rw-r--r--libbacktrace/BacktraceThread.cpp6
-rw-r--r--libbacktrace/BacktraceThread.h9
-rw-r--r--libbacktrace/backtrace_test.cpp13
3 files changed, 23 insertions, 5 deletions
diff --git a/libbacktrace/BacktraceThread.cpp b/libbacktrace/BacktraceThread.cpp
index 4cda19ec2..e0bab24a9 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 3412d5885..9310a4452 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 a5e141b2c..9744922db 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);
}