mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 17:28:30 +00:00
Improve crash backtrace reliability
We're now able to pretty print a C++ backtrace upon crashing in pretty much any runtime execution scenario. The default pledge sandbox policy on Linux is now to return EPERM. If you call pledge and have debugging functions linked (e.g. GetSymbolTable) then the symbol table shall get loaded before any security policy is put in place. This change updates build/bootstrap/fixupobj too and fixes some other sneaky build errors.
This commit is contained in:
parent
7d31fc311a
commit
19c81863a3
17 changed files with 103 additions and 64 deletions
|
@ -37,9 +37,14 @@ static struct {
|
|||
} g_addr2line;
|
||||
|
||||
void GetAddr2linePathInit(void) {
|
||||
char *res;
|
||||
int e = errno;
|
||||
const char *path;
|
||||
if (!(path = getenv("ADDR2LINE"))) {
|
||||
const char *env, *cmd, *path;
|
||||
if ((env = getenv("ADDR2LINE"))) {
|
||||
cmd = env;
|
||||
path = env;
|
||||
} else {
|
||||
cmd = "addr2line";
|
||||
path = ADDR2LINE;
|
||||
}
|
||||
char *buf = g_addr2line.buf;
|
||||
|
@ -48,12 +53,11 @@ void GetAddr2linePathInit(void) {
|
|||
strlcat(buf, "/", PATH_MAX);
|
||||
}
|
||||
strlcat(buf, path, PATH_MAX);
|
||||
}
|
||||
if (*buf) {
|
||||
g_addr2line.res = buf;
|
||||
res = buf;
|
||||
} else {
|
||||
g_addr2line.res = commandv("addr2line", buf, PATH_MAX);
|
||||
res = commandv(cmd, buf, PATH_MAX);
|
||||
}
|
||||
g_addr2line.res = res;
|
||||
errno = e;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
|
|||
}
|
||||
|
||||
if (!PLEDGED(STDIO) || !PLEDGED(EXEC) || !PLEDGED(EXEC)) {
|
||||
ShowHint("won't print addr2line backtrace because pledge");
|
||||
ShowHint("pledge() sandboxing makes backtraces not as good");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/cosmo.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
|
@ -29,6 +30,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
#define LIMIT 100
|
||||
|
@ -47,8 +49,11 @@ dontinstrument dontasan int PrintBacktraceUsingSymbols(
|
|||
int fd, const struct StackFrame *bp, struct SymbolTable *st) {
|
||||
size_t gi;
|
||||
intptr_t addr;
|
||||
const char *name;
|
||||
int i, symbol, addend;
|
||||
static char cxxbuf[8192];
|
||||
struct Garbages *garbage;
|
||||
static pthread_spinlock_t lock;
|
||||
const struct StackFrame *frame;
|
||||
(void)gi;
|
||||
if (!bp)
|
||||
|
@ -83,8 +88,15 @@ dontinstrument dontasan int PrintBacktraceUsingSymbols(
|
|||
symbol = 0;
|
||||
addend = 0;
|
||||
}
|
||||
kprintf("%012lx %lx %s%+d\n", frame, addr, __get_symbol_name(st, symbol),
|
||||
addend);
|
||||
if ((name = __get_symbol_name(st, symbol)) && __is_mangled(name)) {
|
||||
pthread_spin_lock(&lock);
|
||||
__demangle(cxxbuf, name, sizeof(cxxbuf));
|
||||
kprintf("%012lx %lx %s%+d\n", frame, addr, cxxbuf, addend);
|
||||
pthread_spin_unlock(&lock);
|
||||
name = cxxbuf;
|
||||
} else {
|
||||
kprintf("%012lx %lx %s%+d\n", frame, addr, name, addend);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "libc/calls/struct/utsname.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/cosmo.h"
|
||||
#include "libc/cxxabi.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
|
@ -40,7 +41,6 @@
|
|||
#include "libc/log/internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/stackframe.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
@ -178,15 +178,15 @@ static relegated bool AppendFileLine(struct Buffer *b, const char *addr2line,
|
|||
}
|
||||
}
|
||||
|
||||
static relegated char *GetSymbolName(struct SymbolTable *st, int symbol,
|
||||
char **mem, size_t *memsz) {
|
||||
char *s, *t;
|
||||
if ((s = __get_symbol_name(st, symbol)) && //
|
||||
s[0] == '_' && s[1] == 'Z' && //
|
||||
(t = __cxa_demangle(s, *mem, memsz, 0))) {
|
||||
*mem = s = t;
|
||||
}
|
||||
return s;
|
||||
static relegated char *GetSymbolName(struct SymbolTable *st, int symbol) {
|
||||
char *str;
|
||||
static char buf[8192];
|
||||
if (!(str = __get_symbol_name(st, symbol)))
|
||||
return str;
|
||||
if (!__is_mangled(str))
|
||||
return str;
|
||||
__demangle(buf, str, sizeof(buf));
|
||||
return buf;
|
||||
}
|
||||
|
||||
static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
||||
|
@ -241,8 +241,6 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
|||
: (struct StackFrame *)__builtin_frame_address(0)));
|
||||
if (ctx) {
|
||||
long pc;
|
||||
char *mem = 0;
|
||||
size_t memsz = 0;
|
||||
int addend, symbol;
|
||||
const char *debugbin;
|
||||
const char *addr2line;
|
||||
|
@ -305,7 +303,7 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
|||
addend -= st->symbols[symbol].x;
|
||||
Append(b, " ");
|
||||
if (!AppendFileLine(b, addr2line, debugbin, pc)) {
|
||||
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
|
||||
Append(b, "%s", GetSymbolName(st, symbol));
|
||||
if (addend)
|
||||
Append(b, "%+d", addend);
|
||||
}
|
||||
|
@ -327,7 +325,7 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
|||
addend -= st->symbols[symbol].x;
|
||||
Append(b, " ");
|
||||
if (!AppendFileLine(b, addr2line, debugbin, pc)) {
|
||||
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
|
||||
Append(b, "%s", GetSymbolName(st, symbol));
|
||||
if (addend)
|
||||
Append(b, "%+d", addend);
|
||||
}
|
||||
|
@ -367,13 +365,12 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
|||
}
|
||||
Append(b, " %016lx fp %lx lr ", fp, pc);
|
||||
if (!AppendFileLine(b, addr2line, debugbin, pc) && st) {
|
||||
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
|
||||
Append(b, "%s", GetSymbolName(st, symbol));
|
||||
if (addend)
|
||||
Append(b, "%+d", addend);
|
||||
}
|
||||
Append(b, "\n");
|
||||
}
|
||||
free(mem);
|
||||
}
|
||||
b->p[b->n - 1] = '\n';
|
||||
klog(b->p, MIN(b->i, b->n));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue