Bug 243746 - llvm-libunwind does not provide an API useful in signal handler context
Summary: llvm-libunwind does not provide an API useful in signal handler context
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-toolchain mailing list
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2020-01-30 22:25 UTC by Matthias Andree
Modified: 2020-02-12 22:56 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Andree freebsd_committer 2020-01-30 22:25:26 UTC
*** Description
Trying to debug e2fsprogs, which uses backtrace(), I did not see stack backtraces for a crasher.

I have then adapted a test program found on the net, which also does not find stack backtraces - running the same executable under gdb until it receives a provoked SIGSEGV yields a proper backtrace.

*** Received output:
Signal 11 in dump_trace - have 0 frames

*** Expected output SIMILAR TO (this is taken from the same program under Linux - only adapted to use int, not size_t, and omitting -lexecinfo because backtrace is part of GNU libc):
Signal in dump_trace - have 8 frames
./try-bt[0x401185]
/lib64/libc.so.6(+0x3c6b0)[0x7f951de3a6b0]
./try-bt(boom+0x10)[0x4011e0]
./try-bt(two+0xe)[0x4011f4]
./try-bt(one+0xe)[0x401205]
./try-bt(main+0x1d)[0x401225]
/lib64/libc.so.6(__libc_start_main+0xf3)[0x7f951de251a3]
./try-bt(_start+0x2e)[0x4010ae]



*** Program:

/* save as try-bt.c then compile with:
cc -rdynamic -fno-omit-frame-pointer -g -std=c99 -o try-bt try-bt.c -fno-inline -lexecinfo -lelf */
#include <execinfo.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>

static void dump_trace(int sig) {
	size_t max_frames = 32;
	void *buffer[max_frames];
	size_t calls = backtrace(buffer, max_frames);
	fprintf(stderr, "Signal %d in dump_trace - have %zu frames\n", sig, calls);
	backtrace_symbols_fd(buffer, calls, 2);
	_Exit(EXIT_FAILURE);
}

void boom() {
	volatile char *a = 0;
	*a = 17;
}

void two() {boom(); }
void one() {two(); }

int main(void) {
	signal(SIGSEGV, dump_trace);
	one();
	exit(EXIT_SUCCESS);
}
/* END */
Comment 1 Conrad Meyer freebsd_committer 2020-01-31 00:31:55 UTC
Yeah, our libunwind doesn't know how to backtrace out of a signal handler at this time.  I have a WIP patch to unwind starting from a `ucontext`, which signal handlers created with sigaction(2) can access, but I haven't had time to work on it for a while; it would also require slightly different code in the signal handler.
Comment 2 Conrad Meyer freebsd_committer 2020-01-31 00:37:38 UTC
Here is the WIP: https://people.freebsd.org/~cem/libexecinfo.backtrace_ctx3.patch

It works on amd64 (not tested recently) and maybe i386 (untested) and does not have support for other architectures.  It is mostly missing tests, I think. Otherwise it just needs rebasing on the current tree, and eventually it will be nice to support non-x86 architectures.