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

Commit 49702900 authored by Christopher Ferris's avatar Christopher Ferris Committed by android-build-merger
Browse files

Merge "Use async safe logging in signal handlers."

am: fd8fab19

Change-Id: I66b41a0d3035439f85acc52e98348de0bba56576
parents 140d1f51 fd8fab19
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ cc_library {
                "libunwind",
            ],

            static_libs: ["libcutils"],
            static_libs: ["libasync_safe", "libcutils"],
        },
    },
}
+41 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _LIBBACKTRACE_BACKTRACE_ASYNC_SAFE_LOG_H
#define _LIBBACKTRACE_BACKTRACE_ASYNC_SAFE_LOG_H

#if defined(__ANDROID__)

#include <async_safe/log.h>

// Logging macros for use in signal handler, only available on target.
#define BACK_ASYNC_SAFE_LOGW(format, ...)                                                     \
  async_safe_format_log(ANDROID_LOG_WARN, "libbacktrace", "%s: " format, __PRETTY_FUNCTION__, \
                        ##__VA_ARGS__)

#define BACK_ASYNC_SAFE_LOGE(format, ...)                                                      \
  async_safe_format_log(ANDROID_LOG_ERROR, "libbacktrace", "%s: " format, __PRETTY_FUNCTION__, \
                        ##__VA_ARGS__)

#else

#define BACK_ASYNC_SAFE_LOGW(format, ...)

#define BACK_ASYNC_SAFE_LOGE(format, ...)

#endif

#endif  // _LIBBACKTRACE_BACKTRACE_ASYNC_SAFE_LOG_H
+9 −8
Original line number Diff line number Diff line
@@ -31,8 +31,8 @@
#include <backtrace/Backtrace.h>
#include <backtrace/BacktraceMap.h>

#include "BacktraceAsyncSafeLog.h"
#include "BacktraceCurrent.h"
#include "BacktraceLog.h"
#include "ThreadEntry.h"
#include "thread_utils.h"

@@ -47,7 +47,7 @@ bool BacktraceCurrent::ReadWord(uintptr_t ptr, word_t* out_value) {
    *out_value = *reinterpret_cast<word_t*>(ptr);
    return true;
  } else {
    BACK_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr));
    BACK_ASYNC_SAFE_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr));
    *out_value = static_cast<word_t>(-1);
    return false;
  }
@@ -114,7 +114,8 @@ class ErrnoRestorer {
static void SignalLogOnly(int, siginfo_t*, void*) {
  ErrnoRestorer restore;

  BACK_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(), gettid(), THREAD_SIGNAL);
  BACK_ASYNC_SAFE_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(), gettid(),
                       THREAD_SIGNAL);
}

static void SignalHandler(int, siginfo_t*, void* sigcontext) {
@@ -122,7 +123,7 @@ static void SignalHandler(int, siginfo_t*, void* sigcontext) {

  ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false);
  if (!entry) {
    BACK_LOGE("pid %d, tid %d entry not found", getpid(), gettid());
    BACK_ASYNC_SAFE_LOGE("pid %d, tid %d entry not found", getpid(), gettid());
    return;
  }

@@ -141,7 +142,7 @@ static void SignalHandler(int, siginfo_t*, void* sigcontext) {
    entry->Wake();
  } else {
    // At this point, it is possible that entry has been freed, so just exit.
    BACK_LOGE("Timed out waiting for unwind thread to indicate it completed.");
    BACK_ASYNC_SAFE_LOGE("Timed out waiting for unwind thread to indicate it completed.");
  }
}

@@ -159,7 +160,7 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) {
  act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
  sigemptyset(&act.sa_mask);
  if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) {
    BACK_LOGE("sigaction failed: %s", strerror(errno));
    BACK_ASYNC_SAFE_LOGE("sigaction failed: %s", strerror(errno));
    ThreadEntry::Remove(entry);
    pthread_mutex_unlock(&g_sigaction_mutex);
    error_ = BACKTRACE_UNWIND_ERROR_INTERNAL;
@@ -212,7 +213,7 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) {
    // Wait for the thread to indicate it is done with the ThreadEntry.
    if (!entry->Wait(3)) {
      // Send a warning, but do not mark as a failure to unwind.
      BACK_LOGW("Timed out waiting for signal handler to indicate it finished.");
      BACK_ASYNC_SAFE_LOGW("Timed out waiting for signal handler to indicate it finished.");
    }
  } else {
    // Check to see if the thread has disappeared.
@@ -220,7 +221,7 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) {
      error_ = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST;
    } else {
      error_ = BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT;
      BACK_LOGE("Timed out waiting for signal handler to get ucontext data.");
      BACK_ASYNC_SAFE_LOGE("Timed out waiting for signal handler to get ucontext data.");
    }
  }

+2 −2
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@
#include <time.h>
#include <ucontext.h>

#include "BacktraceLog.h"
#include "BacktraceAsyncSafeLog.h"
#include "ThreadEntry.h"

// Initialize static member variables.
@@ -106,7 +106,7 @@ bool ThreadEntry::Wait(int value) {
  while (wait_value_ != value) {
    int ret = pthread_cond_timedwait(&wait_cond_, &wait_mutex_, &ts);
    if (ret != 0) {
      BACK_LOGW("pthread_cond_timedwait for value %d failed: %s", value, strerror(ret));
      BACK_ASYNC_SAFE_LOGW("pthread_cond_timedwait for value %d failed: %s", value, strerror(ret));
      wait_completed = false;
      break;
    }