> 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