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