1""" 2Test defining commands using the lldb command definitions 3""" 4import inspect 5import sys 6import lldb 7from lldb.plugins.parsed_cmd import ParsedCommand 8 9class ReportingCmd(ParsedCommand): 10 def __init__(self, debugger, unused): 11 super().__init__(debugger, unused) 12 13 def __call__(self, debugger, args_array, exe_ctx, result): 14 opt_def = self.get_options_definition() 15 if len(opt_def): 16 result.AppendMessage("Options:\n") 17 for long_option, elem in opt_def.items(): 18 dest = elem["dest"] 19 result.AppendMessage(f"{long_option} (set: {elem['_value_set']}): {object.__getattribute__(self.ov_parser, dest)}\n") 20 else: 21 result.AppendMessage("No options\n") 22 23 num_args = args_array.GetSize() 24 if num_args > 0: 25 result.AppendMessage(f"{num_args} arguments:") 26 for idx in range(0,num_args): 27 result.AppendMessage(f"{idx}: {args_array.GetItemAtIndex(idx).GetStringValue(10000)}\n") 28 29class NoArgsCommand(ReportingCmd): 30 program = "no-args" 31 32 def __init__(self, debugger, unused): 33 super().__init__(debugger, unused) 34 35 @classmethod 36 def register_lldb_command(cls, debugger, module_name): 37 ParsedCommand.do_register_cmd(cls, debugger, module_name) 38 39 def setup_command_definition(self): 40 self.ov_parser.add_option( 41 "b", 42 "bool-arg", 43 "a boolean arg, defaults to True", 44 value_type = lldb.eArgTypeBoolean, 45 groups = [1,2], 46 dest = "bool_arg", 47 default = True 48 ) 49 50 self.ov_parser.add_option( 51 "s", 52 "shlib-name", 53 "A shared library name.", 54 value_type=lldb.eArgTypeShlibName, 55 groups = [1, [3,4]], 56 dest = "shlib_name", 57 default = None 58 ) 59 60 self.ov_parser.add_option( 61 "d", 62 "disk-file-name", 63 "An on disk filename", 64 value_type = lldb.eArgTypeFilename, 65 dest = "disk_file_name", 66 default = None 67 ) 68 69 self.ov_parser.add_option( 70 "l", 71 "line-num", 72 "A line number", 73 value_type = lldb.eArgTypeLineNum, 74 groups = 3, 75 dest = "line_num", 76 default = 0 77 ) 78 79 self.ov_parser.add_option( 80 "e", 81 "enum-option", 82 "An enum, doesn't actually do anything", 83 enum_values = [["foo", "does foo things"], 84 ["bar", "does bar things"], 85 ["baz", "does baz things"]], 86 groups = 4, 87 dest = "enum_option", 88 default = "foo" 89 ) 90 91 def get_short_help(self): 92 return "Example command for use in debugging" 93 94 def get_long_help(self): 95 return self.help_string 96 97class OneArgCommandNoOptions(ReportingCmd): 98 program = "one-arg-no-opt" 99 100 def __init__(self, debugger, unused): 101 super().__init__(debugger, unused) 102 103 @classmethod 104 def register_lldb_command(cls, debugger, module_name): 105 ParsedCommand.do_register_cmd(cls, debugger, module_name) 106 107 def setup_command_definition(self): 108 self.ov_parser.add_argument_set([self.ov_parser.make_argument_element(lldb.eArgTypeSourceFile, "plain")]) 109 110 def get_short_help(self): 111 return "Example command for use in debugging" 112 113 def get_long_help(self): 114 return self.help_string 115 116class TwoArgGroupsCommand(ReportingCmd): 117 program = "two-args" 118 119 def __init__(self, debugger, unused): 120 super().__init__(debugger, unused) 121 122 @classmethod 123 def register_lldb_command(cls, debugger, module_name): 124 ParsedCommand.do_register_cmd(cls, debugger, module_name) 125 126 def setup_command_definition(self): 127 self.ov_parser.add_option( 128 "l", 129 "language", 130 "language defaults to None", 131 value_type = lldb.eArgTypeLanguage, 132 groups = [1,2], 133 dest = "language", 134 default = None 135 ) 136 137 self.ov_parser.add_option( 138 "c", 139 "log-channel", 140 "log channel - defaults to lldb", 141 value_type=lldb.eArgTypeLogChannel, 142 groups = [1, 3], 143 dest = "log_channel", 144 default = "lldb" 145 ) 146 147 self.ov_parser.add_option( 148 "p", 149 "process-name", 150 "A process name, defaults to None", 151 value_type = lldb.eArgTypeProcessName, 152 dest = "proc_name", 153 default = None 154 ) 155 156 self.ov_parser.add_argument_set([self.ov_parser.make_argument_element(lldb.eArgTypeClassName, "plain", [1,2]), 157 self.ov_parser.make_argument_element(lldb.eArgTypeOffset, "optional", [1,2])]) 158 159 self.ov_parser.add_argument_set([self.ov_parser.make_argument_element(lldb.eArgTypePythonClass, "plain", [3,4]), 160 self.ov_parser.make_argument_element(lldb.eArgTypePid, "optional", [3,4])]) 161 162 def get_short_help(self): 163 return "Example command for use in debugging" 164 165 def get_long_help(self): 166 return self.help_string 167 168def __lldb_init_module(debugger, dict): 169 # Register all classes that have a register_lldb_command method 170 for _name, cls in inspect.getmembers(sys.modules[__name__]): 171 if inspect.isclass(cls) and callable( 172 getattr(cls, "register_lldb_command", None) 173 ): 174 cls.register_lldb_command(debugger, __name__) 175