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

Commit fd8fab19 authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "Use async safe logging in signal handlers."

parents 7245ab6a f30a810b
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -110,7 +110,7 @@ cc_library {
                "libunwind",
                "libunwind",
            ],
            ],


            static_libs: ["libcutils"],
            static_libs: ["libasync_safe", "libcutils"],
        },
        },
    },
    },
}
}
+41 −0
Original line number Original line 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 Original line Diff line number Diff line
@@ -31,8 +31,8 @@
#include <backtrace/Backtrace.h>
#include <backtrace/Backtrace.h>
#include <backtrace/BacktraceMap.h>
#include <backtrace/BacktraceMap.h>


#include "BacktraceAsyncSafeLog.h"
#include "BacktraceCurrent.h"
#include "BacktraceCurrent.h"
#include "BacktraceLog.h"
#include "ThreadEntry.h"
#include "ThreadEntry.h"
#include "thread_utils.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);
    *out_value = *reinterpret_cast<word_t*>(ptr);
    return true;
    return true;
  } else {
  } 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);
    *out_value = static_cast<word_t>(-1);
    return false;
    return false;
  }
  }
@@ -114,7 +114,8 @@ class ErrnoRestorer {
static void SignalLogOnly(int, siginfo_t*, void*) {
static void SignalLogOnly(int, siginfo_t*, void*) {
  ErrnoRestorer restore;
  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) {
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);
  ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false);
  if (!entry) {
  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;
    return;
  }
  }


@@ -141,7 +142,7 @@ static void SignalHandler(int, siginfo_t*, void* sigcontext) {
    entry->Wake();
    entry->Wake();
  } else {
  } else {
    // At this point, it is possible that entry has been freed, so just exit.
    // 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;
  act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
  sigemptyset(&act.sa_mask);
  sigemptyset(&act.sa_mask);
  if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) {
  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);
    ThreadEntry::Remove(entry);
    pthread_mutex_unlock(&g_sigaction_mutex);
    pthread_mutex_unlock(&g_sigaction_mutex);
    error_ = BACKTRACE_UNWIND_ERROR_INTERNAL;
    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.
    // Wait for the thread to indicate it is done with the ThreadEntry.
    if (!entry->Wait(3)) {
    if (!entry->Wait(3)) {
      // Send a warning, but do not mark as a failure to unwind.
      // 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 {
  } else {
    // Check to see if the thread has disappeared.
    // 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;
      error_ = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST;
    } else {
    } else {
      error_ = BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT;
      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 Original line Diff line number Diff line
@@ -21,7 +21,7 @@
#include <time.h>
#include <time.h>
#include <ucontext.h>
#include <ucontext.h>


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


// Initialize static member variables.
// Initialize static member variables.
@@ -106,7 +106,7 @@ bool ThreadEntry::Wait(int value) {
  while (wait_value_ != value) {
  while (wait_value_ != value) {
    int ret = pthread_cond_timedwait(&wait_cond_, &wait_mutex_, &ts);
    int ret = pthread_cond_timedwait(&wait_cond_, &wait_mutex_, &ts);
    if (ret != 0) {
    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;
      wait_completed = false;
      break;
      break;
    }
    }