Runtime introspection of "Release Mode" programs using LLVM or LLDB

Hi everyone,

I’m working on a library for runtime introspection of C++ programs, for example, getting stack traces, decorating logs with source file information, etc. It currently uses LLVMObject and LLVMDebugInfo.

There’s a feature I want to add, but it requires that I understand where on the stack local variables are located.

For this to work on x86-64, I would need to do whole “virtual unwinding” thing, i.e., create a library that can understand the DWARF call frame information. This is something that I do not want to do myself, because I would never have the resources to maintain it. LLVM and or LLDB must have code for doing this already though.

In fact, since this sort of dynamic inspection is kind of like debugging, I originally thought LLDB would work better in the first place. I actually tried early on to use LLDB, but I gave up quickly. The API seems to be designed so that you must always attach one process to another, using an operating system facility like ptrace.

That is not really compatible with the idea of the program inspecting itself, although I think there is definitely a place for that, e.g. portable stack traces, source info without the need for FILE and LINE boilerplate, etc.

Does LLDB support anything like this, and I just didn’t find it? Or going another route, is there any plan for the DWARF classes in LLVMDebugInfo to ever support APIs for understanding the call frame info?

If neither, any advice on what I should do?

Thanks!
Ken

Hi everyone,

I'm working on a library for runtime introspection of C++ programs, for
example, getting stack traces, decorating logs with source file
information, etc. It currently uses LLVMObject and LLVMDebugInfo.

There's a feature I want to add, but it requires that I understand where on
the stack local variables are located.

For this to work on x86-64, I would need to do whole "virtual unwinding"
thing, i.e., create a library that can understand the DWARF call frame
information. This is something that I do not want to do myself, because I
would never have the resources to maintain it. LLVM and or LLDB must have
code for doing this already though.

You can probably find what you need in libunwind/libcxxabi. See: http://mentorembedded.github.io/cxx-abi/abi-eh.html

Cheers,

Jon

Hi everyone,

I'm working on a library for runtime introspection of C++ programs, for
example, getting stack traces, decorating logs with source file
information, etc. It currently uses LLVMObject and LLVMDebugInfo.

There's a feature I want to add, but it requires that I understand where on
the stack local variables are located.

For this to work on x86-64, I would need to do whole "virtual unwinding"
thing, i.e., create a library that can understand the DWARF call frame
information. This is something that I do not want to do myself, because I
would never have the resources to maintain it. LLVM and or LLDB must have
code for doing this already though.

You can probably find what you need in libunwind/libcxxabi. See: http://mentorembedded.github.io/cxx-abi/abi-eh.html

Cheers,

Jon

In fact, since this sort of dynamic inspection is kind of like debugging, I
originally thought LLDB would work better in the first place. I actually
tried early on to use LLDB, but I gave up quickly. The API seems to be
designed so that you must always attach one process to another, using an
operating system facility like ptrace.

Yes, the LLDB API is currently very debug centric and we haven't spent any time trying to allow simple process inspection.

That is not really compatible with the idea of the program inspecting
_itself_, although I think there is definitely a place for that, e.g.
portable stack traces, source info without the need for __FILE__ and
__LINE__ boilerplate, etc.

Once inspection is in LLDB, it should be able to inspect itself as well as any other process.

Does LLDB support anything like this, and I just didn't find it?

LLDB is a debugger first and foremost and there has be zero time invested in trying to make it inspect processes.

Or going
another route, is there any plan for the DWARF classes in LLVMDebugInfo to
ever support APIs for understanding the call frame info?

If neither, any advice on what I should do?

So important questions is: do you only want to read DWARF unwind info?

If the answer is yes, you can modify the DWARF classes in LLVMDebugInfo. But one thing that LLDB API does do is it abstracts you from the debug info and runtime info. One example is the compact unwind info in MacOSX and iOS binaries. It replaces 99% of the EH frame info from the .eh_frame section, or .debug_frame which for most compilers is just an exact copy of the .eh_frame.

Exposing the unwind info isn't currently done, but wouldn't be hard to do as we internally have that information, it just isn't exposed via the public API.

So a few things to stress:
1 - I would love to have a process view mode in LLDB where we don't attach for debugging
2 - We can and should expose unwind info in an agnostic way that doesn't limit itself to just one format

If you end up thinking of working on LLDB, let me know and we can help guide your work and monitor your progress, we all will be happy to help.

Greg