[lldb-dev] sharing code between lldb and AddressSanitizer

Greg Clayton gclayton at apple.com
Wed Nov 30 21:48:52 CST 2011


On Nov 30, 2011, at 5:42 PM, Kostya Serebryany wrote:

> 
> So if 0x402661 is an address that is already in terms of the virtual addresses in the a.out file itself, you can use example code from main.cpp mentioned below.
> 
> You could compile the main.cpp into "loopup" and run the result:
> 
> lookup /home/kcc/llvm/build/a.out 0x402661
> 
> And it should do the lookup you want.
> 
> Yes, this is what we already get from addr2line. 
> Can this be used inside the process? 

Yes.

> And can it translate real address to the offset in the library (currently, we use code from google perf tools to achieve that).

LLDB can't currently observer a process, it must debug it, but you can tell the target where each section of a shared library is loaded (a.out has ".text" is at 0x1000, a.out has ".data" at 0x2000). Then you can lookup using "Load" addresses.

You first need to create a target:

// Init LLDB
SBDebugger::Initialize();

// Create a debugger so we can make a target in it
SBDebugger debugger (SBDebugger::Create());

// Create a target and don't let it add all dependent shared libraries, we will add those manually
const bool add_dependent_files = false;
const char *triple = "i386-apple-darwin";
SBError error;
SBTarget target(debugger.CreateTarget ("/tmp/a.out", triple, NULL, add_dependent_files, error));

// Now add all of the shared libraries you want by repeating this loop
for (...)
{
	SBModule module = target.AddModule ("/tmp/libfoo.so", triple, NULL);
	target.SetSectionLoadAddress (module.FindSection ("__TEXT"), 0x1000);
	target.SetSectionLoadAddress (module.FindSection ("__DATA"), 0x2000);
}

Now you have a target that has all of the sections for all of your modules loaded at the addresses at which you want to do the lookups. To do a lookup you can now:

lldb::addr_t load_addr = ...; // The address to lookup

// Resolve a load address into a section + offset addresss within a module
SBAddress addr (target.ResolveLoadAddress (load_addr));
if (addr.IsValid())
{
    // Resolve the address into all of the symbol information
    SBSymbolContext symbol_ctx (addr.GetSymbolContext(eSymbolContextEverything));

    // symbol_ctx now contains the symbol context (module, compile unit, function, 
    // block, line table entry and symbol for the address). Now you should dump the
    // information that you want out of the symbol context....
    DumpSymbolContext (symbol_ctx, addr);

    // This might represent a an inline function within a concrete function, so you 
    // can also dump all of the parent functions above the current inline function.
    // An invalid symbol context will be returned when there are no more
    while (1)
    {
        SBAddress parent_addr; // The address in the parent function for the inline function
	SBSymbolContext parent_symbol_ctx = symbol_ctx.GetParentOfInlinedScope (addr, parent_addr);
        if (!parent_symbol_ctx.IsValid())
            break;
        DumpSymbolContext (parent_symbol_ctx, parent_addr);
        addr = parent_addr;
        symbol_ctx = parent_symbol_ctx;
    }
}


So we can do a very good job at symbolicating inlined functions within concrete functions, all from just a single address.

> Will this work on both linux and mac? 

Yep.


> 
> Thanks, 
> 
> --kcc 
> 
>  
> Let me know if you have any questions about how and what the example code in main.cpp is doing.
> 



More information about the lldb-dev mailing list