#include "base/include/debug/backtrace.h"
#include <cstdlib>
#include <mutex>
namespace lynx {
namespace base {
namespace debug {
namespace {
std::mutex& GetBacktraceDelegateMutex() {
static std::mutex mutex;
return mutex;
}
BacktraceDelegate*& GetBacktraceDelegate() {
static BacktraceDelegate* delegate = nullptr;
return delegate;
}
}
void SetBacktraceDelegate(BacktraceDelegate* delegate) {
std::lock_guard<std::mutex> lock(GetBacktraceDelegateMutex());
auto& current = GetBacktraceDelegate();
if (current == delegate) {
return;
}
current = delegate;
}
std::string GetBacktraceInfo(std::string& error_message) {
BacktraceDelegate* delegate = nullptr;
{
std::lock_guard<std::mutex> lock(GetBacktraceDelegateMutex());
delegate = GetBacktraceDelegate();
}
if (delegate) {
std::string traceInfo = delegate->TraceLog(error_message, 2);
if (!traceInfo.empty()) {
return traceInfo;
}
}
#if OS_IOS
error_message.append("\n\n");
constexpr int max = 30;
void* buffer[max];
int stack_num = backtrace(buffer, max);
char** stacktrace = backtrace_symbols(buffer, stack_num);
if (stacktrace == nullptr) {
return "";
}
for (int i = 2; i < stack_num; ++i) {
int order = i - 2;
int offset = order >= 10 ? 3 : 2;
error_message.append(std::to_string(order))
.append(stacktrace[i] + offset)
.append("\n");
}
free(stacktrace);
#endif
return error_message;
}
}
}
}