Skip to content

Commit a63a104

Browse files
committed
options/glibc: implement backtrace
1 parent 68a53b8 commit a63a104

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

meson.build

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ rtlib_deps = []
452452

453453
if not headers_only
454454
if libgcc_dependency
455+
libgcc_s = meson.get_compiler('c').find_library('gcc_s', required: false)
455456
libgcc = meson.get_compiler('c').find_library('gcc', required: false)
456457

457458
compiler_rt_name = 'libclang_rt.builtins-' + host_machine.cpu_family()
@@ -462,6 +463,10 @@ if not headers_only
462463
compiler_rt = meson.get_compiler('c').find_library(compiler_rt_name, required: false)
463464
endif
464465

466+
if libgcc_s.found()
467+
rtlib_deps += libgcc_s
468+
endif
469+
465470
if libgcc.found()
466471
rtlib_deps += libgcc
467472
elif compiler_rt.found()

options/glibc/generic/execinfo.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,47 @@
11
#include <execinfo.h>
2+
#include <unwind.h>
23

34
#include <bits/ensure.h>
45
#include <mlibc/debug.hpp>
56

6-
int backtrace(void **, int) {
7-
mlibc::infoLogger() << "mlibc: backtrace() is a stub!" << frg::endlog;
8-
return 0;
7+
namespace {
8+
9+
struct UnwindState {
10+
void **frames;
11+
int count;
12+
int current_frame = 0;
13+
};
14+
15+
_Unwind_Reason_Code trace(_Unwind_Context *context, void *arg) {
16+
uintptr_t ip = _Unwind_GetIP(context);
17+
18+
if (ip) {
19+
#if defined(__x86_64__) || defined(__i386__)
20+
ip--;
21+
#elif defined(__aarch64__) || defined(__loongarch64)
22+
ip -= 4;
23+
#elif defined(__riscv) || defined(__m68k__)
24+
ip -= 2;
25+
#else
26+
#warning "Missing support for architecture"
27+
ip--;
28+
#endif
29+
}
30+
31+
UnwindState *state = static_cast<UnwindState *>(arg);
32+
state->frames[state->current_frame++] = reinterpret_cast<void *>(ip);
33+
return (state->current_frame >= state->count) ? _URC_END_OF_STACK : _URC_NO_REASON;
34+
}
35+
36+
} // namespace
37+
38+
int backtrace(void **buffer, int size) {
39+
if (size <= 0)
40+
return 0;
41+
42+
UnwindState state{buffer, size};
43+
_Unwind_Backtrace(trace, &state);
44+
return state.current_frame;
945
}
1046

1147
char **backtrace_symbols(void *const *, int) {

0 commit comments

Comments
 (0)