1d879a630SGreg Clayton#!/usr/bin/python 2d879a630SGreg Clayton 3d879a630SGreg Clayton#---------------------------------------------------------------------- 4d879a630SGreg Clayton# Be sure to add the python path that points to the LLDB shared library. 5d879a630SGreg Clayton# 6e2841639SGreg Clayton# # To use this in the embedded python interpreter using "lldb" just 7e2841639SGreg Clayton# import it with the full path using the "command script import" 8e2841639SGreg Clayton# command 9e2841639SGreg Clayton# (lldb) command script import /path/to/cmdtemplate.py 10d879a630SGreg Clayton#---------------------------------------------------------------------- 11d879a630SGreg Clayton 12d879a630SGreg Claytonimport lldb 13d879a630SGreg Claytonimport commands 14d879a630SGreg Claytonimport optparse 15d879a630SGreg Claytonimport shlex 16d879a630SGreg Clayton 17083fcdb4SEnrico Granatadef create_framestats_options(): 18083fcdb4SEnrico Granata usage = "usage: %prog [options]" 19083fcdb4SEnrico Granata description='''This command is meant to be an example of how to make an LLDB command that 20083fcdb4SEnrico Granatadoes something useful, follows best practices, and exploits the SB API. 21083fcdb4SEnrico GranataSpecifically, this command computes the aggregate and average size of the variables in the current frame 22083fcdb4SEnrico Granataand allows you to tweak exactly which variables are to be accounted in the computation. 23f453907aSGreg Clayton''' 24083fcdb4SEnrico Granata parser = optparse.OptionParser(description=description, prog='framestats',usage=usage) 25083fcdb4SEnrico Granata parser.add_option('-i', '--in-scope', action='store_true', dest='inscope', help='in_scope_only = True', default=False) 26083fcdb4SEnrico Granata parser.add_option('-a', '--arguments', action='store_true', dest='arguments', help='arguments = True', default=False) 27083fcdb4SEnrico Granata parser.add_option('-l', '--locals', action='store_true', dest='locals', help='locals = True', default=False) 28083fcdb4SEnrico Granata parser.add_option('-s', '--statics', action='store_true', dest='statics', help='statics = True', default=False) 29f453907aSGreg Clayton return parser 30f453907aSGreg Clayton 31083fcdb4SEnrico Granatadef the_framestats_command(debugger, command, result, dict): 32f453907aSGreg Clayton # Use the Shell Lexer to properly parse up command options just like a 33f453907aSGreg Clayton # shell would 34f453907aSGreg Clayton command_args = shlex.split(command) 35083fcdb4SEnrico Granata parser = create_framestats_options() 36d879a630SGreg Clayton try: 37d879a630SGreg Clayton (options, args) = parser.parse_args(command_args) 38d879a630SGreg Clayton except: 396308f582SEnrico Granata # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit 406308f582SEnrico Granata # (courtesy of OptParse dealing with argument errors by throwing SystemExit) 41*da504ff0SEnrico Granata result.SetError ("option parsing failed") 42*da504ff0SEnrico Granata return 43d879a630SGreg Clayton 44083fcdb4SEnrico Granata # in a command - the lldb.* convenience variables are not to be used 45083fcdb4SEnrico Granata # and their values (if any) are undefined 46083fcdb4SEnrico Granata # this is the best practice to access those objects from within a command 47083fcdb4SEnrico Granata target = debugger.GetSelectedTarget() 48083fcdb4SEnrico Granata process = target.GetProcess() 49083fcdb4SEnrico Granata thread = process.GetSelectedThread() 50083fcdb4SEnrico Granata frame = thread.GetSelectedFrame() 51083fcdb4SEnrico Granata if not frame.IsValid(): 52083fcdb4SEnrico Granata return "no frame here" 53083fcdb4SEnrico Granata # from now on, replace lldb.<thing>.whatever with <thing>.whatever 54083fcdb4SEnrico Granata variables_list = frame.GetVariables(options.arguments, options.locals, options.statics, options.inscope) 55083fcdb4SEnrico Granata variables_count = variables_list.GetSize() 56083fcdb4SEnrico Granata if variables_count == 0: 57*da504ff0SEnrico Granata print >> result, "no variables here" 58083fcdb4SEnrico Granata return 59083fcdb4SEnrico Granata total_size = 0 60083fcdb4SEnrico Granata for i in range(0,variables_count): 61083fcdb4SEnrico Granata variable = variables_list.GetValueAtIndex(i) 62083fcdb4SEnrico Granata variable_type = variable.GetType() 63083fcdb4SEnrico Granata total_size = total_size + variable_type.GetByteSize() 64083fcdb4SEnrico Granata average_size = float(total_size) / variables_count 65*da504ff0SEnrico Granata print >>result, "Your frame has %d variables. Their total size is %d bytes. The average size is %f bytes" % (variables_count,total_size,average_size) 66*da504ff0SEnrico Granata # not returning anything is akin to returning success 67d879a630SGreg Clayton 6887a59368SJim Inghamdef __lldb_init_module (debugger, dict): 6987a59368SJim Ingham # This initializer is being run from LLDB in the embedded command interpreter 70f453907aSGreg Clayton # Make the options so we can generate the help text for the new LLDB 71f453907aSGreg Clayton # command line command prior to registering it with LLDB below 72083fcdb4SEnrico Granata parser = create_framestats_options() 73083fcdb4SEnrico Granata the_framestats_command.__doc__ = parser.format_help() 74d879a630SGreg Clayton # Add any commands contained in this module to LLDB 75083fcdb4SEnrico Granata debugger.HandleCommand('command script add -f cmdtemplate.the_framestats_command framestats') 76083fcdb4SEnrico Granata print 'The "framestats" command has been installed, type "help framestats" or "framestats --help" for detailed help.' 77