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