You can currently do this by checking for other variables to see if any names match.
In python when stopped in the function below you can do use the API: (lldb) script Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D. >>> frame_vars = lldb.frame.GetVariables(True, True, True, True) >>> print frame_vars (int) v = 1 (int) v = 2 frame_vars is a list of all variables in the current stack frame. They are ordered correctly so you see your first "v" first and the second one next. Lets grab the exact lexical block from the current frame: >>> block = lldb.frame.GetBlock() This is the block from line 4 - 7 in your source code. >>> print block.GetVariables(lldb.frame, True, True, True, 0) (int) v = 2 Note that if we ask the block for its variables, it will only have the variables contained in that block. Now you can ask "block" for its parent block: >>> print block.GetParent().GetVariables(lldb.frame, True, True, True, 0) (int) v = 1 So with all of this you could create a new python command: #!/usr/bin/python import lldb import shlex @lldb.command("check-shadow") def check_shadow_command(debugger, command, result, dict): target = debugger.GetSelectedTarget() if not target: print >>result, "invalid target" return process = target.GetProcess() if not process: print >>result, "invalid process" return thread = process.GetSelectedThread() if not thread: print >>result, "invalid thread" return frame = thread.GetSelectedFrame() if not frame: print >>result, "invalid frame" return # Parse command line args command_args = shlex.split(command) # TODO: add support for using arguments that are passed to this command... # Make a dictionary of variable name to "SBBlock and SBValue" var_dict = {} # Get the deepest most block from the current frame block = frame.GetBlock() # Iterate through the block and all of its parents while block.IsValid(): # Get block variables from the current block only block_vars = block.GetVariables(frame, True, True, True, 0) # Iterate through all variables in the current block for block_var in block_vars: # Get the variable name and see if we already have a variable by this name? block_var_name = block_var.GetName() if block_var_name in var_dict: # We already have seen a variable with this name, so it is shadowed print block, block_var print 'is shadowed by:' shadow_block_and_vars = var_dict[block_var_name] for shadow_block_and_var in shadow_block_and_vars: print shadow_block_and_var[0], shadow_block_and_var[1] # Since we can have multiple shadowed variables, we our variable # name dictionary to have an array or "block + variable" pairs so # We can correctly print out all shadowed variables and whow which # blocks they come from if block_var_name in var_dict: var_dict[block_var_name].append([block, block_var]) else: var_dict[block_var_name] = [[block, block_var]] # Get the parent block and continue block = block.GetParent() I have attached this as a script that you can import:
#!/usr/bin/python import lldb import shlex @lldb.command("check-shadow") def check_shadow_command(debugger, command, result, dict): target = debugger.GetSelectedTarget() if not target: print >>result, "invalid target" return process = target.GetProcess() if not process: print >>result, "invalid process" return thread = process.GetSelectedThread() if not thread: print >>result, "invalid thread" return frame = thread.GetSelectedFrame() if not frame: print >>result, "invalid frame" return # Parse command line args command_args = shlex.split(command) # TODO: add support for using arguments that are passed to this command... # Make a dictionary of variable name to "SBBlock and SBValue" var_dict = {} # Get the deepest most block from the current frame block = frame.GetBlock() # Iterate through the block and all of its parents while block.IsValid(): # Get block variables from the current block only block_vars = block.GetVariables(frame, True, True, True, 0) # Iterate through all variables in the current block for block_var in block_vars: # Get the variable name and see if we already have a variable by this name? block_var_name = block_var.GetName() if block_var_name in var_dict: # We already have seen a variable with this name, so it is shadowed print block, block_var print 'is shadowed by:' shadow_block_and_vars = var_dict[block_var_name] for shadow_block_and_var in shadow_block_and_vars: print shadow_block_and_var[0], shadow_block_and_var[1] # Since we can have multiple shadowed variables, we our variable # name dictionary to have an array or "block + variable" pairs so # We can correctly print out all shadowed variables and whow which # blocks they come from if block_var_name in var_dict: var_dict[block_var_name].append([block, block_var]) else: var_dict[block_var_name] = [[block, block_var]] # Get the parent block and continue block = block.GetParent()
Then you can run this: % lldb a.out (lldb) command script import /tmp/lldbshadow.py (lldb) target create "a.out" (lldb) b main.cpp:6 (lldb) run Process 423 stopped * thread #1: tid = 0x46a88f, 0x0000000100000f82 a.out foo() + 18, stop reason = breakpoint 1.1, queue = com.apple.main-thread frame #0: 0x0000000100000f82 a.out foo() + 18 at main.cpp:6 3 int v = 1; 4 { 5 int v = 2; -> 6 ++v; 7 } 8 } 9 (lldb) check-shadow Block: {id: 46} [0x100000f70-0x100000f8d) (int) v = 1 is shadowed by: Block: {id: 94} [0x100000f7b-0x100000f8b) (int) v = 2 So yes it is possible, and I have attached an example. Adding a function to SBValue might not make sense because SBValue objects are used to represent registers and many other things other than local variables, and there is no language agnostic rule we could use to implement this correctly at the generic API level. Greg Clayton > On Jun 22, 2016, at 9:43 AM, Bogdan Hopulele via lldb-dev > <lldb-dev@lists.llvm.org> wrote: > > Hi all, > > I’m using lldb 3.9 through the C++ API and I’m trying to determine if a local > variable is shadowed or not with no luck. > For the code below: > > 1. Is there an API call, that I somehow missed, that can tell me that > (v = 2) shadows (v = 1)? > 2. Can I rely on their order in the SBValueList object? > 3. Would you guys think it would be worth adding bool > SBValue::IsShadowed() const ? > > > 1 void foo() > 2 { > 3 int v = 1; > 4 { > 5 int v = 2; > --> 6 ++v; > 7 } > 8 } > > Thank, > 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