ianlancetaylor / libbacktrace

A C library that may be linked into a C/C++ program to produce symbolic backtraces

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

how to get stack addresses in libbacktrace API or get symbolicated backtrace from stack addresses

timotheecour opened this issue · comments

The libbacktrace library doesn't return stack addresses. I suppose I could add a new function for that, but it's not clear how useful it would be. You might want to look into using libunwind instead, or using _Unwind_Backtrace with _Unwind_GetCFA.

You might want to look into using libunwind instead, or using _Unwind_Backtrace with _Unwind_GetCFA.

Well I don't want to lose the other functionality of libbacktrace; seems like getting addresses is a reasonable thing to do since it's also exposed by other tools (eg backtrace or those).

Actually I have a related question: is there a way to get symbolication using libbacktrace given input stack addresses?
Use case: deferred symbolication, so I can get an array of stack addresses (eg via backtrace) and then at a subsequent time, symbolicate them using some libbacktrace API?
If so then this feature wouldn't be needed as I would have the 1 to 1 mapping between input stack addresses and what libbacktrace returns for each address as output.

I don't know what it mean to symbolize a stack address. I guess you mean something like "do a stack backtrace until you find the stack frame with that address, and report associated file/line/function information." I don't think that is a feature suitable for libbacktrace. I think that very very few people would use it.

I don't know what it mean to symbolize a stack address

I think symbolize is a standard term for what I'm describing (eg see https://stackoverflow.com/questions/52695965/how-to-symbolize-stack-traces-of-a-stripped-shared-library)

I guess you mean something like [...]
I think that very very few people would use it.

That's not what I mean. The standard way to symbolize is in 2 steps:

Doing it in 2 steps is a requirement for implementing exception handling efficiently (among other applications), this allows to symbolize stack addresses only when needed, eg:

try:
  fun() # may throw
except Exception as e:
  if isDebug: printStackTrace(e)
  # maybe re-raise, or handle

in this code we don't want to automatically symbolicate when exception is thrown, because that's expensive and subsequent code may not need it (in this snippet, depending on isDebug)

So what I mean is: I'd like to use libbacktrace in a deferred mode, replacing backtrace_symbols above (which has accuracy issues, besides lack of C++ demangling) with some libbacktrace API. This would be needed to implement efficient handling in nim, see status-im/nim-libbacktrace#4

I think that very very few people would use it.

here are use cases for the feature of deferred symbolication:

  • exception handling (symbolication in same process at a later time)
  • out-of-process symbolication (exactly this: https://stackoverflow.com/questions/52695965/how-to-symbolize-stack-traces-of-a-stripped-shared-library; allows for eg shipping stripped binaries to customers, and doing symbolication in a remote server given input stack addresses from customer logs); or for efficiency purposes instead of obfuscation purposes, when running stripped binaries on a server
  • profiling, where we generate stack addresses at sample time intervals, then gather/deduplicate/symbolicate them at the end to produce a human readable profiling report

Maybe we are using different meanings for these terms. As I use the term "stack address", the backtrace function does not return a stack address. The backtrace function returns a list of program counter values. These are the same values that libbacktrace returns as the pc argument passed to the callback routine, either by backtrace_full or backtrace_simple. So maybe you are looking for backtrace_simple followed by a later call to backtrace_pcinfo.

@timotheecour, I can confirm that it's possible to do what you want by first collecting program counter addresses with backtrace_simple() and, in a separate step, get debugging info for each of those using backtrace_pcinfo().

A small complication is that you may get more than one debugging info set for a given program counter, due to inlined functions and debugging formats like DWARF that have that info, but that's a good thing because it makes your backtrace more useful.

I implemented this two-step scheme here: status-im/nim-libbacktrace@3ff163c

Thanks, I'm still not completely sure what this issue is about, but it sounds like there is a way to do it. So closing this issue. Please comment if you disagree.