> On Jun 29, 2016, at 9:51 AM, Bogdan Hopulele via lldb-dev 
> <lldb-dev@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.c...@ni.com 
> Web: romania.ni.com 
> 
> Vanzari si suport tehnic:
> Telefon gratuit : 0800 070071
> E-mail vanzari: ni.roma...@ni.com
> E-mail suport tehnic: techsupp...@ni.com 
> _______________________________________________
> lldb-dev mailing list
> lldb-dev@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

_______________________________________________
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

Reply via email to