/*
 *  Copyright 2019 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "sdk/android/native_api/stacktrace/stacktrace.h"

#include <dlfcn.h>
#include <errno.h>
#include <linux/futex.h>
#include <sys/ptrace.h>
#include <sys/ucontext.h>
#include <syscall.h>
#include <ucontext.h>
#include <unistd.h>
#include <unwind.h>
#include <atomic>

// ptrace.h is polluting the namespace. Clean up to avoid conflicts with rtc.
#if defined(DS)
#undef DS
#endif

#include "absl/base/attributes.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/synchronization/mutex.h"

namespace webrtc {

namespace {

// Maximum stack trace depth we allow before aborting.
constexpr size_t kMaxStackSize = 100;
// Signal that will be used to interrupt threads. SIGURG ("Urgent condition on
// socket") is chosen because Android does not set up a specific handler for
// this signal.
constexpr int kSignal = SIGURG;

// Note: This class is only meant for use within this file, and for the
// simplified use case of a single Wait() and a single Signal(), followed by
// discarding the object (never reused).
// This is a replacement of rtc::Event that is async-safe and doesn't use
// pthread api. This is necessary since signal handlers cannot allocate memory
// or use pthread api. This class is ported from Chromium.
class AsyncSafeWaitableEvent {
 public:
  AsyncSafeWaitableEvent() {
    std::atomic_store_explicit(&futex_, 0, std::memory_order_release);
  }

  ~AsyncSafeWaitableEvent() {}

  // Returns false in the event of an error and errno is set to indicate the
  // cause of the error.
  bool Wait() {
    // futex() can wake up spuriously if this memory address was previously used
    // for a pthread mutex. So, also check the condition.
    while (true) {
      int res = syscall(SYS_futex, &futex_, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0,
                        nullptr, nullptr, 0);
      if (std::atomic_load_explicit(&futex_, std::memory_order_acquire) != 0)
        return true;
      if (res != 0)
        return false;
    }
  }

  void Signal() {
    std::atomic_store_explicit(&futex_, 1, std::memory_order_release);
    syscall(SYS_futex, &futex_, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, nullptr,
            nullptr, 0);
  }

 private:
  std::atomic<int> futex_;
};

// Struct to store the arguments to the signal handler.
struct SignalHandlerOutputState {
  // This function is called iteratively for each stack trace element and stores
  // the element in the array from `unwind_output_state`.
  static _Unwind_Reason_Code UnwindBacktrace(
      struct _Unwind_Context* unwind_context,
      void* unwind_output_state);

  // This event is signalled when signal handler is done executing.
  AsyncSafeWaitableEvent signal_handler_finish_event;
  // Running counter of array index below.
  size_t stack_size_counter = 0;
  // Array storing the stack trace.
  uintptr_t addresses[kMaxStackSize];
};

// This function is called iteratively for each stack trace element and stores
// the element in the array from `unwind_output_state`.
_Unwind_Reason_Code SignalHandlerOutputState::UnwindBacktrace(
    struct _Unwind_Context* unwind_context,
    void* unwind_output_state) {
  SignalHandlerOutputState* const output_state =
      static_cast<SignalHandlerOutputState*>(unwind_output_state);

  // Abort if output state is corrupt.
  if (output_state == nullptr)
    return _URC_END_OF_STACK;

  // Avoid overflowing the stack trace array.
  if (output_state->stack_size_counter >= kMaxStackSize)
    return _URC_END_OF_STACK;

  // Store the instruction pointer in the array. Subtract 2 since we want to get
  // the call instruction pointer, not the return address which is the
  // instruction after.
  output_state->addresses[output_state->stack_size_counter] =
      _Unwind_GetIP(unwind_context) - 2;
  ++output_state->stack_size_counter;

  return _URC_NO_REASON;
}

class GlobalStackUnwinder {
 public:
  static GlobalStackUnwinder& Get() {
    static GlobalStackUnwinder* const instance = new GlobalStackUnwinder();
    return *instance;
  }
  const char* CaptureRawStacktrace(int pid,
                                   int tid,
                                   SignalHandlerOutputState* params);

 private:
  GlobalStackUnwinder() { current_output_state_.store(nullptr); }

  // Temporarily installed signal handler.
  static void SignalHandler(int signum, siginfo_t* info, void* ptr);

  Mutex mutex_;

  // Accessed by signal handler.
  static std::atomic<SignalHandlerOutputState*> current_output_state_;
  // A signal handler mustn't use locks.
  static_assert(std::atomic<SignalHandlerOutputState*>::is_always_lock_free);
};

std::atomic<SignalHandlerOutputState*>
    GlobalStackUnwinder::current_output_state_;

// This signal handler is exectued on the interrupted thread.
void GlobalStackUnwinder::SignalHandler(int signum,
                                        siginfo_t* info,
                                        void* ptr) {
  // This should have been set by the thread requesting the stack trace.
  SignalHandlerOutputState* signal_handler_output_state =
      current_output_state_.load();
  if (signal_handler_output_state != nullptr) {
    _Unwind_Backtrace(&SignalHandlerOutputState::UnwindBacktrace,
                      signal_handler_output_state);
    signal_handler_output_state->signal_handler_finish_event.Signal();
  }
}

// Temporarily change the signal handler to a function that records a raw stack
// trace and interrupt the given tid. This function will block until the output
// thread stack trace has been stored in `params`. The return value is an error
// string on failure and null on success.
const char* GlobalStackUnwinder::CaptureRawStacktrace(
    int pid,
    int tid,
    SignalHandlerOutputState* params) {
  // This function is under a global lock since we are changing the signal
  // handler and using global state for the output. The lock is to ensure only
  // one thread at a time gets captured. The lock also means we need to be very
  // careful with what statements we put in this function, and we should even
  // avoid logging here.
  struct sigaction act;
  struct sigaction old_act;
  memset(&act, 0, sizeof(act));
  act.sa_sigaction = &SignalHandler;
  act.sa_flags = SA_RESTART | SA_SIGINFO;
  sigemptyset(&act.sa_mask);

  MutexLock loch(&mutex_);
  current_output_state_.store(params);

  if (sigaction(kSignal, &act, &old_act) != 0)
    return "Failed to change signal action";

  // Interrupt the thread which will execute SignalHandler() on the given
  // thread.
  if (tgkill(pid, tid, kSignal) != 0)
    return "Failed to interrupt thread";

  // Wait until the thread is done recording its stack trace.
  if (!params->signal_handler_finish_event.Wait())
    return "Failed to wait for thread to finish stack trace";

  // Restore previous signal handler.
  sigaction(kSignal, &old_act, /* old_act= */ nullptr);

  return nullptr;
}

// Translate addresses into symbolic information using dladdr().
std::vector<StackTraceElement> FormatStackTrace(
    const SignalHandlerOutputState& params) {
  std::vector<StackTraceElement> stack_trace;
  for (size_t i = 0; i < params.stack_size_counter; ++i) {
    const uintptr_t address = params.addresses[i];

    Dl_info dl_info = {};
    if (!dladdr(reinterpret_cast<void*>(address), &dl_info)) {
      RTC_LOG(LS_WARNING)
          << "Could not translate address to symbolic information for address "
          << address << " at stack depth " << i;
      continue;
    }

    StackTraceElement stack_trace_element;
    stack_trace_element.shared_object_path = dl_info.dli_fname;
    stack_trace_element.relative_address = static_cast<uint32_t>(
        address - reinterpret_cast<uintptr_t>(dl_info.dli_fbase));
    stack_trace_element.symbol_name = dl_info.dli_sname;

    stack_trace.push_back(stack_trace_element);
  }

  return stack_trace;
}

}  // namespace

std::vector<StackTraceElement> GetStackTrace(int tid) {
  // Only a thread itself can unwind its stack, so we will interrupt the given
  // tid with a custom signal handler in order to unwind its stack. The stack
  // will be recorded to `params` through the use of the global pointer
  // `g_signal_handler_param`.
  SignalHandlerOutputState params;

  const char* error_string =
      GlobalStackUnwinder::Get().CaptureRawStacktrace(getpid(), tid, &params);
  if (error_string != nullptr) {
    RTC_LOG(LS_ERROR) << error_string << ". tid: " << tid
                      << ". errno: " << errno;
    return {};
  }
  if (params.stack_size_counter >= kMaxStackSize) {
    RTC_LOG(LS_WARNING) << "Stack trace for thread " << tid << " was truncated";
  }
  return FormatStackTrace(params);
}

std::vector<StackTraceElement> GetStackTrace() {
  SignalHandlerOutputState params;
  _Unwind_Backtrace(&SignalHandlerOutputState::UnwindBacktrace, &params);
  if (params.stack_size_counter >= kMaxStackSize) {
    RTC_LOG(LS_WARNING) << "Stack trace was truncated";
  }
  return FormatStackTrace(params);
}

std::string StackTraceToString(
    const std::vector<StackTraceElement>& stack_trace) {
  rtc::StringBuilder string_builder;

  for (size_t i = 0; i < stack_trace.size(); ++i) {
    const StackTraceElement& stack_trace_element = stack_trace[i];
    string_builder.AppendFormat(
        "#%02zu pc %08x %s", i,
        static_cast<uint32_t>(stack_trace_element.relative_address),
        stack_trace_element.shared_object_path);
    // The symbol name is only available for unstripped .so files.
    if (stack_trace_element.symbol_name != nullptr)
      string_builder.AppendFormat(" %s", stack_trace_element.symbol_name);

    string_builder.AppendFormat("\n");
  }

  return string_builder.Release();
}

}  // namespace webrtc
