Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa63d9f9 authored by Christopher Ferris's avatar Christopher Ferris
Browse files

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
parent f3661cc2
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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));
    }
+9 −0
Original line number Diff line number Diff line
@@ -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 {
+11 −2
Original line number Diff line number Diff line
@@ -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);
}