1*be691f3bSpatrick#!/usr/bin/env python 2061da546Spatrick 3061da546Spatrickimport lldb 4061da546Spatrickimport shlex 5061da546Spatrick 6061da546Spatrick 7061da546Spatrick@lldb.command("shadow") 8061da546Spatrickdef check_shadow_command(debugger, command, exe_ctx, result, dict): 9061da546Spatrick '''Check the currently selected stack frame for shadowed variables''' 10061da546Spatrick process = exe_ctx.GetProcess() 11061da546Spatrick state = process.GetState() 12061da546Spatrick if state != lldb.eStateStopped: 13061da546Spatrick print("process must be stopped, state is %s" % lldb.SBDebugger.StateAsCString( 14061da546Spatrick state), file=result) 15061da546Spatrick return 16061da546Spatrick frame = exe_ctx.GetFrame() 17061da546Spatrick if not frame: 18061da546Spatrick print("invalid frame", file=result) 19061da546Spatrick return 20061da546Spatrick # Parse command line args 21061da546Spatrick command_args = shlex.split(command) 22061da546Spatrick # TODO: add support for using arguments that are passed to this command... 23061da546Spatrick 24061da546Spatrick # Make a dictionary of variable name to "SBBlock and SBValue" 25061da546Spatrick shadow_dict = {} 26061da546Spatrick 27061da546Spatrick num_shadowed_variables = 0 28061da546Spatrick # Get the deepest most block from the current frame 29061da546Spatrick block = frame.GetBlock() 30061da546Spatrick # Iterate through the block and all of its parents 31061da546Spatrick while block.IsValid(): 32061da546Spatrick # Get block variables from the current block only 33061da546Spatrick block_vars = block.GetVariables(frame, True, True, True, 0) 34061da546Spatrick # Iterate through all variables in the current block 35061da546Spatrick for block_var in block_vars: 36061da546Spatrick # Since we can have multiple shadowed variables, we our variable 37061da546Spatrick # name dictionary to have an array or "block + variable" pairs so 38061da546Spatrick # We can correctly print out all shadowed variables and whow which 39061da546Spatrick # blocks they come from 40061da546Spatrick block_var_name = block_var.GetName() 41061da546Spatrick if block_var_name in shadow_dict: 42061da546Spatrick shadow_dict[block_var_name].append(block_var) 43061da546Spatrick else: 44061da546Spatrick shadow_dict[block_var_name] = [block_var] 45061da546Spatrick # Get the parent block and continue 46061da546Spatrick block = block.GetParent() 47061da546Spatrick 48061da546Spatrick num_shadowed_variables = 0 49061da546Spatrick if shadow_dict: 50061da546Spatrick for name in shadow_dict.keys(): 51061da546Spatrick shadow_vars = shadow_dict[name] 52061da546Spatrick if len(shadow_vars) > 1: 53061da546Spatrick print('"%s" is shadowed by the following declarations:' % (name)) 54061da546Spatrick num_shadowed_variables += 1 55061da546Spatrick for shadow_var in shadow_vars: 56061da546Spatrick print(str(shadow_var.GetDeclaration()), file=result) 57061da546Spatrick if num_shadowed_variables == 0: 58061da546Spatrick print('no variables are shadowed', file=result) 59