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
This commit is contained in:
parent
f3661cc2f1
commit
aa63d9f980
3 changed files with 23 additions and 5 deletions
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue