backward-cpp icon indicating copy to clipboard operation
backward-cpp copied to clipboard

Any hints as to what's needed for a PR to work on OSX

Open heapwolf opened this issue 8 years ago • 7 comments

Tinkering around and would like to get stack traces on osx. binutils is in homebrew and I found argp-standalone in homebrew (required by elfutils), then I got elfutils to not complain about GNU99 support, guessing that this is an issue in elfutils?

heapwolf avatar Sep 13 '15 15:09 heapwolf

you need two things to get the traces:

  1. first a way to "walk the stack", which should be provided by gcc/clang under the unwind api. If that works, you should at least get the bare stacktrace. ie: a list of addresses.
  2. then you need a way to map the addresses to the debug info of your executable. This is where elfutils/bfd are coming into play on linux. I have no idea if this works the same on macosx.

bombela avatar Sep 15 '15 20:09 bombela

So i was able to do something like this to get backtraces on sigs...

void* callstack[128];
size_t size = backtrace(callstack, 128);
char** symbols = backtrace_symbols(callstack, size);

Then loop over the symbols, converting the symbols (after a little regexing) like leveraging abi...

char* name = abi::__cxa_demangle(s.c_str(), NULL, NULL, &status);

The problem is, the general solution (as i have found so far) for mapping addresses to files is a linux specific tool (addr2line) which depends on a bunch of crazy things to parse drawf. However, i recently found this which seems to be able to parse DWv4 files. So maybe it's possible to bypass elfutils using this (which seems to be able to map the line numbers). Im definitely going down a rabbit hole, considering how awesome lldb::gui is and how much more powerful core dumps are, but this is really fun :)

heapwolf avatar Sep 15 '15 20:09 heapwolf

~~does libbfd is available on macox? because its more accurate than libelfutils anyway.~~

Does libdw is available on macosx? because its more accurate than libbfd from the binutils anyway.

bombela avatar Sep 15 '15 20:09 bombela

Also, just to clear things up: libunwind != unwind API. backward uses the unwind API from gcc/clang. libunwind is an advanced library for walking the stack (with way more features than backward).

bombela avatar Sep 16 '15 06:09 bombela

I'm fairly certain that none of the dwarf-parsing libraries will work on OS X because they all assume ELF-executable format and OS X uses Mach-O instead.

I've been able to get a backtrace_symbols-based version of this working and will submit a PR for it shortly. It's not nearly as pretty as the Linux versions can be, but it's more useful than the default output.

Sample:

$ ./test_stacktrace 
-- running test case: minitrace
Stack trace (most recent call last) in thread 6837446:
#6    Object "???", at 0x1, in 0x0 + 1
#5    Object "libdyld.dylib", at 0x7fff98da7235, in start + 1
#4    Object "libtest_main.dylib", at 0x10b5e8912, in main + 578
#3    Object "libtest_main.dylib", at 0x10b5e8375, in run_test(test::TestBase&) + 85
#2    Object "libtest_main.dylib", at 0x10b5e8555, in test::TestBase::run() + 21
#1    Object "test_stacktrace", at 0x10b5b4d1b, in TEST_minitrace::do_test() + 43
#0    Object "test_stacktrace", at 0x10b5b4bac, in collect_trace(backward::StackTrace&) + 28
-- test case success: minitrace
-- running test case: smalltrace
Stack trace (most recent call last) in thread 6837447:
#9    Object "???", at 0x1, in 0x0 + 1
#8    Object "libdyld.dylib", at 0x7fff98da7235, in start + 1
#7    Object "libtest_main.dylib", at 0x10b5e8912, in main + 578
#6    Object "libtest_main.dylib", at 0x10b5e8375, in run_test(test::TestBase&) + 85
#5    Object "libtest_main.dylib", at 0x10b5e8555, in test::TestBase::run() + 21
#4    Object "test_stacktrace", at 0x10b5b511b, in TEST_smalltrace::do_test() + 43
#3    Object "test_stacktrace", at 0x10b5b50c5, in a(backward::StackTrace&) + 21
#2    Object "test_stacktrace", at 0x10b5b50a5, in b(backward::StackTrace&) + 21
#1    Object "test_stacktrace", at 0x10b5b5085, in c(backward::StackTrace&) + 21
#0    Object "test_stacktrace", at 0x10b5b505c, in d(backward::StackTrace&) + 28
-- test case success: smalltrace
-- tests passing: 2/2 (100%)

zuercher avatar Aug 25 '17 01:08 zuercher

Nice work. I saw your PR. And is the copy paste is mostly renaming. We can probably add some macro to represent the common parts. I don't have much time right now. But I am definitely keeping an eye on your work.

bombela avatar Sep 01 '17 06:09 bombela

For the mac, when I enable BACKWARD_HAS_BACKTRACE_SYMBOL=1, the stack traces disappear entirely, even though I am linking in libbacktrace (-lbacktrace, libraries present, libbacktrace.dylib, libbacktrace.0.dylib). I'm hoping to see the ultimate output like I do on linux for this amazing library. Any ideas?

cruisercoder avatar Feb 03 '19 22:02 cruisercoder