1061da546SpatrickPython Reference 2061da546Spatrick================ 3061da546Spatrick 4061da546SpatrickThe entire LLDB API is available as Python functions through a script bridging 5061da546Spatrickinterface. This means the LLDB API's can be used directly from python either 6061da546Spatrickinteractively or to build python apps that provide debugger features. 7061da546Spatrick 8061da546SpatrickAdditionally, Python can be used as a programmatic interface within the lldb 9061da546Spatrickcommand interpreter (we refer to this for brevity as the embedded interpreter). 10061da546SpatrickOf course, in this context it has full access to the LLDB API - with some 11061da546Spatrickadditional conveniences we will call out in the FAQ. 12061da546Spatrick 13061da546Spatrick.. contents:: 14061da546Spatrick :local: 15061da546Spatrick 16061da546SpatrickDocumentation 17061da546Spatrick-------------- 18061da546Spatrick 19061da546SpatrickThe LLDB API is contained in a python module named lldb. A useful resource when 20061da546Spatrickwriting Python extensions is the lldb Python classes reference guide. 21061da546Spatrick 22061da546SpatrickThe documentation is also accessible in an interactive debugger session with 23061da546Spatrickthe following command: 24061da546Spatrick 25061da546Spatrick:: 26061da546Spatrick 27061da546Spatrick (lldb) script help(lldb) 28061da546Spatrick Help on package lldb: 29061da546Spatrick 30061da546Spatrick NAME 31061da546Spatrick lldb - The lldb module contains the public APIs for Python binding. 32061da546Spatrick 33061da546Spatrick FILE 34061da546Spatrick /System/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/__init__.py 35061da546Spatrick 36061da546Spatrick DESCRIPTION 37061da546Spatrick ... 38061da546Spatrick 39061da546SpatrickYou can also get help using a module class name. The full API that is exposed 40061da546Spatrickfor that class will be displayed in a man page style window. Below we want to 41061da546Spatrickget help on the lldb.SBFrame class: 42061da546Spatrick 43061da546Spatrick:: 44061da546Spatrick 45061da546Spatrick (lldb) script help(lldb.SBFrame) 46061da546Spatrick Help on class SBFrame in module lldb: 47061da546Spatrick 48061da546Spatrick class SBFrame(__builtin__.object) 49061da546Spatrick | Represents one of the stack frames associated with a thread. 50061da546Spatrick | SBThread contains SBFrame(s). For example (from test/lldbutil.py), 51061da546Spatrick | 52061da546Spatrick | def print_stacktrace(thread, string_buffer = False): 53061da546Spatrick | '''Prints a simple stack trace of this thread.''' 54061da546Spatrick | 55061da546Spatrick ... 56061da546Spatrick 57061da546SpatrickOr you can get help using any python object, here we use the lldb.process 58061da546Spatrickobject which is a global variable in the lldb module which represents the 59061da546Spatrickcurrently selected process: 60061da546Spatrick 61061da546Spatrick:: 62061da546Spatrick 63061da546Spatrick (lldb) script help(lldb.process) 64061da546Spatrick Help on SBProcess in module lldb object: 65061da546Spatrick 66061da546Spatrick class SBProcess(__builtin__.object) 67061da546Spatrick | Represents the process associated with the target program. 68061da546Spatrick | 69061da546Spatrick | SBProcess supports thread iteration. For example (from test/lldbutil.py), 70061da546Spatrick | 71061da546Spatrick | # ================================================== 72061da546Spatrick | # Utility functions related to Threads and Processes 73061da546Spatrick | # ================================================== 74061da546Spatrick | 75061da546Spatrick ... 76061da546Spatrick 77061da546SpatrickEmbedded Python Interpreter 78061da546Spatrick--------------------------- 79061da546Spatrick 80061da546SpatrickThe embedded python interpreter can be accessed in a variety of ways from 81061da546Spatrickwithin LLDB. The easiest way is to use the lldb command script with no 82061da546Spatrickarguments at the lldb command prompt: 83061da546Spatrick 84061da546Spatrick:: 85061da546Spatrick 86061da546Spatrick (lldb) script 87061da546Spatrick Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D. 88061da546Spatrick >>> 2+3 89061da546Spatrick 5 90061da546Spatrick >>> hex(12345) 91061da546Spatrick '0x3039' 92061da546Spatrick >>> 93061da546Spatrick 94061da546SpatrickThis drops you into the embedded python interpreter. When running under the 95061da546Spatrickscript command, lldb sets some convenience variables that give you quick access 96061da546Spatrickto the currently selected entities that characterize the program and debugger 97061da546Spatrickstate. In each case, if there is no currently selected entity of the 98061da546Spatrickappropriate type, the variable's IsValid method will return false. These 99061da546Spatrickvariables are: 100061da546Spatrick 101be691f3bSpatrick+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 102be691f3bSpatrick| Variable | Type | Equivalent | Description | 103be691f3bSpatrick+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 104be691f3bSpatrick| ``lldb.debugger`` | `lldb.SBDebugger` | `SBTarget.GetDebugger` | Contains the debugger object whose ``script`` command was invoked. | 105be691f3bSpatrick| | | | The `lldb.SBDebugger` object owns the command interpreter | 106be691f3bSpatrick| | | | and all the targets in your debug session. There will always be a | 107be691f3bSpatrick| | | | Debugger in the embedded interpreter. | 108be691f3bSpatrick+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 109be691f3bSpatrick| ``lldb.target`` | `lldb.SBTarget` | `SBDebugger.GetSelectedTarget` | Contains the currently selected target - for instance the one made with the | 110be691f3bSpatrick| | | | ``file`` or selected by the ``target select <target-index>`` command. | 111be691f3bSpatrick| | | `SBProcess.GetTarget` | The `lldb.SBTarget` manages one running process, and all the executable | 112be691f3bSpatrick| | | | and debug files for the process. | 113be691f3bSpatrick+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 114be691f3bSpatrick| ``lldb.process`` | `lldb.SBProcess` | `SBTarget.GetProcess` | Contains the process of the currently selected target. | 115be691f3bSpatrick| | | | The `lldb.SBProcess` object manages the threads and allows access to | 116be691f3bSpatrick| | | `SBThread.GetProcess` | memory for the process. | 117be691f3bSpatrick+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 118be691f3bSpatrick| ``lldb.thread`` | `lldb.SBThread` | `SBProcess.GetSelectedThread` | Contains the currently selected thread. | 119be691f3bSpatrick| | | | The `lldb.SBThread` object manages the stack frames in that thread. | 120be691f3bSpatrick| | | `SBFrame.GetThread` | A thread is always selected in the command interpreter when a target stops. | 121be691f3bSpatrick| | | | The ``thread select <thread-index>`` command can be used to change the | 122be691f3bSpatrick| | | | currently selected thread. So as long as you have a stopped process, there will be | 123be691f3bSpatrick| | | | some selected thread. | 124be691f3bSpatrick+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 125be691f3bSpatrick| ``lldb.frame`` | `lldb.SBFrame` | `SBThread.GetSelectedFrame` | Contains the currently selected stack frame. | 126be691f3bSpatrick| | | | The `lldb.SBFrame` object manage the stack locals and the register set for | 127be691f3bSpatrick| | | | that stack. | 128be691f3bSpatrick| | | | A stack frame is always selected in the command interpreter when a target stops. | 129be691f3bSpatrick| | | | The ``frame select <frame-index>`` command can be used to change the | 130be691f3bSpatrick| | | | currently selected frame. So as long as you have a stopped process, there will | 131be691f3bSpatrick| | | | be some selected frame. | 132be691f3bSpatrick+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 133061da546Spatrick 134061da546SpatrickWhile extremely convenient, these variables have a couple caveats that you 135061da546Spatrickshould be aware of. First of all, they hold the values of the selected objects 136061da546Spatrickon entry to the embedded interpreter. They do not update as you use the LLDB 137061da546SpatrickAPI's to change, for example, the currently selected stack frame or thread. 138061da546Spatrick 139061da546SpatrickMoreover, they are only defined and meaningful while in the interactive Python 140061da546Spatrickinterpreter. There is no guarantee on their value in any other situation, hence 141061da546Spatrickyou should not use them when defining Python formatters, breakpoint scripts and 142be691f3bSpatrickcommands (or any other Python extension point that LLDB provides). For the 143be691f3bSpatricklatter you'll be passed an `SBDebugger`, `SBTarget`, `SBProcess`, `SBThread` or 144be691f3bSpatrick`SBFrame` instance and you can use the functions from the "Equivalent" column 145be691f3bSpatrickto navigate between them. 146be691f3bSpatrick 147be691f3bSpatrickAs a rationale for such behavior, consider that lldb can run in a multithreaded 148061da546Spatrickenvironment, and another thread might call the "script" command, changing the 149061da546Spatrickvalue out from under you. 150061da546Spatrick 151061da546SpatrickTo get started with these objects and LLDB scripting, please note that almost 152061da546Spatrickall of the lldb Python objects are able to briefly describe themselves when you 153061da546Spatrickpass them to the Python print function: 154061da546Spatrick 155061da546Spatrick:: 156061da546Spatrick 157061da546Spatrick (lldb) script 158061da546Spatrick Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D. 159061da546Spatrick >>> print lldb.debugger 160061da546Spatrick Debugger (instance: "debugger_1", id: 1) 161061da546Spatrick >>> print lldb.target 162061da546Spatrick a.out 163061da546Spatrick >>> print lldb.process 164061da546Spatrick SBProcess: pid = 59289, state = stopped, threads = 1, executable = a.out 165061da546Spatrick >>> print lldb.thread 166061da546Spatrick SBThread: tid = 0x1f03 167061da546Spatrick >>> print lldb.frame 168061da546Spatrick frame #0: 0x0000000100000bb6 a.out main + 54 at main.c:16 169061da546Spatrick 170061da546Spatrick 171061da546SpatrickRunning a python script when a breakpoint gets hit 172061da546Spatrick-------------------------------------------------- 173061da546Spatrick 174061da546SpatrickOne very powerful use of the lldb Python API is to have a python script run 175061da546Spatrickwhen a breakpoint gets hit. Adding python scripts to breakpoints provides a way 176061da546Spatrickto create complex breakpoint conditions and also allows for smart logging and 177061da546Spatrickdata gathering. 178061da546Spatrick 179061da546SpatrickWhen your process hits a breakpoint to which you have attached some python 180061da546Spatrickcode, the code is executed as the body of a function which takes three 181061da546Spatrickarguments: 182061da546Spatrick 183061da546Spatrick:: 184061da546Spatrick 185be691f3bSpatrick def breakpoint_function_wrapper(frame, bp_loc, internal_dict): 186be691f3bSpatrick # Your code goes here 187be691f3bSpatrick 188be691f3bSpatrickor: 189be691f3bSpatrick 190be691f3bSpatrick:: 191be691f3bSpatrick 192be691f3bSpatrick def breakpoint_function_wrapper(frame, bp_loc, extra_args, internal_dict): 193061da546Spatrick # Your code goes here 194061da546Spatrick 195061da546Spatrick 196be691f3bSpatrick+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 197061da546Spatrick| Argument | Type | Description | 198be691f3bSpatrick+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 199be691f3bSpatrick| ``frame`` | `lldb.SBFrame` | The current stack frame where the breakpoint got hit. | 200061da546Spatrick| | | The object will always be valid. | 201be691f3bSpatrick| | | This ``frame`` argument might *not* match the currently selected stack frame found in the `lldb` module global variable ``lldb.frame``. | 202be691f3bSpatrick+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 203be691f3bSpatrick| ``bp_loc`` | `lldb.SBBreakpointLocation` | The breakpoint location that just got hit. Breakpoints are represented by `lldb.SBBreakpoint` | 204061da546Spatrick| | | objects. These breakpoint objects can have one or more locations. These locations | 205be691f3bSpatrick| | | are represented by `lldb.SBBreakpointLocation` objects. | 206be691f3bSpatrick+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 207be691f3bSpatrick| ``extra_args`` | `lldb.SBStructuredData` | ``Optional`` If your breakpoint callback function takes this extra parameter, then when the callback gets added to a breakpoint, its | 208be691f3bSpatrick| | | contents can parametrize this use of the callback. For instance, instead of writing a callback that stops when the caller is "Foo", | 209be691f3bSpatrick| | | you could take the function name from a field in the ``extra_args``, making the callback more general. The ``-k`` and ``-v`` options | 210be691f3bSpatrick| | | to ``breakpoint command add`` will be passed as a Dictionary in the ``extra_args`` parameter, or you can provide it with the SB API's. | 211be691f3bSpatrick+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 212be691f3bSpatrick| ``internal_dict`` | ``dict`` | The python session dictionary as a standard python dictionary object. | 213be691f3bSpatrick+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 214061da546Spatrick 215061da546SpatrickOptionally, a Python breakpoint command can return a value. Returning False 216061da546Spatricktells LLDB that you do not want to stop at the breakpoint. Any other return 217061da546Spatrickvalue (including None or leaving out the return statement altogether) is akin 218061da546Spatrickto telling LLDB to actually stop at the breakpoint. This can be useful in 219061da546Spatricksituations where a breakpoint only needs to stop the process when certain 220061da546Spatrickconditions are met, and you do not want to inspect the program state manually 221061da546Spatrickat every stop and then continue. 222061da546Spatrick 223061da546SpatrickAn example will show how simple it is to write some python code and attach it 224061da546Spatrickto a breakpoint. The following example will allow you to track the order in 225061da546Spatrickwhich the functions in a given shared library are first executed during one run 226061da546Spatrickof your program. This is a simple method to gather an order file which can be 227061da546Spatrickused to optimize function placement within a binary for execution locality. 228061da546Spatrick 229061da546SpatrickWe do this by setting a regular expression breakpoint that will match every 230061da546Spatrickfunction in the shared library. The regular expression '.' will match any 231061da546Spatrickstring that has at least one character in it, so we will use that. This will 232061da546Spatrickresult in one lldb.SBBreakpoint object that contains an 233061da546Spatricklldb.SBBreakpointLocation object for each function. As the breakpoint gets hit, 234061da546Spatrickwe use a counter to track the order in which the function at this particular 235061da546Spatrickbreakpoint location got hit. Since our code is passed the location that was 236061da546Spatrickhit, we can get the name of the function from the location, disable the 237061da546Spatricklocation so we won't count this function again; then log some info and continue 238061da546Spatrickthe process. 239061da546Spatrick 240061da546SpatrickNote we also have to initialize our counter, which we do with the simple 241061da546Spatrickone-line version of the script command. 242061da546Spatrick 243061da546SpatrickHere is the code: 244061da546Spatrick 245061da546Spatrick:: 246061da546Spatrick 247061da546Spatrick (lldb) breakpoint set --func-regex=. --shlib=libfoo.dylib 248061da546Spatrick Breakpoint created: 1: regex = '.', module = libfoo.dylib, locations = 223 249061da546Spatrick (lldb) script counter = 0 250061da546Spatrick (lldb) breakpoint command add --script-type python 1 251061da546Spatrick Enter your Python command(s). Type 'DONE' to end. 252061da546Spatrick > # Increment our counter. Since we are in a function, this must be a global python variable 253061da546Spatrick > global counter 254061da546Spatrick > counter += 1 255061da546Spatrick > # Get the name of the function 256061da546Spatrick > name = frame.GetFunctionName() 257061da546Spatrick > # Print the order and the function name 258061da546Spatrick > print '[%i] %s' % (counter, name) 259061da546Spatrick > # Disable the current breakpoint location so it doesn't get hit again 260061da546Spatrick > bp_loc.SetEnabled(False) 261061da546Spatrick > # No need to stop here 262061da546Spatrick > return False 263061da546Spatrick > DONE 264061da546Spatrick 265061da546SpatrickThe breakpoint command add command above attaches a python script to breakpoint 1. To remove the breakpoint command: 266061da546Spatrick 267061da546Spatrick:: 268061da546Spatrick 269061da546Spatrick (lldb) breakpoint command delete 1 270061da546Spatrick 271061da546Spatrick 272061da546SpatrickUsing the python api's to create custom breakpoints 273061da546Spatrick--------------------------------------------------- 274061da546Spatrick 275061da546Spatrick 276061da546SpatrickAnother use of the Python API's in lldb is to create a custom breakpoint 277061da546Spatrickresolver. This facility was added in r342259. 278061da546Spatrick 279061da546SpatrickIt allows you to provide the algorithm which will be used in the breakpoint's 280061da546Spatricksearch of the space of the code in a given Target to determine where to set the 281061da546Spatrickbreakpoint locations - the actual places where the breakpoint will trigger. To 282061da546Spatrickunderstand how this works you need to know a little about how lldb handles 283061da546Spatrickbreakpoints. 284061da546Spatrick 285061da546SpatrickIn lldb, a breakpoint is composed of three parts: the Searcher, the Resolver, 286061da546Spatrickand the Stop Options. The Searcher and Resolver cooperate to determine how 287061da546Spatrickbreakpoint locations are set and differ between each breakpoint type. Stop 288061da546Spatrickoptions determine what happens when a location triggers and includes the 289061da546Spatrickcommands, conditions, ignore counts, etc. Stop options are common between all 290061da546Spatrickbreakpoint types, so for our purposes only the Searcher and Resolver are 291061da546Spatrickrelevant. 292061da546Spatrick 293061da546SpatrickThe Searcher's job is to traverse in a structured way the code in the current 294061da546Spatricktarget. It proceeds from the Target, to search all the Modules in the Target, 295061da546Spatrickin each Module it can recurse into the Compile Units in that module, and within 296061da546Spatrickeach Compile Unit it can recurse over the Functions it contains. 297061da546Spatrick 298061da546SpatrickThe Searcher can be provided with a SearchFilter that it will use to restrict 299061da546Spatrickthis search. For instance, if the SearchFilter specifies a list of Modules, the 300061da546SpatrickSearcher will not recurse into Modules that aren't on the list. When you pass 301061da546Spatrickthe -s modulename flag to break set you are creating a Module-based search 302061da546Spatrickfilter. When you pass -f filename.c to break set -n you are creating a file 303061da546Spatrickbased search filter. If neither of these is specified, the breakpoint will have 304061da546Spatricka no-op search filter, so all parts of the program are searched and all 305061da546Spatricklocations accepted. 306061da546Spatrick 307061da546SpatrickThe Resolver has two functions. The most important one is the callback it 308061da546Spatrickprovides. This will get called at the appropriate time in the course of the 309061da546Spatricksearch. The callback is where the job of adding locations to the breakpoint 310061da546Spatrickgets done. 311061da546Spatrick 312061da546SpatrickThe other function is specifying to the Searcher at what depth in the above 313061da546Spatrickdescribed recursion it wants to be called. Setting a search depth also provides 314061da546Spatricka stop for the recursion. For instance, if you request a Module depth search, 315061da546Spatrickthen the callback will be called for each Module as it gets added to the 316061da546SpatrickTarget, but the searcher will not recurse into the Compile Units in the module. 317061da546Spatrick 318be691f3bSpatrickOne other slight subtlety is that the depth at which you get called back is not 319be691f3bSpatricknecessarily the depth at which the SearchFilter is specified. For instance, 320061da546Spatrickif you are doing symbol searches, it is convenient to use the Module depth for 321061da546Spatrickthe search, since symbols are stored in the module. But the SearchFilter might 322061da546Spatrickspecify some subset of CompileUnits, so not all the symbols you might find in 323061da546Spatrickeach module will pass the search. You don't need to handle this situation 324061da546Spatrickyourself, since SBBreakpoint::AddLocation will only add locations that pass the 325061da546SpatrickSearch Filter. This API returns an SBError to inform you whether your location 326061da546Spatrickwas added. 327061da546Spatrick 328061da546SpatrickWhen the breakpoint is originally created, its Searcher will process all the 329061da546Spatrickcurrently loaded modules. The Searcher will also visit any new modules as they 330061da546Spatrickare added to the target. This happens, for instance, when a new shared library 331061da546Spatrickgets added to the target in the course of running, or on rerunning if any of 332061da546Spatrickthe currently loaded modules have been changed. Note, in the latter case, all 333061da546Spatrickthe locations set in the old module will get deleted and you will be asked to 334061da546Spatrickrecreate them in the new version of the module when your callback gets called 335061da546Spatrickwith that module. For this reason, you shouldn't try to manage the locations 336061da546Spatrickyou add to the breakpoint yourself. Note that the Breakpoint takes care of 337061da546Spatrickdeduplicating equal addresses in AddLocation, so you shouldn't need to worry 338061da546Spatrickabout that anyway. 339061da546Spatrick 340061da546SpatrickAt present, when adding a scripted Breakpoint type, you can only provide a 341061da546Spatrickcustom Resolver, not a custom SearchFilter. 342061da546Spatrick 343061da546SpatrickThe custom Resolver is provided as a Python class with the following methods: 344061da546Spatrick 345061da546Spatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 346061da546Spatrick| Name | Arguments | Description | 347061da546Spatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 348be691f3bSpatrick| ``__init__`` | ``bkpt``:`lldb.SBBreakpoint` | This is the constructor for the new Resolver. | 349be691f3bSpatrick| | ``extra_args``:`lldb.SBStructuredData`| | 350061da546Spatrick| | | | 351be691f3bSpatrick| | | ``bkpt`` is the breakpoint owning this Resolver. | 352061da546Spatrick| | | | 353061da546Spatrick| | | | 354be691f3bSpatrick| | | ``extra_args`` is an `SBStructuredData` object that the user can pass in when creating instances of this | 355061da546Spatrick| | | breakpoint. It is not required, but is quite handy. For instance if you were implementing a breakpoint on some | 356061da546Spatrick| | | symbol name, you could write a generic symbol name based Resolver, and then allow the user to pass | 357061da546Spatrick| | | in the particular symbol in the extra_args | 358061da546Spatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 359be691f3bSpatrick| ``__callback__`` | ``sym_ctx``:`lldb.SBSymbolContext` | This is the Resolver callback. | 360be691f3bSpatrick| | | The ``sym_ctx`` argument will be filled with the current stage | 361061da546Spatrick| | | of the search. | 362061da546Spatrick| | | | 363061da546Spatrick| | | | 364061da546Spatrick| | | For instance, if you asked for a search depth of lldb.eSearchDepthCompUnit, then the | 365061da546Spatrick| | | target, module and compile_unit fields of the sym_ctx will be filled. The callback should look just in the | 366be691f3bSpatrick| | | context passed in ``sym_ctx`` for new locations. If the callback finds an address of interest, it | 367be691f3bSpatrick| | | can add it to the breakpoint with the `SBBreakpoint.AddLocation` method, using the breakpoint passed | 368be691f3bSpatrick| | | in to the ``__init__`` method. | 369061da546Spatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 370be691f3bSpatrick| ``__get_depth__`` | ``None`` | Specify the depth at which you wish your callback to get called. The currently supported options are: | 371061da546Spatrick| | | | 372be691f3bSpatrick| | | `lldb.eSearchDepthModule` | 373be691f3bSpatrick| | | `lldb.eSearchDepthCompUnit` | 374be691f3bSpatrick| | | `lldb.eSearchDepthFunction` | 375061da546Spatrick| | | | 376061da546Spatrick| | | For instance, if you are looking | 377061da546Spatrick| | | up symbols, which are stored at the Module level, you will want to get called back module by module. | 378be691f3bSpatrick| | | So you would want to return `lldb.eSearchDepthModule`. This method is optional. If not provided the search | 379061da546Spatrick| | | will be done at Module depth. | 380061da546Spatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 381*f6aab3d8Srobert| ``get_short_help`` | ``None`` | This is an optional method. If provided, the returned string will be printed at the beginning of | 382061da546Spatrick| | | the description for this breakpoint. | 383061da546Spatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 384061da546Spatrick 385061da546SpatrickTo define a new breakpoint command defined by this class from the lldb command 386061da546Spatrickline, use the command: 387061da546Spatrick 388061da546Spatrick:: 389061da546Spatrick 390061da546Spatrick (lldb) breakpoint set -P MyModule.MyResolverClass 391061da546Spatrick 392061da546SpatrickYou can also populate the extra_args SBStructuredData with a dictionary of 393061da546Spatrickkey/value pairs with: 394061da546Spatrick 395061da546Spatrick:: 396061da546Spatrick 397061da546Spatrick (lldb) breakpoint set -P MyModule.MyResolverClass -k key_1 -v value_1 -k key_2 -v value_2 398061da546Spatrick 399061da546SpatrickAlthough you can't write a scripted SearchFilter, both the command line and the 400061da546SpatrickSB API's for adding a scripted resolver allow you to specify a SearchFilter 401061da546Spatrickrestricted to certain modules or certain compile units. When using the command 402061da546Spatrickline to create the resolver, you can specify a Module specific SearchFilter by 403061da546Spatrickpassing the -s ModuleName option - which can be specified multiple times. You 404061da546Spatrickcan also specify a SearchFilter restricted to certain compile units by passing 405061da546Spatrickin the -f CompUnitName option. This can also be specified more than once. And 406061da546Spatrickyou can mix the two to specify "this comp unit in this module". So, for 407061da546Spatrickinstance, 408061da546Spatrick 409061da546Spatrick:: 410061da546Spatrick 411061da546Spatrick (lldb) breakpoint set -P MyModule.MyResolverClass -s a.out 412061da546Spatrick 413061da546Spatrickwill use your resolver, but will only recurse into or accept new locations in 414061da546Spatrickthe module a.out. 415061da546Spatrick 416061da546SpatrickAnother option for creating scripted breakpoints is to use the 417061da546SpatrickSBTarget.CreateBreakpointFromScript API. This one has the advantage that you 418061da546Spatrickcan pass in an arbitrary SBStructuredData object, so you can create more 419061da546Spatrickcomplex parametrizations. SBStructuredData has a handy SetFromJSON method which 420061da546Spatrickyou can use for this purpose. Your __init__ function gets passed this 421061da546SpatrickSBStructuredData object. This API also allows you to directly provide the list 422061da546Spatrickof Modules and the list of CompileUnits that will make up the SearchFilter. If 423061da546Spatrickyou pass in empty lists, the breakpoint will use the default "search 424061da546Spatrickeverywhere,accept everything" filter. 425061da546Spatrick 426061da546SpatrickUsing the python API' to create custom stepping logic 427061da546Spatrick----------------------------------------------------- 428061da546Spatrick 429061da546SpatrickA slightly esoteric use of the Python API's is to construct custom stepping 430061da546Spatricktypes. LLDB's stepping is driven by a stack of "thread plans" and a fairly 431061da546Spatricksimple state machine that runs the plans. You can create a Python class that 432061da546Spatrickworks as a thread plan, and responds to the requests the state machine makes to 433061da546Spatrickrun its operations. 434061da546Spatrick 435061da546SpatrickThere is a longer discussion of scripted thread plans and the state machine, 436061da546Spatrickand several interesting examples of their use in: 437061da546Spatrick 438be691f3bSpatrickhttps://github.com/llvm/llvm-project/blob/main/lldb/examples/python/scripted_step.py 439061da546Spatrick 440061da546SpatrickAnd for a MUCH fuller discussion of the whole state machine, see: 441061da546Spatrick 442be691f3bSpatrickhttps://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Target/ThreadPlan.h 443061da546Spatrick 444061da546SpatrickIf you are reading those comments it is useful to know that scripted thread 445*f6aab3d8Srobertplans are set to be "ControllingPlans", and not "OkayToDiscard". 446061da546Spatrick 447061da546SpatrickTo implement a scripted step, you define a python class that has the following 448061da546Spatrickmethods: 449061da546Spatrick 450061da546Spatrick+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 451061da546Spatrick| Name | Arguments | Description | 452061da546Spatrick+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 453be691f3bSpatrick| ``__init__`` | ``thread_plan``:`lldb.SBThreadPlan`| This is the underlying `SBThreadPlan` that is pushed onto the plan stack. | 454061da546Spatrick| | | You will want to store this away in an ivar. Also, if you are going to | 455061da546Spatrick| | | use one of the canned thread plans, you can queue it at this point. | 456061da546Spatrick+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 457be691f3bSpatrick| ``explains_stop`` | ``event``: `lldb.SBEvent` | Return True if this stop is part of your thread plans logic, false otherwise. | 458061da546Spatrick+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 459be691f3bSpatrick| ``is_stale`` | ``None`` | If your plan is no longer relevant (for instance, you were | 460061da546Spatrick| | | stepping in a particular stack frame, but some other operation | 461061da546Spatrick| | | pushed that frame off the stack) return True and your plan will | 462061da546Spatrick| | | get popped. | 463061da546Spatrick+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 464be691f3bSpatrick| ``should_step`` | ``None`` | Return ``True`` if you want lldb to instruction step one instruction, | 465061da546Spatrick| | | or False to continue till the next breakpoint is hit. | 466061da546Spatrick+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 467be691f3bSpatrick| ``should_stop`` | ``event``: `lldb.SBEvent` | If your plan wants to stop and return control to the user at this point, return True. | 468061da546Spatrick| | | If your plan is done at this point, call SetPlanComplete on your | 469061da546Spatrick| | | thread plan instance. | 470061da546Spatrick| | | Also, do any work you need here to set up the next stage of stepping. | 471061da546Spatrick+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 472061da546Spatrick 473061da546SpatrickTo use this class to implement a step, use the command: 474061da546Spatrick 475061da546Spatrick:: 476061da546Spatrick 477061da546Spatrick (lldb) thread step-scripted -C MyModule.MyStepPlanClass 478061da546Spatrick 479061da546SpatrickOr use the SBThread.StepUsingScriptedThreadPlan API. The SBThreadPlan passed 480061da546Spatrickinto your __init__ function can also push several common plans (step 481061da546Spatrickin/out/over and run-to-address) in front of itself on the stack, which can be 482061da546Spatrickused to compose more complex stepping operations. When you use subsidiary plans 483061da546Spatrickyour explains_stop and should_stop methods won't get called until the 484061da546Spatricksubsidiary plan is done, or the process stops for an event the subsidiary plan 485061da546Spatrickdoesn't explain. For instance, step over plans don't explain a breakpoint hit 486061da546Spatrickwhile performing the step-over. 487061da546Spatrick 488061da546Spatrick 489061da546SpatrickCreate a new lldb command using a Python function 490061da546Spatrick------------------------------------------------- 491061da546Spatrick 492061da546SpatrickPython functions can be used to create new LLDB command interpreter commands, 493061da546Spatrickwhich will work like all the natively defined lldb commands. This provides a 494061da546Spatrickvery flexible and easy way to extend LLDB to meet your debugging requirements. 495061da546Spatrick 496061da546SpatrickTo write a python function that implements a new LLDB command define the 497061da546Spatrickfunction to take four arguments as follows: 498061da546Spatrick 499061da546Spatrick:: 500061da546Spatrick 501061da546Spatrick def command_function(debugger, command, result, internal_dict): 502061da546Spatrick # Your code goes here 503061da546Spatrick 504061da546SpatrickOptionally, you can also provide a Python docstring, and LLDB will use it when providing help for your command, as in: 505061da546Spatrick 506061da546Spatrick:: 507061da546Spatrick 508061da546Spatrick def command_function(debugger, command, result, internal_dict): 509061da546Spatrick """This command takes a lot of options and does many fancy things""" 510061da546Spatrick # Your code goes here 511061da546Spatrick 512061da546SpatrickSince lldb 3.5.2, LLDB Python commands can also take an SBExecutionContext as an 513061da546Spatrickargument. This is useful in cases where the command's notion of where to act is 514061da546Spatrickindependent of the currently-selected entities in the debugger. 515061da546Spatrick 516061da546SpatrickThis feature is enabled if the command-implementing function can be recognized 517061da546Spatrickas taking 5 arguments, or a variable number of arguments, and it alters the 518061da546Spatricksignature as such: 519061da546Spatrick 520061da546Spatrick:: 521061da546Spatrick 522061da546Spatrick def command_function(debugger, command, exe_ctx, result, internal_dict): 523061da546Spatrick # Your code goes here 524061da546Spatrick 525061da546Spatrick+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 526061da546Spatrick| Argument | Type | Description | 527061da546Spatrick+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 528be691f3bSpatrick| ``debugger`` | `lldb.SBDebugger` | The current debugger object. | 529061da546Spatrick+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 530be691f3bSpatrick| ``command`` | ``python string`` | A python string containing all arguments for your command. If you need to chop up the arguments | 531be691f3bSpatrick| | | try using the ``shlex`` module's ``shlex.split(command)`` to properly extract the | 532061da546Spatrick| | | arguments. | 533061da546Spatrick+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 534be691f3bSpatrick| ``exe_ctx`` | `lldb.SBExecutionContext` | An execution context object carrying around information on the inferior process' context in which the command is expected to act | 535061da546Spatrick| | | | 536061da546Spatrick| | | *Optional since lldb 3.5.2, unavailable before* | 537061da546Spatrick+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 538be691f3bSpatrick| ``result`` | `lldb.SBCommandReturnObject` | A return object which encapsulates success/failure information for the command and output text | 539061da546Spatrick| | | that needs to be printed as a result of the command. The plain Python "print" command also works but | 540061da546Spatrick| | | text won't go in the result by default (it is useful as a temporary logging facility). | 541061da546Spatrick+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 542be691f3bSpatrick| ``internal_dict`` | ``python dict object`` | The dictionary for the current embedded script session which contains all variables | 543061da546Spatrick| | | and functions. | 544061da546Spatrick+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 545061da546Spatrick 546061da546SpatrickSince lldb 3.7, Python commands can also be implemented by means of a class 547061da546Spatrickwhich should implement the following interface: 548061da546Spatrick 549061da546Spatrick:: 550061da546Spatrick 551061da546Spatrick class CommandObjectType: 552be691f3bSpatrick def __init__(self, debugger, internal_dict): 553061da546Spatrick this call should initialize the command with respect to the command interpreter for the passed-in debugger 554061da546Spatrick def __call__(self, debugger, command, exe_ctx, result): 555061da546Spatrick this is the actual bulk of the command, akin to Python command functions 556061da546Spatrick def get_short_help(self): 557061da546Spatrick this call should return the short help text for this command[1] 558061da546Spatrick def get_long_help(self): 559061da546Spatrick this call should return the long help text for this command[1] 560061da546Spatrick 561061da546Spatrick[1] This method is optional. 562061da546Spatrick 563061da546SpatrickAs a convenience, you can treat the result object as a Python file object, and 564061da546Spatricksay 565061da546Spatrick 566061da546Spatrick:: 567061da546Spatrick 568061da546Spatrick print >>result, "my command does lots of cool stuff" 569061da546Spatrick 570061da546SpatrickSBCommandReturnObject and SBStream both support this file-like behavior by 571061da546Spatrickproviding write() and flush() calls at the Python layer. 572061da546Spatrick 573061da546SpatrickOne other handy convenience when defining lldb command-line commands is the 574061da546Spatrickcommand command script import which will import a module specified by file 575061da546Spatrickpath, so you don't have to change your PYTHONPATH for temporary scripts. It 576061da546Spatrickalso has another convenience that if your new script module has a function of 577061da546Spatrickthe form: 578061da546Spatrick 579061da546Spatrick:: 580061da546Spatrick 581061da546Spatrick def __lldb_init_module(debugger, internal_dict): 582061da546Spatrick # Command Initialization code goes here 583061da546Spatrick 584061da546Spatrickwhere debugger and internal_dict are as above, that function will get run when 585061da546Spatrickthe module is loaded allowing you to add whatever commands you want into the 586061da546Spatrickcurrent debugger. Note that this function will only be run when using the LLDB 587*f6aab3d8Srobertcommand ``command script import``, it will not get run if anyone imports your 588*f6aab3d8Srobertmodule from another module. 589*f6aab3d8Srobert 590*f6aab3d8SrobertThe standard test for ``__main__``, like many python modules do, is useful for 591*f6aab3d8Srobertcreating scripts that can be run from the command line. However, for command 592*f6aab3d8Srobertline scripts, the debugger instance must be created manually. Sample code would 593*f6aab3d8Srobertlook like: 594061da546Spatrick 595061da546Spatrick:: 596061da546Spatrick 597061da546Spatrick if __name__ == '__main__': 598*f6aab3d8Srobert # Initialize the debugger before making any API calls. 599*f6aab3d8Srobert lldb.SBDebugger.Initialize() 600061da546Spatrick # Create a new debugger instance in your module if your module 601061da546Spatrick # can be run from the command line. When we run a script from 602061da546Spatrick # the command line, we won't have any debugger object in 603061da546Spatrick # lldb.debugger, so we can just create it if it will be needed 604*f6aab3d8Srobert debugger = lldb.SBDebugger.Create() 605*f6aab3d8Srobert 606*f6aab3d8Srobert # Next, do whatever work this module should do when run as a command. 607*f6aab3d8Srobert # ... 608*f6aab3d8Srobert 609*f6aab3d8Srobert # Finally, dispose of the debugger you just made. 610*f6aab3d8Srobert lldb.SBDebugger.Destroy(debugger) 611*f6aab3d8Srobert # Terminate the debug session 612*f6aab3d8Srobert lldb.SBDebugger.Terminate() 613*f6aab3d8Srobert 614061da546Spatrick 615061da546SpatrickNow we can create a module called ls.py in the file ~/ls.py that will implement 616061da546Spatricka function that can be used by LLDB's python command code: 617061da546Spatrick 618061da546Spatrick:: 619061da546Spatrick 620be691f3bSpatrick #!/usr/bin/env python 621061da546Spatrick 622061da546Spatrick import lldb 623061da546Spatrick import commands 624061da546Spatrick import optparse 625061da546Spatrick import shlex 626061da546Spatrick 627061da546Spatrick def ls(debugger, command, result, internal_dict): 628061da546Spatrick print >>result, (commands.getoutput('/bin/ls %s' % command)) 629061da546Spatrick 630061da546Spatrick # And the initialization code to add your commands 631061da546Spatrick def __lldb_init_module(debugger, internal_dict): 632061da546Spatrick debugger.HandleCommand('command script add -f ls.ls ls') 633061da546Spatrick print 'The "ls" python command has been installed and is ready for use.' 634061da546Spatrick 635061da546SpatrickNow we can load the module into LLDB and use it 636061da546Spatrick 637061da546Spatrick:: 638061da546Spatrick 639*f6aab3d8Srobert $ lldb 640061da546Spatrick (lldb) command script import ~/ls.py 641061da546Spatrick The "ls" python command has been installed and is ready for use. 642061da546Spatrick (lldb) ls -l /tmp/ 643061da546Spatrick total 365848 644061da546Spatrick -rw-r--r--@ 1 someuser wheel 6148 Jan 19 17:27 .DS_Store 645061da546Spatrick -rw------- 1 someuser wheel 7331 Jan 19 15:37 crash.log 646061da546Spatrick 647*f6aab3d8SrobertYou can also make "container" commands to organize the commands you are adding to 648*f6aab3d8Srobertlldb. Most of the lldb built-in commands structure themselves this way, and using 649*f6aab3d8Sroberta tree structure has the benefit of leaving the one-word command space free for user 650*f6aab3d8Srobertaliases. It can also make it easier to find commands if you are adding more than 651*f6aab3d8Sroberta few of them. Here's a trivial example of adding two "utility" commands into a 652*f6aab3d8Srobert"my-utilities" container: 653*f6aab3d8Srobert 654*f6aab3d8Srobert:: 655*f6aab3d8Srobert 656*f6aab3d8Srobert #!/usr/bin/env python 657*f6aab3d8Srobert 658*f6aab3d8Srobert import lldb 659*f6aab3d8Srobert 660*f6aab3d8Srobert def first_utility(debugger, command, result, internal_dict): 661*f6aab3d8Srobert print("I am the first utility") 662*f6aab3d8Srobert 663*f6aab3d8Srobert def second_utility(debugger, command, result, internal_dict): 664*f6aab3d8Srobert print("I am the second utility") 665*f6aab3d8Srobert 666*f6aab3d8Srobert # And the initialization code to add your commands 667*f6aab3d8Srobert def __lldb_init_module(debugger, internal_dict): 668*f6aab3d8Srobert debugger.HandleCommand('command container add -h "A container for my utilities" my-utilities') 669*f6aab3d8Srobert debugger.HandleCommand('command script add -f my_utilities.first_utility -h "My first utility" my-utilities first') 670*f6aab3d8Srobert debugger.HandleCommand('command script add -f my_utilities.second_utility -h "My second utility" my-utilities second') 671*f6aab3d8Srobert print('The "my-utilities" python command has been installed and its subcommands are ready for use.') 672*f6aab3d8Srobert 673*f6aab3d8SrobertThen your new commands are available under the my-utilities node: 674*f6aab3d8Srobert 675*f6aab3d8Srobert:: 676*f6aab3d8Srobert 677*f6aab3d8Srobert (lldb) help my-utilities 678*f6aab3d8Srobert A container for my utilities 679*f6aab3d8Srobert 680*f6aab3d8Srobert Syntax: my-utilities 681*f6aab3d8Srobert 682*f6aab3d8Srobert The following subcommands are supported: 683*f6aab3d8Srobert 684*f6aab3d8Srobert first -- My first utility Expects 'raw' input (see 'help raw-input'.) 685*f6aab3d8Srobert second -- My second utility Expects 'raw' input (see 'help raw-input'.) 686*f6aab3d8Srobert 687*f6aab3d8Srobert For more help on any particular subcommand, type 'help <command> <subcommand>'. 688*f6aab3d8Srobert (lldb) my-utilities first 689*f6aab3d8Srobert I am the first utility 690*f6aab3d8Srobert 691*f6aab3d8Srobert 692061da546SpatrickA more interesting template has been created in the source repository that can 693061da546Spatrickhelp you to create lldb command quickly: 694061da546Spatrick 695be691f3bSpatrickhttps://github.com/llvm/llvm-project/blob/main/lldb/examples/python/cmdtemplate.py 696061da546Spatrick 697061da546SpatrickA commonly required facility is being able to create a command that does some 698061da546Spatricktoken substitution, and then runs a different debugger command (usually, it 699061da546Spatrickpo'es the result of an expression evaluated on its argument). For instance, 700061da546Spatrickgiven the following program: 701061da546Spatrick 702061da546Spatrick:: 703061da546Spatrick 704061da546Spatrick #import <Foundation/Foundation.h> 705061da546Spatrick NSString* 706061da546Spatrick ModifyString(NSString* src) 707061da546Spatrick { 708061da546Spatrick return [src stringByAppendingString:@"foobar"]; 709061da546Spatrick } 710061da546Spatrick 711061da546Spatrick int main() 712061da546Spatrick { 713061da546Spatrick NSString* aString = @"Hello world"; 714061da546Spatrick NSString* anotherString = @"Let's be friends"; 715061da546Spatrick return 1; 716061da546Spatrick } 717061da546Spatrick 718061da546Spatrickyou may want a pofoo X command, that equates po [ModifyString(X) 719061da546SpatrickcapitalizedString]. The following debugger interaction shows how to achieve 720061da546Spatrickthat goal: 721061da546Spatrick 722061da546Spatrick:: 723061da546Spatrick 724061da546Spatrick (lldb) script 725061da546Spatrick Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D. 726061da546Spatrick >>> def pofoo_funct(debugger, command, result, internal_dict): 727061da546Spatrick ... cmd = "po [ModifyString(" + command + ") capitalizedString]" 728*f6aab3d8Srobert ... debugger.HandleCommand(cmd) 729061da546Spatrick ... 730061da546Spatrick >>> ^D 731061da546Spatrick (lldb) command script add pofoo -f pofoo_funct 732061da546Spatrick (lldb) pofoo aString 733061da546Spatrick $1 = 0x000000010010aa00 Hello Worldfoobar 734061da546Spatrick (lldb) pofoo anotherString 735061da546Spatrick $2 = 0x000000010010aba0 Let's Be Friendsfoobar 736061da546Spatrick 737061da546SpatrickUsing the lldb.py module in Python 738061da546Spatrick---------------------------------- 739061da546Spatrick 740061da546SpatrickLLDB has all of its core code build into a shared library which gets used by 741061da546Spatrickthe `lldb` command line application. On macOS this shared library is a 742061da546Spatrickframework: LLDB.framework and on other unix variants the program is a shared 743061da546Spatricklibrary: lldb.so. LLDB also provides an lldb.py module that contains the 744061da546Spatrickbindings from LLDB into Python. To use the LLDB.framework to create your own 745061da546Spatrickstand-alone python programs, you will need to tell python where to look in 746061da546Spatrickorder to find this module. This is done by setting the PYTHONPATH environment 747061da546Spatrickvariable, adding a path to the directory that contains the lldb.py python 748061da546Spatrickmodule. The lldb driver program has an option to report the path to the lldb 749061da546Spatrickmodule. You can use that to point to correct lldb.py: 750061da546Spatrick 751061da546SpatrickFor csh and tcsh: 752061da546Spatrick 753061da546Spatrick:: 754061da546Spatrick 755061da546Spatrick % setenv PYTHONPATH `lldb -P` 756061da546Spatrick 757061da546SpatrickFor sh and bash: 758061da546Spatrick 759061da546Spatrick:: 760061da546Spatrick 761*f6aab3d8Srobert $ export PYTHONPATH=`lldb -P` 762061da546Spatrick 763061da546SpatrickAlternately, you can append the LLDB Python directory to the sys.path list 764061da546Spatrickdirectly in your Python code before importing the lldb module. 765061da546Spatrick 766061da546SpatrickNow your python scripts are ready to import the lldb module. Below is a python 767061da546Spatrickscript that will launch a program from the current working directory called 768061da546Spatrick"a.out", set a breakpoint at "main", and then run and hit the breakpoint, and 769061da546Spatrickprint the process, thread and frame objects if the process stopped: 770061da546Spatrick 771061da546Spatrick:: 772061da546Spatrick 773be691f3bSpatrick #!/usr/bin/env python 774061da546Spatrick 775061da546Spatrick import lldb 776061da546Spatrick import os 777061da546Spatrick 778061da546Spatrick def disassemble_instructions(insts): 779061da546Spatrick for i in insts: 780061da546Spatrick print i 781061da546Spatrick 782061da546Spatrick # Set the path to the executable to debug 783061da546Spatrick exe = "./a.out" 784061da546Spatrick 785061da546Spatrick # Create a new debugger instance 786061da546Spatrick debugger = lldb.SBDebugger.Create() 787061da546Spatrick 788061da546Spatrick # When we step or continue, don't return from the function until the process 789061da546Spatrick # stops. Otherwise we would have to handle the process events ourselves which, while doable is 790061da546Spatrick #a little tricky. We do this by setting the async mode to false. 791061da546Spatrick debugger.SetAsync (False) 792061da546Spatrick 793061da546Spatrick # Create a target from a file and arch 794061da546Spatrick print "Creating a target for '%s'" % exe 795061da546Spatrick 796061da546Spatrick target = debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT) 797061da546Spatrick 798061da546Spatrick if target: 799061da546Spatrick # If the target is valid set a breakpoint at main 800061da546Spatrick main_bp = target.BreakpointCreateByName ("main", target.GetExecutable().GetFilename()); 801061da546Spatrick 802061da546Spatrick print main_bp 803061da546Spatrick 804061da546Spatrick # Launch the process. Since we specified synchronous mode, we won't return 805061da546Spatrick # from this function until we hit the breakpoint at main 806061da546Spatrick process = target.LaunchSimple (None, None, os.getcwd()) 807061da546Spatrick 808061da546Spatrick # Make sure the launch went ok 809061da546Spatrick if process: 810061da546Spatrick # Print some simple process info 811061da546Spatrick state = process.GetState () 812061da546Spatrick print process 813061da546Spatrick if state == lldb.eStateStopped: 814061da546Spatrick # Get the first thread 815061da546Spatrick thread = process.GetThreadAtIndex (0) 816061da546Spatrick if thread: 817061da546Spatrick # Print some simple thread info 818061da546Spatrick print thread 819061da546Spatrick # Get the first frame 820061da546Spatrick frame = thread.GetFrameAtIndex (0) 821061da546Spatrick if frame: 822061da546Spatrick # Print some simple frame info 823061da546Spatrick print frame 824061da546Spatrick function = frame.GetFunction() 825061da546Spatrick # See if we have debug info (a function) 826061da546Spatrick if function: 827061da546Spatrick # We do have a function, print some info for the function 828061da546Spatrick print function 829061da546Spatrick # Now get all instructions for this function and print them 830061da546Spatrick insts = function.GetInstructions(target) 831061da546Spatrick disassemble_instructions (insts) 832061da546Spatrick else: 833061da546Spatrick # See if we have a symbol in the symbol table for where we stopped 834061da546Spatrick symbol = frame.GetSymbol(); 835061da546Spatrick if symbol: 836061da546Spatrick # We do have a symbol, print some info for the symbol 837061da546Spatrick print symbol 838061da546Spatrick 839061da546SpatrickWriting lldb frame recognizers in Python 840061da546Spatrick---------------------------------------- 841061da546Spatrick 842061da546SpatrickFrame recognizers allow for retrieving information about special frames based 843061da546Spatrickon ABI, arguments or other special properties of that frame, even without 844061da546Spatricksource code or debug info. Currently, one use case is to extract function 845be691f3bSpatrickarguments that would otherwise be inaccessible, or augment existing arguments. 846061da546Spatrick 847061da546SpatrickAdding a custom frame recognizer is done by implementing a Python class and 848061da546Spatrickusing the 'frame recognizer add' command. The Python class should have a 849061da546Spatrick'get_recognized_arguments' method and it will receive an argument of type 850061da546Spatricklldb.SBFrame representing the current frame that we are trying to recognize. 851061da546SpatrickThe method should return a (possibly empty) list of lldb.SBValue objects that 852061da546Spatrickrepresent the recognized arguments. 853061da546Spatrick 854061da546SpatrickAn example of a recognizer that retrieves the file descriptor values from libc 855061da546Spatrickfunctions 'read', 'write' and 'close' follows: 856061da546Spatrick 857061da546Spatrick:: 858061da546Spatrick 859061da546Spatrick class LibcFdRecognizer(object): 860061da546Spatrick def get_recognized_arguments(self, frame): 861061da546Spatrick if frame.name in ["read", "write", "close"]: 862061da546Spatrick fd = frame.EvaluateExpression("$arg1").unsigned 863*f6aab3d8Srobert target = frame.thread.process.target 864*f6aab3d8Srobert value = target.CreateValueFromExpression("fd", "(int)%d" % fd) 865061da546Spatrick return [value] 866061da546Spatrick return [] 867061da546Spatrick 868be691f3bSpatrickThe file containing this implementation can be imported via ``command script import`` 869be691f3bSpatrickand then we can register this recognizer with ``frame recognizer add``. 870061da546SpatrickIt's important to restrict the recognizer to the libc library (which is 871061da546Spatricklibsystem_kernel.dylib on macOS) to avoid matching functions with the same name 872061da546Spatrickin other modules: 873061da546Spatrick 874061da546Spatrick:: 875061da546Spatrick 876061da546Spatrick (lldb) command script import .../fd_recognizer.py 877061da546Spatrick (lldb) frame recognizer add -l fd_recognizer.LibcFdRecognizer -n read -s libsystem_kernel.dylib 878061da546Spatrick 879061da546SpatrickWhen the program is stopped at the beginning of the 'read' function in libc, we can view the recognizer arguments in 'frame variable': 880061da546Spatrick 881061da546Spatrick:: 882061da546Spatrick 883061da546Spatrick (lldb) b read 884061da546Spatrick (lldb) r 885061da546Spatrick Process 1234 stopped 886061da546Spatrick * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.3 887061da546Spatrick frame #0: 0x00007fff06013ca0 libsystem_kernel.dylib`read 888061da546Spatrick (lldb) frame variable 889061da546Spatrick (int) fd = 3 890be691f3bSpatrick 891be691f3bSpatrickWriting Target Stop-Hooks in Python: 892be691f3bSpatrick------------------------------------ 893be691f3bSpatrick 894be691f3bSpatrickStop hooks fire whenever the process stops just before control is returned to the 895be691f3bSpatrickuser. Stop hooks can either be a set of lldb command-line commands, or can 896be691f3bSpatrickbe implemented by a suitably defined Python class. The Python based stop-hooks 897be691f3bSpatrickcan also be passed as set of -key -value pairs when they are added, and those 898be691f3bSpatrickwill get packaged up into a SBStructuredData Dictionary and passed to the 899be691f3bSpatrickconstructor of the Python object managing the stop hook. This allows for 900be691f3bSpatrickparametrization of the stop hooks. 901be691f3bSpatrick 902be691f3bSpatrickTo add a Python-based stop hook, first define a class with the following methods: 903be691f3bSpatrick 904be691f3bSpatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 905be691f3bSpatrick| Name | Arguments | Description | 906be691f3bSpatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 907be691f3bSpatrick| ``__init__`` | ``target: lldb.SBTarget`` | This is the constructor for the new stop-hook. | 908be691f3bSpatrick| | ``extra_args: lldb.SBStructuredData`` | | 909be691f3bSpatrick| | | | 910be691f3bSpatrick| | | ``target`` is the SBTarget to which the stop hook is added. | 911be691f3bSpatrick| | | | 912be691f3bSpatrick| | | ``extra_args`` is an SBStructuredData object that the user can pass in when creating instances of this | 913be691f3bSpatrick| | | breakpoint. It is not required, but allows for reuse of stop-hook classes. | 914be691f3bSpatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 915be691f3bSpatrick| ``handle_stop`` | ``exe_ctx: lldb.SBExecutionContext`` | This is the called when the target stops. | 916be691f3bSpatrick| | ``stream: lldb.SBStream`` | | 917be691f3bSpatrick| | | ``exe_ctx`` argument will be filled with the current stop point for which the stop hook is | 918be691f3bSpatrick| | | being evaluated. | 919be691f3bSpatrick| | | | 920be691f3bSpatrick| | | ``stream`` an lldb.SBStream, anything written to this stream will be written to the debugger console. | 921be691f3bSpatrick| | | | 922be691f3bSpatrick| | | The return value is a "Should Stop" vote from this thread. If the method returns either True or no return | 923be691f3bSpatrick| | | this thread votes to stop. If it returns False, then the thread votes to continue after all the stop-hooks | 924be691f3bSpatrick| | | are evaluated. | 925be691f3bSpatrick| | | Note, the --auto-continue flag to 'target stop-hook add' overrides a True return value from the method. | 926be691f3bSpatrick+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 927be691f3bSpatrick 928be691f3bSpatrickTo use this class in lldb, run the command: 929be691f3bSpatrick 930be691f3bSpatrick:: 931be691f3bSpatrick 932be691f3bSpatrick (lldb) command script import MyModule.py 933be691f3bSpatrick (lldb) target stop-hook add -P MyModule.MyStopHook -k first -v 1 -k second -v 2 934be691f3bSpatrick 935be691f3bSpatrickwhere MyModule.py is the file containing the class definition MyStopHook. 936