[lldb-dev] process calling lldb to symbolicate its own backtrace

Greg Clayton gclayton at apple.com
Tue Sep 24 10:10:10 PDT 2013


In order to symbolicate here are the steps:

1 - Create debugger
2 - Create target with the following call:

lldb::SBTarget
SBDebugger::CreateTarget (const char *filename,
                          const char *target_triple,
                          const char *platform_name,
                          bool add_dependent_modules,
                          lldb::SBError& sb_error)

You can specify NULL for platform if it is the local host platform, else specify a valid platform name ("remote-linux", "remote-macosx", etc).

Specify "false" for "add_dependent_modules. This will make a target that _only_ loads the files you add to it.

3 - Load an additional modules (shared libraries) you need to do your symbolication with:

lldb::SBModule
SBTarget::AddModule (const char *path,
                     const char *triple,
                     const char *uuid_cstr,
                     const char *symfile)

Lets say you have "/tmp/a.so" which doesn't contain debug symbols, but "/tmp/debug/a.so" does and is a separate stand alone debug info file, you would specify "/tmp/a.so" for "path" and "/tmp/debug/a.so" for "symfile". Specify NULL for "uuid_cstr" unless you have a crash log that has the UUID information for each module in it. Use the same "triple" as you did for the target create.

4 - Specify the load locations for the sections you care about for each module

First find the module:

SBFileSpec module_path("/tmp/a.so");
SBModule module = target.FindModule(module_path);
if (module.IsValid())
{

Now you need to decide if you want to rigidly slide your executables, or set the load address of sections individually. If you know the slide of your library and all sections should be slid by a fixed amount, figure out the slide and slide it:

    int64_t slide = ...
    target.SetModuleLoadAddress (module, slide);

Or, you can lookup the sections and set the load addresses individually:

    lldb::addr_t text_load_address = ...;
    SBSection section = module.FindSection(".text")
    target.SetSectionLoadAddress(section, text_load_address);

When setting the load address of sections, you don't need to compute a slide, you just need to set the actual address itself for the base of the section.

Repeat this for all modules so they all have load locations and now you are ready to do lookups:

    lldb::addr_t lookup_addr = ...;

    lldb::SBAddress addr = target.ResolveLoadAddress (lookup_addr);
    if (addr.GetSection())
    {
        // If we have a valid section, then we can symbolicate
        SBSymbolContext sc = target.ResolveSymbolContextForAddress (addr, lldb::eSymbolContextEverything);

Now you have a symbol context "sc" which has everything filled in. The symbol context has accessors for everything you need:

    lldb::SBModule        GetModule ();
    lldb::SBCompileUnit   GetCompileUnit ();
    lldb::SBFunction      GetFunction ();
    lldb::SBBlock         GetBlock ();
    lldb::SBLineEntry     GetLineEntry ();
    lldb::SBSymbol        GetSymbol ();

Each of these objects could be valid, or could be invalid. Test each one with "IsValid()":

    if (GetFunction().IsValid())
    {
    }
    else if (GetSymbol().IsValid())
    {
    }


Now you have the deepest most scope for the address you have looked up. You might want to figure out if there are any inlined functions. For this you can use:

    SBSymbolContext
    SBSymbolContext::GetParentOfInlinedScope (const SBAddress &curr_frame_pc, 
                                              SBAddress &parent_frame_addr) const;


For example, we already have "addr" from above which is a SBAddress:

    SBAddress curr_addr(addr);

    while (1)
    {
        SBAddress parent_addr;
        SBSymbolContext parent_sc = sc.GetParentOfInlinedScope(curr_addr, parent_addr);
        if (!parent_sc.IsValid())
            break;
        // Print out frame info in "parent_addr" and "parent_sc"

     
    } 

There are more basics on our website:

http://lldb.llvm.org/symbolication.html


On Sep 24, 2013, at 12:32 AM, Timothee Cour <timothee.cour2 at gmail.com> wrote:

> I'm trying to get complete stacktraces from C/C++ (backtrace/backtrace_symbols has issues, eg line numbers are often wrong and file name omits full path), and want to use lldb for that.
> 
> from the main process A (with pidA), I tried calling lldb in a separate process that attaches to pidA and then prints the backtrace; that works but is slow. 
> 
> So I'd like A to directly call lldb (via the C++ api) without having to launch a separate process, but can't make it work so far:
> 
> SBDebugger.Create (works)
> CreateTargetWithFileAndArch (works)
> 
> * FindFunctions (works but then GetContextAtIndex(0).GetLineEntry is invalid)
> * I also tried using ResolveFileAddress but that didn't work; not sure if it's because I need to set the load address somehow.
> 
> Note that all the above work when calling a separate process.
> 
> Is there some example code snippet for doing that?
> 
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev




More information about the lldb-dev mailing list