1#!/usr/bin/python 2 3#---------------------------------------------------------------------- 4# Be sure to add the python path that points to the LLDB shared library. 5# 6# # To use this in the embedded python interpreter using "lldb" just 7# import it with the full path using the "command script import" 8# command 9# (lldb) command script import /path/to/cmdtemplate.py 10#---------------------------------------------------------------------- 11 12import lldb 13import commands 14import optparse 15import shlex 16 17class FrameStatCommand: 18 def create_options(self): 19 20 usage = "usage: %prog [options]" 21 description = '''This command is meant to be an example of how to make an LLDB command that 22does something useful, follows best practices, and exploits the SB API. 23Specifically, this command computes the aggregate and average size of the variables in the current frame 24and allows you to tweak exactly which variables are to be accounted in the computation. 25''' 26 27 # Pass add_help_option = False, since this keeps the command in line with lldb commands, 28 # and we wire up "help command" to work by providing the long & short help methods below. 29 self.parser = optparse.OptionParser( 30 description = description, 31 prog = 'framestats', 32 usage = usage, 33 add_help_option = False) 34 35 self.parser.add_option( 36 '-i', 37 '--in-scope', 38 action = 'store_true', 39 dest = 'inscope', 40 help = 'in_scope_only = True', 41 default = True) 42 43 self.parser.add_option( 44 '-a', 45 '--arguments', 46 action = 'store_true', 47 dest = 'arguments', 48 help = 'arguments = True', 49 default = True) 50 51 self.parser.add_option( 52 '-l', 53 '--locals', 54 action = 'store_true', 55 dest = 'locals', 56 help = 'locals = True', 57 default = True) 58 59 self.parser.add_option( 60 '-s', 61 '--statics', 62 action = 'store_true', 63 dest = 'statics', 64 help = 'statics = True', 65 default = True) 66 67 def get_short_help(self): 68 return "Example command for use in debugging" 69 70 def get_long_help(self): 71 return self.help_string 72 73 def __init__(self, debugger, unused): 74 self.create_options() 75 self.help_string = self.parser.format_help() 76 77 def __call__(self, debugger, command, exe_ctx, result): 78 # Use the Shell Lexer to properly parse up command options just like a 79 # shell would 80 command_args = shlex.split(command) 81 82 try: 83 (options, args) = self.parser.parse_args(command_args) 84 except: 85 # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit 86 # (courtesy of OptParse dealing with argument errors by throwing SystemExit) 87 result.SetError("option parsing failed") 88 return 89 90 # Always get program state from the SBExecutionContext passed in as exe_ctx 91 frame = exe_ctx.GetFrame() 92 if not frame.IsValid(): 93 result.SetError("invalid frame") 94 return 95 96 variables_list = frame.GetVariables( 97 options.arguments, 98 options.locals, 99 options.statics, 100 options.inscope) 101 variables_count = variables_list.GetSize() 102 if variables_count == 0: 103 print >> result, "no variables here" 104 return 105 total_size = 0 106 for i in range(0, variables_count): 107 variable = variables_list.GetValueAtIndex(i) 108 variable_type = variable.GetType() 109 total_size = total_size + variable_type.GetByteSize() 110 average_size = float(total_size) / variables_count 111 print >>result, "Your frame has %d variables. Their total size is %d bytes. The average size is %f bytes" % ( 112 variables_count, total_size, average_size) 113 # not returning anything is akin to returning success 114 115 116def __lldb_init_module(debugger, dict): 117 # This initializer is being run from LLDB in the embedded command interpreter 118 119 # Add any commands contained in this module to LLDB 120 debugger.HandleCommand( 121 'command script add -c cmdtemplate.FrameStatCommand framestats') 122 print 'The "framestats" command has been installed, type "help framestats" for detailed help.' 123