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

Commit 2678664b authored by Jack He's avatar Jack He
Browse files

Cert: Dump stacktrace when stack process crashed on host

* Use google-breakpad to capture crash event
* Use libbacktrace to walk frames and print stack traces

Bug: 154339809
Test: gd/cert/run --host
Change-Id: Icd90e22f4898f44f35be0abf8dce11506b4e4c36
parent 44edcf97
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -215,12 +215,14 @@ cc_binary {
    static_libs: [
        "libbluetooth_gd",
        "libbluetooth-protos",
        "breakpad_client",
    ],
    shared_libs: [
        "libchrome",
        "libcrypto",
        "libgrpc++_unsecure",
        "libprotobuf-cpp-full",
        "libbacktrace",
    ],
    target: {
        android: {
+5 −1
Original line number Diff line number Diff line
@@ -25,7 +25,11 @@ LOCAL_host_libraries := \
	$(HOST_OUT_SHARED_LIBRARIES)/libgrpc++_unsecure.so \
	$(HOST_OUT_SHARED_LIBRARIES)/liblog.so \
	$(HOST_OUT_SHARED_LIBRARIES)/libz-host.so \
	$(HOST_OUT_SHARED_LIBRARIES)/libprotobuf-cpp-full.so
	$(HOST_OUT_SHARED_LIBRARIES)/libprotobuf-cpp-full.so \
	$(HOST_OUT_SHARED_LIBRARIES)/libunwindstack.so \
	$(HOST_OUT_SHARED_LIBRARIES)/libdexfile_support.so \
	$(HOST_OUT_SHARED_LIBRARIES)/liblzma.so \
	$(HOST_OUT_SHARED_LIBRARIES)/libbacktrace.so

LOCAL_target_executables := \
	$(TARGET_OUT_EXECUTABLES)/bluetooth_stack_with_facade
+49 −7
Original line number Diff line number Diff line
@@ -22,31 +22,73 @@
#include <unistd.h>
#include <csignal>
#include <cstring>
#include <memory>
#include <string>
#include <thread>

#include <client/linux/handler/exception_handler.h>

#include <backtrace/Backtrace.h>
#include <backtrace/backtrace_constants.h>

#include "facade/grpc_root_server.h"
#include "grpc/grpc_module.h"
#include "hal/hci_hal.h"
#include "hal/hci_hal_host_rootcanal.h"
#include "hal/snoop_logger.h"
#include "os/log.h"

using ::bluetooth::hal::HciHalHostRootcanalConfig;
using ::bluetooth::StackManager;
using ::bluetooth::grpc::GrpcModule;
using ::bluetooth::ModuleList;
using ::bluetooth::StackManager;
using ::bluetooth::hal::HciHalHostRootcanalConfig;
using ::bluetooth::os::Thread;

namespace {
::bluetooth::facade::GrpcRootServer grpc_root_server;

void interrupt_handler(int) {
struct sigaction old_act = {};
void interrupt_handler(int signal_number) {
  LOG_INFO("Stopping gRPC root server due to signal: %s[%d]", strsignal(signal_number), signal_number);
  grpc_root_server.StopServer();
  if (old_act.sa_handler != nullptr) {
    LOG_INFO("Calling saved signal handler");
    old_act.sa_handler(signal_number);
  }
}
struct sigaction new_act = {.sa_handler = interrupt_handler};

bool crash_callback(const void* crash_context, size_t crash_context_size, void* context) {
  pid_t tid = BACKTRACE_CURRENT_THREAD;
  if (crash_context_size >= sizeof(google_breakpad::ExceptionHandler::CrashContext)) {
    auto* ctx = static_cast<const google_breakpad::ExceptionHandler::CrashContext*>(crash_context);
    tid = ctx->tid;
    int signal_number = ctx->siginfo.si_signo;
    LOG_ERROR("Process crashed, signal: %s[%d], tid: %d", strsignal(signal_number), signal_number, ctx->tid);
  } else {
    LOG_ERROR("Process crashed, signal: unknown, tid: unknown");
  }
  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid));
  if (backtrace == nullptr) {
    LOG_ERROR("Failed to create backtrace object");
    return false;
  }
  if (!backtrace->Unwind(0)) {
    LOG_ERROR("backtrace->Unwind failed");
    return false;
  }
  LOG_ERROR("Backtrace:");
  for (size_t i = 0; i < backtrace->NumFrames(); i++) {
    LOG_ERROR("%s", backtrace->FormatFrameData(i).c_str());
  }
  return true;
}

}  // namespace

// The entry point for the binary with libbluetooth + facades
int main(int argc, const char** argv) {
  google_breakpad::MinidumpDescriptor descriptor(google_breakpad::MinidumpDescriptor::kMicrodumpOnConsole);
  google_breakpad::ExceptionHandler eh(descriptor, nullptr, nullptr, nullptr, true, -1);
  eh.set_crash_handler(crash_callback);

  int root_server_port = 8897;
  int grpc_port = 8899;
  int signal_port = 8895;
@@ -81,7 +123,7 @@ int main(int argc, const char** argv) {
    }
  }

  signal(SIGINT, interrupt_handler);
  sigaction(SIGINT, &new_act, &old_act);
  grpc_root_server.StartServer("0.0.0.0", root_server_port, grpc_port);
  int tester_signal_socket = socket(AF_INET, SOCK_STREAM, 0);
  struct sockaddr_in addr;