Add backtrace functions for sandbox, including: - os_backtrace() to collect addresses into a caller-supplied buffer - os_backtrace_symbols() to convert addresses to symbol strings - os_backtrace_symbols_free() to free the symbol array The libbacktrace library (bundled with GCC) reads DWARF debug information to provide detailed symbol resolution including function names (even for static functions), source file paths, and line numbers. The sandbox backtrace implementation wraps these OS functions to implement the generic backtrace API (backtrace_init, backtrace_get_syms, etc.). Enable it for just the 'sandbox' board. Add the library for the Rust example too. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com>
72 lines
1.4 KiB
C
72 lines
1.4 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Backtrace support for sandbox
|
|
*
|
|
* Copyright 2025 Canonical Ltd
|
|
* Written by Simon Glass <simon.glass@canonical.com>
|
|
*/
|
|
|
|
#include <backtrace.h>
|
|
#include <errno.h>
|
|
#include <os.h>
|
|
#include <string.h>
|
|
|
|
int backtrace_init(struct backtrace_ctx *ctx, uint skip)
|
|
{
|
|
uint i;
|
|
|
|
for (i = 0; i < BACKTRACE_MAX; i++)
|
|
ctx->syms[i] = NULL;
|
|
/* +1 to skip this function */
|
|
ctx->count = os_backtrace(ctx->addrs, BACKTRACE_MAX, skip + 1);
|
|
|
|
return ctx->count;
|
|
}
|
|
|
|
int backtrace_get_syms(struct backtrace_ctx *ctx, char *buf, int size)
|
|
{
|
|
char **raw_syms;
|
|
size_t total_len;
|
|
char *p;
|
|
uint i;
|
|
|
|
raw_syms = os_backtrace_symbols(ctx->addrs, ctx->count);
|
|
if (!raw_syms)
|
|
return -ENOMEM;
|
|
|
|
/* Calculate total buffer size needed */
|
|
total_len = 0;
|
|
for (i = 0; i < ctx->count; i++) {
|
|
if (raw_syms[i])
|
|
total_len += strlen(raw_syms[i]) + 1;
|
|
else
|
|
total_len += 1; /* empty string */
|
|
}
|
|
|
|
if ((size_t)size < total_len) {
|
|
os_backtrace_symbols_free(raw_syms);
|
|
return -ENOSPC;
|
|
}
|
|
|
|
/* Copy strings into buffer */
|
|
p = buf;
|
|
for (i = 0; i < ctx->count; i++) {
|
|
ctx->syms[i] = p;
|
|
if (raw_syms[i]) {
|
|
strcpy(p, raw_syms[i]);
|
|
p += strlen(raw_syms[i]) + 1;
|
|
} else {
|
|
*p++ = '\0';
|
|
}
|
|
}
|
|
|
|
os_backtrace_symbols_free(raw_syms);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void backtrace_uninit(struct backtrace_ctx *ctx)
|
|
{
|
|
/* Nothing to free - caller owns the buffer */
|
|
}
|