207
|
1 #!/usr/bin/env python
|
150
|
2 from __future__ import print_function
|
|
3
|
|
4 import lldb
|
|
5 import shlex
|
|
6
|
|
7
|
|
8 @lldb.command("shadow")
|
|
9 def check_shadow_command(debugger, command, exe_ctx, result, dict):
|
|
10 '''Check the currently selected stack frame for shadowed variables'''
|
|
11 process = exe_ctx.GetProcess()
|
|
12 state = process.GetState()
|
|
13 if state != lldb.eStateStopped:
|
|
14 print("process must be stopped, state is %s" % lldb.SBDebugger.StateAsCString(
|
|
15 state), file=result)
|
|
16 return
|
|
17 frame = exe_ctx.GetFrame()
|
|
18 if not frame:
|
|
19 print("invalid frame", file=result)
|
|
20 return
|
|
21 # Parse command line args
|
|
22 command_args = shlex.split(command)
|
|
23 # TODO: add support for using arguments that are passed to this command...
|
|
24
|
|
25 # Make a dictionary of variable name to "SBBlock and SBValue"
|
|
26 shadow_dict = {}
|
|
27
|
|
28 num_shadowed_variables = 0
|
|
29 # Get the deepest most block from the current frame
|
|
30 block = frame.GetBlock()
|
|
31 # Iterate through the block and all of its parents
|
|
32 while block.IsValid():
|
|
33 # Get block variables from the current block only
|
|
34 block_vars = block.GetVariables(frame, True, True, True, 0)
|
|
35 # Iterate through all variables in the current block
|
|
36 for block_var in block_vars:
|
|
37 # Since we can have multiple shadowed variables, we our variable
|
|
38 # name dictionary to have an array or "block + variable" pairs so
|
|
39 # We can correctly print out all shadowed variables and whow which
|
|
40 # blocks they come from
|
|
41 block_var_name = block_var.GetName()
|
|
42 if block_var_name in shadow_dict:
|
|
43 shadow_dict[block_var_name].append(block_var)
|
|
44 else:
|
|
45 shadow_dict[block_var_name] = [block_var]
|
|
46 # Get the parent block and continue
|
|
47 block = block.GetParent()
|
|
48
|
|
49 num_shadowed_variables = 0
|
|
50 if shadow_dict:
|
|
51 for name in shadow_dict.keys():
|
|
52 shadow_vars = shadow_dict[name]
|
|
53 if len(shadow_vars) > 1:
|
|
54 print('"%s" is shadowed by the following declarations:' % (name))
|
|
55 num_shadowed_variables += 1
|
|
56 for shadow_var in shadow_vars:
|
|
57 print(str(shadow_var.GetDeclaration()), file=result)
|
|
58 if num_shadowed_variables == 0:
|
|
59 print('no variables are shadowed', file=result)
|