[lldb-dev] Getting the address of a variable

Greg Clayton via lldb-dev lldb-dev at lists.llvm.org
Wed Jun 29 10:23:36 PDT 2016


> On Jun 29, 2016, at 9:51 AM, Bogdan Hopulele via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> 
> Hi all,
>  
> Given a file name, line number and variable name, I am trying to determine the address. I tried the following approach:
> ·         First I got the block corresponding to the file and line:
> o   from the file name I got a SBCompileUnit
> o   using the SBCompileUnit and line number I got a SBLineEntry
> §  for FindLineEntryIndex the “exact” parameter needs to be false else it will return empty if the line is on a function
> o   get the SBBlock: lineEntry.GetStartAddress().GetBlock()
> ·         Now I got the variables for that block and search by name

Any easier way might be to set a breakpoint by file and line. There may be more than one breakpoint location for a given file and line (inline functions for example). Once you have a breakpoint you can check the SBAddress of each location:

lldb::SBBreakpoint bp = target.BreakpointCreateByLocation("main.cpp", 12);
const size_t num_locs = bp.GetNumLocations();
for (size_t i=0; i<num_locs; ++i)
{
    lldb::SBBreakpointLocation bp_loc = bp.GetLocationAtIndex(i);
    lldb::SBSymbolContext sc = bp.GetSymbolContext(lldb::eSymbolContextEverything);
    // Now you have a symbol context that can give you all info
    lldb::SBFunction function = sc.GetFunction();
    lldb::SBBlock block = sc.GetBlock();
    lldb::SBLineEntry line_entry = sc.GetLineEntry();
}



> o   block.GetVariables(target, True, True, True)
> o   I still need to figure out if on the given line there is a function static and a function argument since both will show up in the list

You can ask each SBValue for its lldb::ValueType:

    lldb::ValueType
    lldb::SBValue::GetValueType ();


    enum ValueType
    {
        eValueTypeInvalid           = 0,
        eValueTypeVariableGlobal    = 1,    // globals variable
        eValueTypeVariableStatic    = 2,    // static variable
        eValueTypeVariableArgument  = 3,    // function argument variables
        eValueTypeVariableLocal     = 4,    // function local variables
        eValueTypeRegister          = 5,    // stack frame register value
        eValueTypeRegisterSet       = 6,    // A collection of stack frame register values
        eValueTypeConstResult       = 7     // constant result variables
    };

> o   Search for the variable by name and get its address – there is no address L

You can ask each value for its load address with:

    lldb::addr_t
    lldb::SBValue::GetLoadAddress();

You must be stopped in a stack frame in order for this to work with locals and arguments. Statics and globals will be able to answer the question _if_ the module that contains the static/global is loaded into memory in a process that is running. You can also set make a target and manually set the load locations of shared libraries (see http://lldb.llvm.org/symbolication.html) and then you will be able to get addresses for globals/statics.

> The problem is that for line 3 in the code below, my SBValue object in the list doesn’t have an address, just “<Invalid stack frame in context for DW_OP_fbreg opcode.>”. Any ideas how to solve this?

You can't evaluate expressions for local variables unless you are in the stack frame stopped at that address. Why? Variables say "I am located at the frame base pointer + 32". So unless you actually are stopped in a stack frame at that address, you won't be able to know what "frame base pointer" is. This is typically the RBP register on x86_64, EBP on x86, and FP register on ARM and ARM64.
>  
> Also, how can I set the context for evaluating an expression to a file and line number? (on line 8, evaluate “v” to 1)

Again, you really can't set the context because you actually need to be stopped there so that the CPU registers are all setup and correct. You can just set breakpoints and run to the needed locations and then evaluate the expressions when you know where you are stopped so that you know which expressions you will want to evaluate.

There are two ways to evaluate an expression: 
- use a lldb::SBTarget
- use a lldb::SBFrame

If you use the target, you can evaluate an expression for code like:

int g_global = 123;
int main()
{...}

lldb::SBValue global_expr = target.EvaluateExpression("g_global");

Since "g_global" has a value in the .data section, it can be evaluated without needing a frame and this expression will after you create your target and before you actually run it because it can read the value of g_global from the .data section in your executable. 

If you use a stack frame, then you are stopped somewhere and are asking the frame to help evaluate the values of any local and arguments values for the current function.

Does that make more sense?

> 1 void foo()
> 2 {
>       3     int v = 1;
>       4     {
>       5           int v = 2;
> -->   6           ++v;
>       7     }
>       8     v += 5;
> 9 }
>  
> Thanks,
> Bogdan
> National Instruments Romania S.R.L.
> ------------------------------------------------------
> B-dul 21 Decembrie 1989, nr. 77, A2
> Cluj-Napoca 400604, Romania
> C.I.F.: RO17961616 | O.R.C.: J12/3337/2005
> Telefon: +40 264 406428 | Fax: +40 264 406429
> E-mail: office.cluj at ni.com 
> Web: romania.ni.com 
> 
> Vanzari si suport tehnic:
> Telefon gratuit : 0800 070071
> E-mail vanzari: ni.romania at ni.com
> E-mail suport tehnic: techsupport at ni.com _______________________________________________
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev



More information about the lldb-dev mailing list