backtrace: Use a static buffer in backtrace_ctx for symbols

Replace the dynamic allocation in os_backtrace_symbols() with a static
buffer embedded in struct backtrace_ctx. This avoids malloc recursion
when backtrace is called from within dlmalloc (e.g., for the upcoming
mcheck caller-tracking).

The API gets a complete rework as part of this:

- Combine addrs[] and syms[] arrays into struct backtrace_frame with
  addr and sym fields
- Store the strings in a unified buffer, with pointers from an array
- Change os_backtrace_symbols() to take ctx pointer and fill sym_buf
- Remove os_backtrace_symbols_free() as nothing needs freeing
- Rename BACKTRACE_MAX to BACKTRACE_MAX_FRAMES

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
This commit is contained in:
Simon Glass
2025-12-08 09:45:10 -07:00
parent 95f10a6302
commit e1e95b2887
6 changed files with 86 additions and 103 deletions

View File

@@ -15,24 +15,25 @@
/* Test backtrace_init() and backtrace_get_syms() */
static int lib_test_backtrace(struct unit_test_state *uts)
{
char buf[BACKTRACE_BUFSZ];
struct backtrace_ctx ctx;
static struct backtrace_ctx ctx;
bool found_self = false;
bool found_ut_run_list = false;
uint i;
ut_assert(backtrace_init(&ctx, 0) > 2);
ut_assertok(backtrace_get_syms(&ctx, buf, sizeof(buf)));
ut_assertok(backtrace_get_syms(&ctx, NULL, 0));
/*
* Check for known functions in the call stack. With libbacktrace
* we can find static functions too, so check for this test function.
*/
for (i = 0; i < ctx.count; i++) {
if (ctx.syms[i]) {
if (strstr(ctx.syms[i], "lib_test_backtrace"))
const struct backtrace_frame *frame = &ctx.frame[i];
if (frame->sym) {
if (strstr(frame->sym, "lib_test_backtrace"))
found_self = true;
if (strstr(ctx.syms[i], "ut_run_list"))
if (strstr(frame->sym, "ut_run_list"))
found_ut_run_list = true;
}
}