17b844849SJonas DevliegherePython Reference 27b844849SJonas Devlieghere================ 37b844849SJonas Devlieghere 47b844849SJonas DevlieghereThe entire LLDB API is available as Python functions through a script bridging 57b844849SJonas Devlieghereinterface. This means the LLDB API's can be used directly from python either 67b844849SJonas Devlieghereinteractively or to build python apps that provide debugger features. 77b844849SJonas Devlieghere 87b844849SJonas DevlieghereAdditionally, Python can be used as a programmatic interface within the lldb 97b844849SJonas Devliegherecommand interpreter (we refer to this for brevity as the embedded interpreter). 107b844849SJonas DevlieghereOf course, in this context it has full access to the LLDB API - with some 117b844849SJonas Devlieghereadditional conveniences we will call out in the FAQ. 127b844849SJonas Devlieghere 137b844849SJonas Devlieghere.. contents:: 147b844849SJonas Devlieghere :local: 157b844849SJonas Devlieghere 167b844849SJonas DevlieghereDocumentation 177b844849SJonas Devlieghere-------------- 187b844849SJonas Devlieghere 197b844849SJonas DevlieghereThe LLDB API is contained in a python module named lldb. A useful resource when 207b844849SJonas Devliegherewriting Python extensions is the lldb Python classes reference guide. 217b844849SJonas Devlieghere 227b844849SJonas DevlieghereThe documentation is also accessible in an interactive debugger session with 237b844849SJonas Devliegherethe following command: 247b844849SJonas Devlieghere 257b844849SJonas Devlieghere:: 267b844849SJonas Devlieghere 277b844849SJonas Devlieghere (lldb) script help(lldb) 287b844849SJonas Devlieghere Help on package lldb: 297b844849SJonas Devlieghere 307b844849SJonas Devlieghere NAME 317b844849SJonas Devlieghere lldb - The lldb module contains the public APIs for Python binding. 327b844849SJonas Devlieghere 337b844849SJonas Devlieghere FILE 347b844849SJonas Devlieghere /System/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/__init__.py 357b844849SJonas Devlieghere 367b844849SJonas Devlieghere DESCRIPTION 377b844849SJonas Devlieghere ... 387b844849SJonas Devlieghere 397b844849SJonas DevlieghereYou can also get help using a module class name. The full API that is exposed 407b844849SJonas Devliegherefor that class will be displayed in a man page style window. Below we want to 417b844849SJonas Devlieghereget help on the lldb.SBFrame class: 427b844849SJonas Devlieghere 437b844849SJonas Devlieghere:: 447b844849SJonas Devlieghere 457b844849SJonas Devlieghere (lldb) script help(lldb.SBFrame) 467b844849SJonas Devlieghere Help on class SBFrame in module lldb: 477b844849SJonas Devlieghere 487b844849SJonas Devlieghere class SBFrame(__builtin__.object) 497b844849SJonas Devlieghere | Represents one of the stack frames associated with a thread. 507b844849SJonas Devlieghere | SBThread contains SBFrame(s). For example (from test/lldbutil.py), 517b844849SJonas Devlieghere | 527b844849SJonas Devlieghere | def print_stacktrace(thread, string_buffer = False): 537b844849SJonas Devlieghere | '''Prints a simple stack trace of this thread.''' 547b844849SJonas Devlieghere | 557b844849SJonas Devlieghere ... 567b844849SJonas Devlieghere 577b844849SJonas DevlieghereOr you can get help using any python object, here we use the lldb.process 587b844849SJonas Devlieghereobject which is a global variable in the lldb module which represents the 597b844849SJonas Devliegherecurrently selected process: 607b844849SJonas Devlieghere 617b844849SJonas Devlieghere:: 627b844849SJonas Devlieghere 637b844849SJonas Devlieghere (lldb) script help(lldb.process) 647b844849SJonas Devlieghere Help on SBProcess in module lldb object: 657b844849SJonas Devlieghere 667b844849SJonas Devlieghere class SBProcess(__builtin__.object) 677b844849SJonas Devlieghere | Represents the process associated with the target program. 687b844849SJonas Devlieghere | 697b844849SJonas Devlieghere | SBProcess supports thread iteration. For example (from test/lldbutil.py), 707b844849SJonas Devlieghere | 717b844849SJonas Devlieghere | # ================================================== 727b844849SJonas Devlieghere | # Utility functions related to Threads and Processes 737b844849SJonas Devlieghere | # ================================================== 747b844849SJonas Devlieghere | 757b844849SJonas Devlieghere ... 767b844849SJonas Devlieghere 777b844849SJonas DevlieghereEmbedded Python Interpreter 787b844849SJonas Devlieghere--------------------------- 797b844849SJonas Devlieghere 807b844849SJonas DevlieghereThe embedded python interpreter can be accessed in a variety of ways from 817b844849SJonas Devliegherewithin LLDB. The easiest way is to use the lldb command script with no 827b844849SJonas Devliegherearguments at the lldb command prompt: 837b844849SJonas Devlieghere 847b844849SJonas Devlieghere:: 857b844849SJonas Devlieghere 867b844849SJonas Devlieghere (lldb) script 877b844849SJonas Devlieghere Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D. 887b844849SJonas Devlieghere >>> 2+3 897b844849SJonas Devlieghere 5 907b844849SJonas Devlieghere >>> hex(12345) 917b844849SJonas Devlieghere '0x3039' 927b844849SJonas Devlieghere >>> 937b844849SJonas Devlieghere 947b844849SJonas DevlieghereThis drops you into the embedded python interpreter. When running under the 957b844849SJonas Devliegherescript command, lldb sets some convenience variables that give you quick access 967b844849SJonas Devlieghereto the currently selected entities that characterize the program and debugger 977b844849SJonas Devliegherestate. In each case, if there is no currently selected entity of the 987b844849SJonas Devlieghereappropriate type, the variable's IsValid method will return false. These 997b844849SJonas Devliegherevariables are: 1007b844849SJonas Devlieghere 101f46a441bSJonas Devlieghere+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 102f46a441bSJonas Devlieghere| Variable | Type | Equivalent | Description | 103f46a441bSJonas Devlieghere+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 10451ab17b9SRaphael Isemann| ``lldb.debugger`` | `lldb.SBDebugger` | `SBTarget.GetDebugger` | Contains the debugger object whose ``script`` command was invoked. | 105f46a441bSJonas Devlieghere| | | | The `lldb.SBDebugger` object owns the command interpreter | 106f46a441bSJonas Devlieghere| | | | and all the targets in your debug session. There will always be a | 107f46a441bSJonas Devlieghere| | | | Debugger in the embedded interpreter. | 108f46a441bSJonas Devlieghere+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 10951ab17b9SRaphael Isemann| ``lldb.target`` | `lldb.SBTarget` | `SBDebugger.GetSelectedTarget` | Contains the currently selected target - for instance the one made with the | 11051ab17b9SRaphael Isemann| | | | ``file`` or selected by the ``target select <target-index>`` command. | 111f46a441bSJonas Devlieghere| | | `SBProcess.GetTarget` | The `lldb.SBTarget` manages one running process, and all the executable | 112f46a441bSJonas Devlieghere| | | | and debug files for the process. | 113f46a441bSJonas Devlieghere+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 11451ab17b9SRaphael Isemann| ``lldb.process`` | `lldb.SBProcess` | `SBTarget.GetProcess` | Contains the process of the currently selected target. | 115f46a441bSJonas Devlieghere| | | | The `lldb.SBProcess` object manages the threads and allows access to | 116f46a441bSJonas Devlieghere| | | `SBThread.GetProcess` | memory for the process. | 117f46a441bSJonas Devlieghere+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 11851ab17b9SRaphael Isemann| ``lldb.thread`` | `lldb.SBThread` | `SBProcess.GetSelectedThread` | Contains the currently selected thread. | 119f46a441bSJonas Devlieghere| | | | The `lldb.SBThread` object manages the stack frames in that thread. | 120f46a441bSJonas Devlieghere| | | `SBFrame.GetThread` | A thread is always selected in the command interpreter when a target stops. | 12151ab17b9SRaphael Isemann| | | | The ``thread select <thread-index>`` command can be used to change the | 122f46a441bSJonas Devlieghere| | | | currently selected thread. So as long as you have a stopped process, there will be | 123f46a441bSJonas Devlieghere| | | | some selected thread. | 124f46a441bSJonas Devlieghere+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 12551ab17b9SRaphael Isemann| ``lldb.frame`` | `lldb.SBFrame` | `SBThread.GetSelectedFrame` | Contains the currently selected stack frame. | 126f46a441bSJonas Devlieghere| | | | The `lldb.SBFrame` object manage the stack locals and the register set for | 127f46a441bSJonas Devlieghere| | | | that stack. | 128f46a441bSJonas Devlieghere| | | | A stack frame is always selected in the command interpreter when a target stops. | 12951ab17b9SRaphael Isemann| | | | The ``frame select <frame-index>`` command can be used to change the | 130f46a441bSJonas Devlieghere| | | | currently selected frame. So as long as you have a stopped process, there will | 131f46a441bSJonas Devlieghere| | | | be some selected frame. | 132f46a441bSJonas Devlieghere+-------------------+---------------------+-------------------------------------+-------------------------------------------------------------------------------------+ 1337b844849SJonas Devlieghere 1347b844849SJonas DevlieghereWhile extremely convenient, these variables have a couple caveats that you 1357b844849SJonas Devlieghereshould be aware of. First of all, they hold the values of the selected objects 1367b844849SJonas Devlieghereon entry to the embedded interpreter. They do not update as you use the LLDB 1377b844849SJonas DevlieghereAPI's to change, for example, the currently selected stack frame or thread. 1387b844849SJonas Devlieghere 1397b844849SJonas DevlieghereMoreover, they are only defined and meaningful while in the interactive Python 1407b844849SJonas Devlieghereinterpreter. There is no guarantee on their value in any other situation, hence 1417b844849SJonas Devlieghereyou should not use them when defining Python formatters, breakpoint scripts and 142f46a441bSJonas Devliegherecommands (or any other Python extension point that LLDB provides). For the 143f46a441bSJonas Devliegherelatter you'll be passed an `SBDebugger`, `SBTarget`, `SBProcess`, `SBThread` or 14451ab17b9SRaphael Isemann`SBFrame` instance and you can use the functions from the "Equivalent" column 145f46a441bSJonas Devlieghereto navigate between them. 146f46a441bSJonas Devlieghere 147f46a441bSJonas DevlieghereAs a rationale for such behavior, consider that lldb can run in a multithreaded 1487b844849SJonas Devlieghereenvironment, and another thread might call the "script" command, changing the 1497b844849SJonas Devliegherevalue out from under you. 1507b844849SJonas Devlieghere 1517b844849SJonas DevlieghereTo get started with these objects and LLDB scripting, please note that almost 1527b844849SJonas Devlieghereall of the lldb Python objects are able to briefly describe themselves when you 1537b844849SJonas Devliegherepass them to the Python print function: 1547b844849SJonas Devlieghere 1557b844849SJonas Devlieghere:: 1567b844849SJonas Devlieghere 1577b844849SJonas Devlieghere (lldb) script 1587b844849SJonas Devlieghere Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D. 1597b844849SJonas Devlieghere >>> print lldb.debugger 1607b844849SJonas Devlieghere Debugger (instance: "debugger_1", id: 1) 1617b844849SJonas Devlieghere >>> print lldb.target 1627b844849SJonas Devlieghere a.out 1637b844849SJonas Devlieghere >>> print lldb.process 1647b844849SJonas Devlieghere SBProcess: pid = 59289, state = stopped, threads = 1, executable = a.out 1657b844849SJonas Devlieghere >>> print lldb.thread 1667b844849SJonas Devlieghere SBThread: tid = 0x1f03 1677b844849SJonas Devlieghere >>> print lldb.frame 1687b844849SJonas Devlieghere frame #0: 0x0000000100000bb6 a.out main + 54 at main.c:16 1697b844849SJonas Devlieghere 1707b844849SJonas Devlieghere 1717b844849SJonas DevlieghereRunning a python script when a breakpoint gets hit 1727b844849SJonas Devlieghere-------------------------------------------------- 1737b844849SJonas Devlieghere 1747b844849SJonas DevlieghereOne very powerful use of the lldb Python API is to have a python script run 1757b844849SJonas Devliegherewhen a breakpoint gets hit. Adding python scripts to breakpoints provides a way 1767b844849SJonas Devlieghereto create complex breakpoint conditions and also allows for smart logging and 1777b844849SJonas Devliegheredata gathering. 1787b844849SJonas Devlieghere 1797b844849SJonas DevlieghereWhen your process hits a breakpoint to which you have attached some python 1807b844849SJonas Devliegherecode, the code is executed as the body of a function which takes three 1817b844849SJonas Devliegherearguments: 1827b844849SJonas Devlieghere 1837b844849SJonas Devlieghere:: 1847b844849SJonas Devlieghere 185483ec136SJim Ingham def breakpoint_function_wrapper(frame, bp_loc, internal_dict): 1867b844849SJonas Devlieghere # Your code goes here 1877b844849SJonas Devlieghere 188365b186cSJim Inghamor: 1897b844849SJonas Devlieghere 190365b186cSJim Ingham:: 191365b186cSJim Ingham 192483ec136SJim Ingham def breakpoint_function_wrapper(frame, bp_loc, extra_args, internal_dict): 193365b186cSJim Ingham # Your code goes here 194365b186cSJim Ingham 195365b186cSJim Ingham 196483ec136SJim Ingham+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 1977b844849SJonas Devlieghere| Argument | Type | Description | 198483ec136SJim Ingham+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 19951ab17b9SRaphael Isemann| ``frame`` | `lldb.SBFrame` | The current stack frame where the breakpoint got hit. | 2007b844849SJonas Devlieghere| | | The object will always be valid. | 20151ab17b9SRaphael Isemann| | | This ``frame`` argument might *not* match the currently selected stack frame found in the `lldb` module global variable ``lldb.frame``. | 202483ec136SJim Ingham+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 20351ab17b9SRaphael Isemann| ``bp_loc`` | `lldb.SBBreakpointLocation` | The breakpoint location that just got hit. Breakpoints are represented by `lldb.SBBreakpoint` | 2047b844849SJonas Devlieghere| | | objects. These breakpoint objects can have one or more locations. These locations | 205f46a441bSJonas Devlieghere| | | are represented by `lldb.SBBreakpointLocation` objects. | 206483ec136SJim Ingham+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 20751ab17b9SRaphael Isemann| ``extra_args`` | `lldb.SBStructuredData` | ``Optional`` If your breakpoint callback function takes this extra parameter, then when the callback gets added to a breakpoint, its | 208365b186cSJim Ingham| | | contents can parametrize this use of the callback. For instance, instead of writing a callback that stops when the caller is "Foo", | 20951ab17b9SRaphael Isemann| | | you could take the function name from a field in the ``extra_args``, making the callback more general. The ``-k`` and ``-v`` options | 21051ab17b9SRaphael Isemann| | | 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. | 211483ec136SJim Ingham+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 21251ab17b9SRaphael Isemann| ``internal_dict`` | ``dict`` | The python session dictionary as a standard python dictionary object. | 213483ec136SJim Ingham+-------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ 2147b844849SJonas Devlieghere 2157b844849SJonas DevlieghereOptionally, a Python breakpoint command can return a value. Returning False 2167b844849SJonas Devliegheretells LLDB that you do not want to stop at the breakpoint. Any other return 2177b844849SJonas Devliegherevalue (including None or leaving out the return statement altogether) is akin 2187b844849SJonas Devlieghereto telling LLDB to actually stop at the breakpoint. This can be useful in 2197b844849SJonas Devliegheresituations where a breakpoint only needs to stop the process when certain 2207b844849SJonas Devlieghereconditions are met, and you do not want to inspect the program state manually 2217b844849SJonas Devlieghereat every stop and then continue. 2227b844849SJonas Devlieghere 2237b844849SJonas DevlieghereAn example will show how simple it is to write some python code and attach it 2247b844849SJonas Devlieghereto a breakpoint. The following example will allow you to track the order in 2257b844849SJonas Devliegherewhich the functions in a given shared library are first executed during one run 2267b844849SJonas Devlieghereof your program. This is a simple method to gather an order file which can be 2277b844849SJonas Devlieghereused to optimize function placement within a binary for execution locality. 2287b844849SJonas Devlieghere 2297b844849SJonas DevlieghereWe do this by setting a regular expression breakpoint that will match every 2307b844849SJonas Devliegherefunction in the shared library. The regular expression '.' will match any 2317b844849SJonas Devliegherestring that has at least one character in it, so we will use that. This will 2327b844849SJonas Devlieghereresult in one lldb.SBBreakpoint object that contains an 2337b844849SJonas Devliegherelldb.SBBreakpointLocation object for each function. As the breakpoint gets hit, 2347b844849SJonas Devliegherewe use a counter to track the order in which the function at this particular 2357b844849SJonas Devliegherebreakpoint location got hit. Since our code is passed the location that was 2367b844849SJonas Devliegherehit, we can get the name of the function from the location, disable the 2377b844849SJonas Devliegherelocation so we won't count this function again; then log some info and continue 2387b844849SJonas Devliegherethe process. 2397b844849SJonas Devlieghere 2407b844849SJonas DevlieghereNote we also have to initialize our counter, which we do with the simple 2417b844849SJonas Devlieghereone-line version of the script command. 2427b844849SJonas Devlieghere 2437b844849SJonas DevlieghereHere is the code: 2447b844849SJonas Devlieghere 2457b844849SJonas Devlieghere:: 2467b844849SJonas Devlieghere 2477b844849SJonas Devlieghere (lldb) breakpoint set --func-regex=. --shlib=libfoo.dylib 2487b844849SJonas Devlieghere Breakpoint created: 1: regex = '.', module = libfoo.dylib, locations = 223 2497b844849SJonas Devlieghere (lldb) script counter = 0 2507b844849SJonas Devlieghere (lldb) breakpoint command add --script-type python 1 2517b844849SJonas Devlieghere Enter your Python command(s). Type 'DONE' to end. 2527b844849SJonas Devlieghere > # Increment our counter. Since we are in a function, this must be a global python variable 2537b844849SJonas Devlieghere > global counter 2547b844849SJonas Devlieghere > counter += 1 2557b844849SJonas Devlieghere > # Get the name of the function 2567b844849SJonas Devlieghere > name = frame.GetFunctionName() 2577b844849SJonas Devlieghere > # Print the order and the function name 2587b844849SJonas Devlieghere > print '[%i] %s' % (counter, name) 2597b844849SJonas Devlieghere > # Disable the current breakpoint location so it doesn't get hit again 2607b844849SJonas Devlieghere > bp_loc.SetEnabled(False) 2617b844849SJonas Devlieghere > # No need to stop here 2627b844849SJonas Devlieghere > return False 2637b844849SJonas Devlieghere > DONE 2647b844849SJonas Devlieghere 2657b844849SJonas DevlieghereThe breakpoint command add command above attaches a python script to breakpoint 1. To remove the breakpoint command: 2667b844849SJonas Devlieghere 2677b844849SJonas Devlieghere:: 2687b844849SJonas Devlieghere 2697b844849SJonas Devlieghere (lldb) breakpoint command delete 1 2707b844849SJonas Devlieghere 2717b844849SJonas Devlieghere 2727b844849SJonas DevlieghereUsing the python api's to create custom breakpoints 2737b844849SJonas Devlieghere--------------------------------------------------- 2747b844849SJonas Devlieghere 2757b844849SJonas Devlieghere 2767b844849SJonas DevlieghereAnother use of the Python API's in lldb is to create a custom breakpoint 2777b844849SJonas Devlieghereresolver. This facility was added in r342259. 2787b844849SJonas Devlieghere 2797b844849SJonas DevlieghereIt allows you to provide the algorithm which will be used in the breakpoint's 2807b844849SJonas Devliegheresearch of the space of the code in a given Target to determine where to set the 2817b844849SJonas Devliegherebreakpoint locations - the actual places where the breakpoint will trigger. To 2827b844849SJonas Devlieghereunderstand how this works you need to know a little about how lldb handles 2837b844849SJonas Devliegherebreakpoints. 2847b844849SJonas Devlieghere 2857b844849SJonas DevlieghereIn lldb, a breakpoint is composed of three parts: the Searcher, the Resolver, 2867b844849SJonas Devlieghereand the Stop Options. The Searcher and Resolver cooperate to determine how 2877b844849SJonas Devliegherebreakpoint locations are set and differ between each breakpoint type. Stop 2887b844849SJonas Devlieghereoptions determine what happens when a location triggers and includes the 2897b844849SJonas Devliegherecommands, conditions, ignore counts, etc. Stop options are common between all 2907b844849SJonas Devliegherebreakpoint types, so for our purposes only the Searcher and Resolver are 2917b844849SJonas Devlieghererelevant. 2927b844849SJonas Devlieghere 2937b844849SJonas DevlieghereThe Searcher's job is to traverse in a structured way the code in the current 2947b844849SJonas Devliegheretarget. It proceeds from the Target, to search all the Modules in the Target, 2957b844849SJonas Devliegherein each Module it can recurse into the Compile Units in that module, and within 2967b844849SJonas Devlieghereeach Compile Unit it can recurse over the Functions it contains. 2977b844849SJonas Devlieghere 2987b844849SJonas DevlieghereThe Searcher can be provided with a SearchFilter that it will use to restrict 2997b844849SJonas Devliegherethis search. For instance, if the SearchFilter specifies a list of Modules, the 3007b844849SJonas DevlieghereSearcher will not recurse into Modules that aren't on the list. When you pass 3017b844849SJonas Devliegherethe -s modulename flag to break set you are creating a Module-based search 3027b844849SJonas Devliegherefilter. When you pass -f filename.c to break set -n you are creating a file 3037b844849SJonas Devliegherebased search filter. If neither of these is specified, the breakpoint will have 3047b844849SJonas Devliegherea no-op search filter, so all parts of the program are searched and all 3057b844849SJonas Devliegherelocations accepted. 3067b844849SJonas Devlieghere 3077b844849SJonas DevlieghereThe Resolver has two functions. The most important one is the callback it 3087b844849SJonas Devlieghereprovides. This will get called at the appropriate time in the course of the 3097b844849SJonas Devliegheresearch. The callback is where the job of adding locations to the breakpoint 3107b844849SJonas Devliegheregets done. 3117b844849SJonas Devlieghere 3127b844849SJonas DevlieghereThe other function is specifying to the Searcher at what depth in the above 3137b844849SJonas Devliegheredescribed recursion it wants to be called. Setting a search depth also provides 3147b844849SJonas Devliegherea stop for the recursion. For instance, if you request a Module depth search, 3157b844849SJonas Devliegherethen the callback will be called for each Module as it gets added to the 3167b844849SJonas DevlieghereTarget, but the searcher will not recurse into the Compile Units in the module. 3177b844849SJonas Devlieghere 31836597e47SBruce MitchenerOne other slight subtlety is that the depth at which you get called back is not 31936597e47SBruce Mitchenernecessarily the depth at which the SearchFilter is specified. For instance, 3207b844849SJonas Devlieghereif you are doing symbol searches, it is convenient to use the Module depth for 3217b844849SJonas Devliegherethe search, since symbols are stored in the module. But the SearchFilter might 3227b844849SJonas Devliegherespecify some subset of CompileUnits, so not all the symbols you might find in 3237b844849SJonas Devlieghereeach module will pass the search. You don't need to handle this situation 3247b844849SJonas Devlieghereyourself, since SBBreakpoint::AddLocation will only add locations that pass the 3257b844849SJonas DevlieghereSearch Filter. This API returns an SBError to inform you whether your location 3267b844849SJonas Devliegherewas added. 3277b844849SJonas Devlieghere 3287b844849SJonas DevlieghereWhen the breakpoint is originally created, its Searcher will process all the 3297b844849SJonas Devliegherecurrently loaded modules. The Searcher will also visit any new modules as they 3307b844849SJonas Devlieghereare added to the target. This happens, for instance, when a new shared library 3317b844849SJonas Devliegheregets added to the target in the course of running, or on rerunning if any of 3327b844849SJonas Devliegherethe currently loaded modules have been changed. Note, in the latter case, all 3337b844849SJonas Devliegherethe locations set in the old module will get deleted and you will be asked to 3347b844849SJonas Devlieghererecreate them in the new version of the module when your callback gets called 3357b844849SJonas Devliegherewith that module. For this reason, you shouldn't try to manage the locations 3367b844849SJonas Devlieghereyou add to the breakpoint yourself. Note that the Breakpoint takes care of 3377b844849SJonas Devliegherededuplicating equal addresses in AddLocation, so you shouldn't need to worry 3387b844849SJonas Devlieghereabout that anyway. 3397b844849SJonas Devlieghere 3407b844849SJonas DevlieghereAt present, when adding a scripted Breakpoint type, you can only provide a 3417b844849SJonas Devliegherecustom Resolver, not a custom SearchFilter. 3427b844849SJonas Devlieghere 3437b844849SJonas DevlieghereThe custom Resolver is provided as a Python class with the following methods: 3447b844849SJonas Devlieghere 3452f67cbb6SJonas Devlieghere+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 3467b844849SJonas Devlieghere| Name | Arguments | Description | 3472f67cbb6SJonas Devlieghere+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 34851ab17b9SRaphael Isemann| ``__init__`` | ``bkpt``:`lldb.SBBreakpoint` | This is the constructor for the new Resolver. | 34951ab17b9SRaphael Isemann| | ``extra_args``:`lldb.SBStructuredData`| | 3507b844849SJonas Devlieghere| | | | 35151ab17b9SRaphael Isemann| | | ``bkpt`` is the breakpoint owning this Resolver. | 3527b844849SJonas Devlieghere| | | | 3537b844849SJonas Devlieghere| | | | 35451ab17b9SRaphael Isemann| | | ``extra_args`` is an `SBStructuredData` object that the user can pass in when creating instances of this | 3557b844849SJonas Devlieghere| | | breakpoint. It is not required, but is quite handy. For instance if you were implementing a breakpoint on some | 3567b844849SJonas Devlieghere| | | symbol name, you could write a generic symbol name based Resolver, and then allow the user to pass | 3577b844849SJonas Devlieghere| | | in the particular symbol in the extra_args | 3582f67cbb6SJonas Devlieghere+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 35951ab17b9SRaphael Isemann| ``__callback__`` | ``sym_ctx``:`lldb.SBSymbolContext` | This is the Resolver callback. | 36051ab17b9SRaphael Isemann| | | The ``sym_ctx`` argument will be filled with the current stage | 3617b844849SJonas Devlieghere| | | of the search. | 3627b844849SJonas Devlieghere| | | | 3637b844849SJonas Devlieghere| | | | 3647b844849SJonas Devlieghere| | | For instance, if you asked for a search depth of lldb.eSearchDepthCompUnit, then the | 3657b844849SJonas Devlieghere| | | target, module and compile_unit fields of the sym_ctx will be filled. The callback should look just in the | 36651ab17b9SRaphael Isemann| | | context passed in ``sym_ctx`` for new locations. If the callback finds an address of interest, it | 36751ab17b9SRaphael Isemann| | | can add it to the breakpoint with the `SBBreakpoint.AddLocation` method, using the breakpoint passed | 36851ab17b9SRaphael Isemann| | | in to the ``__init__`` method. | 3692f67cbb6SJonas Devlieghere+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 37051ab17b9SRaphael Isemann| ``__get_depth__`` | ``None`` | Specify the depth at which you wish your callback to get called. The currently supported options are: | 3717b844849SJonas Devlieghere| | | | 37251ab17b9SRaphael Isemann| | | `lldb.eSearchDepthModule` | 37351ab17b9SRaphael Isemann| | | `lldb.eSearchDepthCompUnit` | 37451ab17b9SRaphael Isemann| | | `lldb.eSearchDepthFunction` | 3757b844849SJonas Devlieghere| | | | 3767b844849SJonas Devlieghere| | | For instance, if you are looking | 3777b844849SJonas Devlieghere| | | up symbols, which are stored at the Module level, you will want to get called back module by module. | 378f46a441bSJonas Devlieghere| | | So you would want to return `lldb.eSearchDepthModule`. This method is optional. If not provided the search | 3797b844849SJonas Devlieghere| | | will be done at Module depth. | 3802f67cbb6SJonas Devlieghere+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 38151ab17b9SRaphael Isemann| ``get_short_help` | ``None`` | This is an optional method. If provided, the returned string will be printed at the beginning of | 3827b844849SJonas Devlieghere| | | the description for this breakpoint. | 3832f67cbb6SJonas Devlieghere+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 3847b844849SJonas Devlieghere 3857b844849SJonas DevlieghereTo define a new breakpoint command defined by this class from the lldb command 3867b844849SJonas Devlieghereline, use the command: 3877b844849SJonas Devlieghere 3887b844849SJonas Devlieghere:: 3897b844849SJonas Devlieghere 3907b844849SJonas Devlieghere (lldb) breakpoint set -P MyModule.MyResolverClass 3917b844849SJonas Devlieghere 3927b844849SJonas DevlieghereYou can also populate the extra_args SBStructuredData with a dictionary of 3937b844849SJonas Devliegherekey/value pairs with: 3947b844849SJonas Devlieghere 3957b844849SJonas Devlieghere:: 3967b844849SJonas Devlieghere 3977b844849SJonas Devlieghere (lldb) breakpoint set -P MyModule.MyResolverClass -k key_1 -v value_1 -k key_2 -v value_2 3987b844849SJonas Devlieghere 3997b844849SJonas DevlieghereAlthough you can't write a scripted SearchFilter, both the command line and the 4007b844849SJonas DevlieghereSB API's for adding a scripted resolver allow you to specify a SearchFilter 4017b844849SJonas Devlieghererestricted to certain modules or certain compile units. When using the command 4027b844849SJonas Devlieghereline to create the resolver, you can specify a Module specific SearchFilter by 4037b844849SJonas Devliegherepassing the -s ModuleName option - which can be specified multiple times. You 4047b844849SJonas Devliegherecan also specify a SearchFilter restricted to certain compile units by passing 4057b844849SJonas Devliegherein the -f CompUnitName option. This can also be specified more than once. And 4067b844849SJonas Devlieghereyou can mix the two to specify "this comp unit in this module". So, for 4077b844849SJonas Devlieghereinstance, 4087b844849SJonas Devlieghere 4097b844849SJonas Devlieghere:: 4107b844849SJonas Devlieghere 4117b844849SJonas Devlieghere (lldb) breakpoint set -P MyModule.MyResolverClass -s a.out 4127b844849SJonas Devlieghere 4137b844849SJonas Devliegherewill use your resolver, but will only recurse into or accept new locations in 4147b844849SJonas Devliegherethe module a.out. 4157b844849SJonas Devlieghere 4167b844849SJonas DevlieghereAnother option for creating scripted breakpoints is to use the 4177b844849SJonas DevlieghereSBTarget.CreateBreakpointFromScript API. This one has the advantage that you 4187b844849SJonas Devliegherecan pass in an arbitrary SBStructuredData object, so you can create more 4197b844849SJonas Devliegherecomplex parametrizations. SBStructuredData has a handy SetFromJSON method which 4207b844849SJonas Devlieghereyou can use for this purpose. Your __init__ function gets passed this 4217b844849SJonas DevlieghereSBStructuredData object. This API also allows you to directly provide the list 4227b844849SJonas Devlieghereof Modules and the list of CompileUnits that will make up the SearchFilter. If 4237b844849SJonas Devlieghereyou pass in empty lists, the breakpoint will use the default "search 4247b844849SJonas Devlieghereeverywhere,accept everything" filter. 4257b844849SJonas Devlieghere 4267b844849SJonas DevlieghereUsing the python API' to create custom stepping logic 4277b844849SJonas Devlieghere----------------------------------------------------- 4287b844849SJonas Devlieghere 4297b844849SJonas DevlieghereA slightly esoteric use of the Python API's is to construct custom stepping 4307b844849SJonas Devliegheretypes. LLDB's stepping is driven by a stack of "thread plans" and a fairly 4317b844849SJonas Devliegheresimple state machine that runs the plans. You can create a Python class that 4327b844849SJonas Devlieghereworks as a thread plan, and responds to the requests the state machine makes to 4337b844849SJonas Devlieghererun its operations. 4347b844849SJonas Devlieghere 4357b844849SJonas DevlieghereThere is a longer discussion of scripted thread plans and the state machine, 4367b844849SJonas Devlieghereand several interesting examples of their use in: 4377b844849SJonas Devlieghere 43894fac81fSxguptahttps://github.com/llvm/llvm-project/blob/main/lldb/examples/python/scripted_step.py 4397b844849SJonas Devlieghere 4407b844849SJonas DevlieghereAnd for a MUCH fuller discussion of the whole state machine, see: 4417b844849SJonas Devlieghere 44294fac81fSxguptahttps://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Target/ThreadPlan.h 4437b844849SJonas Devlieghere 4447b844849SJonas DevlieghereIf you are reading those comments it is useful to know that scripted thread 44504cbfa95SQuinn Phamplans are set to be "ControllingPlans", and not "OkayToDiscard". 4467b844849SJonas Devlieghere 4477b844849SJonas DevlieghereTo implement a scripted step, you define a python class that has the following 4487b844849SJonas Devliegheremethods: 4497b844849SJonas Devlieghere 4507b844849SJonas Devlieghere+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 4517b844849SJonas Devlieghere| Name | Arguments | Description | 4527b844849SJonas Devlieghere+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 45351ab17b9SRaphael Isemann| ``__init__`` | ``thread_plan``:`lldb.SBThreadPlan`| This is the underlying `SBThreadPlan` that is pushed onto the plan stack. | 4547b844849SJonas Devlieghere| | | You will want to store this away in an ivar. Also, if you are going to | 4557b844849SJonas Devlieghere| | | use one of the canned thread plans, you can queue it at this point. | 4567b844849SJonas Devlieghere+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 45751ab17b9SRaphael Isemann| ``explains_stop`` | ``event``: `lldb.SBEvent` | Return True if this stop is part of your thread plans logic, false otherwise. | 4587b844849SJonas Devlieghere+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 45951ab17b9SRaphael Isemann| ``is_stale`` | ``None`` | If your plan is no longer relevant (for instance, you were | 4607b844849SJonas Devlieghere| | | stepping in a particular stack frame, but some other operation | 4617b844849SJonas Devlieghere| | | pushed that frame off the stack) return True and your plan will | 4627b844849SJonas Devlieghere| | | get popped. | 4637b844849SJonas Devlieghere+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 46451ab17b9SRaphael Isemann| ``should_step`` | ``None`` | Return ``True`` if you want lldb to instruction step one instruction, | 4657b844849SJonas Devlieghere| | | or False to continue till the next breakpoint is hit. | 4667b844849SJonas Devlieghere+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 46751ab17b9SRaphael Isemann| ``should_stop`` | ``event``: `lldb.SBEvent` | If your plan wants to stop and return control to the user at this point, return True. | 4687b844849SJonas Devlieghere| | | If your plan is done at this point, call SetPlanComplete on your | 4697b844849SJonas Devlieghere| | | thread plan instance. | 4707b844849SJonas Devlieghere| | | Also, do any work you need here to set up the next stage of stepping. | 4717b844849SJonas Devlieghere+-------------------+------------------------------------+---------------------------------------------------------------------------------------+ 4727b844849SJonas Devlieghere 4737b844849SJonas DevlieghereTo use this class to implement a step, use the command: 4747b844849SJonas Devlieghere 4757b844849SJonas Devlieghere:: 4767b844849SJonas Devlieghere 4777b844849SJonas Devlieghere (lldb) thread step-scripted -C MyModule.MyStepPlanClass 4787b844849SJonas Devlieghere 4797b844849SJonas DevlieghereOr use the SBThread.StepUsingScriptedThreadPlan API. The SBThreadPlan passed 4807b844849SJonas Devlieghereinto your __init__ function can also push several common plans (step 4817b844849SJonas Devliegherein/out/over and run-to-address) in front of itself on the stack, which can be 4827b844849SJonas Devlieghereused to compose more complex stepping operations. When you use subsidiary plans 4837b844849SJonas Devlieghereyour explains_stop and should_stop methods won't get called until the 4847b844849SJonas Devliegheresubsidiary plan is done, or the process stops for an event the subsidiary plan 4857b844849SJonas Devliegheredoesn't explain. For instance, step over plans don't explain a breakpoint hit 4867b844849SJonas Devliegherewhile performing the step-over. 4877b844849SJonas Devlieghere 4887b844849SJonas Devlieghere 4897b844849SJonas DevlieghereCreate a new lldb command using a Python function 4907b844849SJonas Devlieghere------------------------------------------------- 4917b844849SJonas Devlieghere 4927b844849SJonas DevliegherePython functions can be used to create new LLDB command interpreter commands, 4937b844849SJonas Devliegherewhich will work like all the natively defined lldb commands. This provides a 4947b844849SJonas Devliegherevery flexible and easy way to extend LLDB to meet your debugging requirements. 4957b844849SJonas Devlieghere 4967b844849SJonas DevlieghereTo write a python function that implements a new LLDB command define the 4977b844849SJonas Devliegherefunction to take four arguments as follows: 4987b844849SJonas Devlieghere 4997b844849SJonas Devlieghere:: 5007b844849SJonas Devlieghere 5017b844849SJonas Devlieghere def command_function(debugger, command, result, internal_dict): 5027b844849SJonas Devlieghere # Your code goes here 5037b844849SJonas Devlieghere 5047b844849SJonas DevlieghereOptionally, you can also provide a Python docstring, and LLDB will use it when providing help for your command, as in: 5057b844849SJonas Devlieghere 5067b844849SJonas Devlieghere:: 5077b844849SJonas Devlieghere 5087b844849SJonas Devlieghere def command_function(debugger, command, result, internal_dict): 5097b844849SJonas Devlieghere """This command takes a lot of options and does many fancy things""" 5107b844849SJonas Devlieghere # Your code goes here 5117b844849SJonas Devlieghere 51290148db0SDave LeeSince lldb 3.5.2, LLDB Python commands can also take an SBExecutionContext as an 51390148db0SDave Leeargument. This is useful in cases where the command's notion of where to act is 51490148db0SDave Leeindependent of the currently-selected entities in the debugger. 5157b844849SJonas Devlieghere 5167b844849SJonas DevlieghereThis feature is enabled if the command-implementing function can be recognized 5177b844849SJonas Devlieghereas taking 5 arguments, or a variable number of arguments, and it alters the 5187b844849SJonas Devliegheresignature as such: 5197b844849SJonas Devlieghere 5207b844849SJonas Devlieghere:: 5217b844849SJonas Devlieghere 5227b844849SJonas Devlieghere def command_function(debugger, command, exe_ctx, result, internal_dict): 5237b844849SJonas Devlieghere # Your code goes here 5247b844849SJonas Devlieghere 5257b844849SJonas Devlieghere+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 5267b844849SJonas Devlieghere| Argument | Type | Description | 5277b844849SJonas Devlieghere+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 52851ab17b9SRaphael Isemann| ``debugger`` | `lldb.SBDebugger` | The current debugger object. | 5297b844849SJonas Devlieghere+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 53051ab17b9SRaphael Isemann| ``command`` | ``python string`` | A python string containing all arguments for your command. If you need to chop up the arguments | 53151ab17b9SRaphael Isemann| | | try using the ``shlex`` module's ``shlex.split(command)`` to properly extract the | 5327b844849SJonas Devlieghere| | | arguments. | 5337b844849SJonas Devlieghere+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 53451ab17b9SRaphael Isemann| ``exe_ctx`` | `lldb.SBExecutionContext` | An execution context object carrying around information on the inferior process' context in which the command is expected to act | 5357b844849SJonas Devlieghere| | | | 53690148db0SDave Lee| | | *Optional since lldb 3.5.2, unavailable before* | 5377b844849SJonas Devlieghere+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 53851ab17b9SRaphael Isemann| ``result`` | `lldb.SBCommandReturnObject` | A return object which encapsulates success/failure information for the command and output text | 5397b844849SJonas Devlieghere| | | that needs to be printed as a result of the command. The plain Python "print" command also works but | 5407b844849SJonas Devlieghere| | | text won't go in the result by default (it is useful as a temporary logging facility). | 5417b844849SJonas Devlieghere+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 54251ab17b9SRaphael Isemann| ``internal_dict`` | ``python dict object`` | The dictionary for the current embedded script session which contains all variables | 5437b844849SJonas Devlieghere| | | and functions. | 5447b844849SJonas Devlieghere+-------------------+--------------------------------+----------------------------------------------------------------------------------------------------------------------------------+ 5457b844849SJonas Devlieghere 54690148db0SDave LeeSince lldb 3.7, Python commands can also be implemented by means of a class 54790148db0SDave Leewhich should implement the following interface: 5487b844849SJonas Devlieghere 5497b844849SJonas Devlieghere:: 5507b844849SJonas Devlieghere 5517b844849SJonas Devlieghere class CommandObjectType: 552483ec136SJim Ingham def __init__(self, debugger, internal_dict): 5537b844849SJonas Devlieghere this call should initialize the command with respect to the command interpreter for the passed-in debugger 5547b844849SJonas Devlieghere def __call__(self, debugger, command, exe_ctx, result): 5557b844849SJonas Devlieghere this is the actual bulk of the command, akin to Python command functions 5567b844849SJonas Devlieghere def get_short_help(self): 5577b844849SJonas Devlieghere this call should return the short help text for this command[1] 5587b844849SJonas Devlieghere def get_long_help(self): 5597b844849SJonas Devlieghere this call should return the long help text for this command[1] 5607b844849SJonas Devlieghere 5617b844849SJonas Devlieghere[1] This method is optional. 5627b844849SJonas Devlieghere 5637b844849SJonas DevlieghereAs a convenience, you can treat the result object as a Python file object, and 5647b844849SJonas Devliegheresay 5657b844849SJonas Devlieghere 5667b844849SJonas Devlieghere:: 5677b844849SJonas Devlieghere 5687b844849SJonas Devlieghere print >>result, "my command does lots of cool stuff" 5697b844849SJonas Devlieghere 5707b844849SJonas DevlieghereSBCommandReturnObject and SBStream both support this file-like behavior by 5717b844849SJonas Devlieghereproviding write() and flush() calls at the Python layer. 5727b844849SJonas Devlieghere 5737b844849SJonas DevlieghereOne other handy convenience when defining lldb command-line commands is the 5747b844849SJonas Devliegherecommand command script import which will import a module specified by file 5757b844849SJonas Devliegherepath, so you don't have to change your PYTHONPATH for temporary scripts. It 5767b844849SJonas Devliegherealso has another convenience that if your new script module has a function of 5777b844849SJonas Devliegherethe form: 5787b844849SJonas Devlieghere 5797b844849SJonas Devlieghere:: 5807b844849SJonas Devlieghere 5817b844849SJonas Devlieghere def __lldb_init_module(debugger, internal_dict): 5827b844849SJonas Devlieghere # Command Initialization code goes here 5837b844849SJonas Devlieghere 5847b844849SJonas Devliegherewhere debugger and internal_dict are as above, that function will get run when 5857b844849SJonas Devliegherethe module is loaded allowing you to add whatever commands you want into the 5867b844849SJonas Devliegherecurrent debugger. Note that this function will only be run when using the LLDB 5871441ffe6SDave Leecommand ``command script import``, it will not get run if anyone imports your 5881441ffe6SDave Leemodule from another module. 5891441ffe6SDave Lee 5901441ffe6SDave LeeThe standard test for ``__main__``, like many python modules do, is useful for 5911441ffe6SDave Leecreating scripts that can be run from the command line. However, for command 5921441ffe6SDave Leeline scripts, the debugger instance must be created manually. Sample code would 5931441ffe6SDave Leelook like: 5947b844849SJonas Devlieghere 5957b844849SJonas Devlieghere:: 5967b844849SJonas Devlieghere 5977b844849SJonas Devlieghere if __name__ == '__main__': 5981441ffe6SDave Lee # Initialize the debugger before making any API calls. 5991441ffe6SDave Lee lldb.SBDebugger.Initialize() 6007b844849SJonas Devlieghere # Create a new debugger instance in your module if your module 6017b844849SJonas Devlieghere # can be run from the command line. When we run a script from 6027b844849SJonas Devlieghere # the command line, we won't have any debugger object in 6037b844849SJonas Devlieghere # lldb.debugger, so we can just create it if it will be needed 6041441ffe6SDave Lee debugger = lldb.SBDebugger.Create() 6051441ffe6SDave Lee 6061441ffe6SDave Lee # Next, do whatever work this module should do when run as a command. 6071441ffe6SDave Lee # ... 6081441ffe6SDave Lee 6091441ffe6SDave Lee # Finally, dispose of the debugger you just made. 6101441ffe6SDave Lee lldb.SBDebugger.Destroy(debugger) 6111441ffe6SDave Lee # Terminate the debug sesssion 6121441ffe6SDave Lee lldb.SBDebugger.Terminate() 6131441ffe6SDave Lee 6147b844849SJonas Devlieghere 6157b844849SJonas DevlieghereNow we can create a module called ls.py in the file ~/ls.py that will implement 6167b844849SJonas Devliegherea function that can be used by LLDB's python command code: 6177b844849SJonas Devlieghere 6187b844849SJonas Devlieghere:: 6197b844849SJonas Devlieghere 620a54f160bSHarmen Stoppels #!/usr/bin/env python 6217b844849SJonas Devlieghere 6227b844849SJonas Devlieghere import lldb 6237b844849SJonas Devlieghere import commands 6247b844849SJonas Devlieghere import optparse 6257b844849SJonas Devlieghere import shlex 6267b844849SJonas Devlieghere 6277b844849SJonas Devlieghere def ls(debugger, command, result, internal_dict): 6287b844849SJonas Devlieghere print >>result, (commands.getoutput('/bin/ls %s' % command)) 6297b844849SJonas Devlieghere 6307b844849SJonas Devlieghere # And the initialization code to add your commands 6317b844849SJonas Devlieghere def __lldb_init_module(debugger, internal_dict): 6327b844849SJonas Devlieghere debugger.HandleCommand('command script add -f ls.ls ls') 6337b844849SJonas Devlieghere print 'The "ls" python command has been installed and is ready for use.' 6347b844849SJonas Devlieghere 6357b844849SJonas DevlieghereNow we can load the module into LLDB and use it 6367b844849SJonas Devlieghere 6377b844849SJonas Devlieghere:: 6387b844849SJonas Devlieghere 63959c954f7SShivam Gupta $ lldb 6407b844849SJonas Devlieghere (lldb) command script import ~/ls.py 6417b844849SJonas Devlieghere The "ls" python command has been installed and is ready for use. 6427b844849SJonas Devlieghere (lldb) ls -l /tmp/ 6437b844849SJonas Devlieghere total 365848 6447b844849SJonas Devlieghere -rw-r--r--@ 1 someuser wheel 6148 Jan 19 17:27 .DS_Store 6457b844849SJonas Devlieghere -rw------- 1 someuser wheel 7331 Jan 19 15:37 crash.log 6467b844849SJonas Devlieghere 647*aa7470a1SJim InghamYou can also make "container" commands to organize the commands you are adding to 648*aa7470a1SJim Inghamlldb. Most of the lldb built-in commands structure themselves this way, and using 649*aa7470a1SJim Inghama tree structure has the benefit of leaving the one-word command space free for user 650*aa7470a1SJim Inghamaliases. It can also make it easier to find commands if you are adding more than 651*aa7470a1SJim Inghama few of them. Here's a trivial example of adding two "utility" commands into a 652*aa7470a1SJim Ingham"my-utilities" container: 653*aa7470a1SJim Ingham 654*aa7470a1SJim Ingham:: 655*aa7470a1SJim Ingham 656*aa7470a1SJim Ingham #!/usr/bin/env python 657*aa7470a1SJim Ingham 658*aa7470a1SJim Ingham import lldb 659*aa7470a1SJim Ingham 660*aa7470a1SJim Ingham def first_utility(debugger, command, result, internal_dict): 661*aa7470a1SJim Ingham print("I am the first utility") 662*aa7470a1SJim Ingham 663*aa7470a1SJim Ingham def second_utility(debugger, command, result, internal_dict): 664*aa7470a1SJim Ingham print("I am the second utility") 665*aa7470a1SJim Ingham 666*aa7470a1SJim Ingham # And the initialization code to add your commands 667*aa7470a1SJim Ingham def __lldb_init_module(debugger, internal_dict): 668*aa7470a1SJim Ingham debugger.HandleCommand('command container add -h "A container for my utilities" my-utilities') 669*aa7470a1SJim Ingham debugger.HandleCommand('command script add -f my_utilities.first_utility -h "My first utility" my-utilities first') 670*aa7470a1SJim Ingham debugger.HandleCommand('command script add -f my_utilities.second_utility -h "My second utility" my-utilities second') 671*aa7470a1SJim Ingham print('The "my-utilities" python command has been installed and its subcommands are ready for use.') 672*aa7470a1SJim Ingham 673*aa7470a1SJim InghamThen your new commands are available under the my-utilities node: 674*aa7470a1SJim Ingham 675*aa7470a1SJim Ingham:: 676*aa7470a1SJim Ingham 677*aa7470a1SJim Ingham (lldb) help my-utilities 678*aa7470a1SJim Ingham A container for my utilities 679*aa7470a1SJim Ingham 680*aa7470a1SJim Ingham Syntax: my-utilities 681*aa7470a1SJim Ingham 682*aa7470a1SJim Ingham The following subcommands are supported: 683*aa7470a1SJim Ingham 684*aa7470a1SJim Ingham first -- My first utility Expects 'raw' input (see 'help raw-input'.) 685*aa7470a1SJim Ingham second -- My second utility Expects 'raw' input (see 'help raw-input'.) 686*aa7470a1SJim Ingham 687*aa7470a1SJim Ingham For more help on any particular subcommand, type 'help <command> <subcommand>'. 688*aa7470a1SJim Ingham (lldb) my-utilities first 689*aa7470a1SJim Ingham I am the first utility 690*aa7470a1SJim Ingham 691*aa7470a1SJim Ingham 6927b844849SJonas DevlieghereA more interesting template has been created in the source repository that can 6937b844849SJonas Devliegherehelp you to create lldb command quickly: 6947b844849SJonas Devlieghere 69594fac81fSxguptahttps://github.com/llvm/llvm-project/blob/main/lldb/examples/python/cmdtemplate.py 6967b844849SJonas Devlieghere 6977b844849SJonas DevlieghereA commonly required facility is being able to create a command that does some 6987b844849SJonas Devliegheretoken substitution, and then runs a different debugger command (usually, it 6997b844849SJonas Devliegherepo'es the result of an expression evaluated on its argument). For instance, 7007b844849SJonas Devliegheregiven the following program: 7017b844849SJonas Devlieghere 7027b844849SJonas Devlieghere:: 7037b844849SJonas Devlieghere 7047b844849SJonas Devlieghere #import <Foundation/Foundation.h> 7057b844849SJonas Devlieghere NSString* 7067b844849SJonas Devlieghere ModifyString(NSString* src) 7077b844849SJonas Devlieghere { 7087b844849SJonas Devlieghere return [src stringByAppendingString:@"foobar"]; 7097b844849SJonas Devlieghere } 7107b844849SJonas Devlieghere 7117b844849SJonas Devlieghere int main() 7127b844849SJonas Devlieghere { 7137b844849SJonas Devlieghere NSString* aString = @"Hello world"; 7147b844849SJonas Devlieghere NSString* anotherString = @"Let's be friends"; 7157b844849SJonas Devlieghere return 1; 7167b844849SJonas Devlieghere } 7177b844849SJonas Devlieghere 7187b844849SJonas Devlieghereyou may want a pofoo X command, that equates po [ModifyString(X) 7197b844849SJonas DevliegherecapitalizedString]. The following debugger interaction shows how to achieve 7207b844849SJonas Devliegherethat goal: 7217b844849SJonas Devlieghere 7227b844849SJonas Devlieghere:: 7237b844849SJonas Devlieghere 7247b844849SJonas Devlieghere (lldb) script 7257b844849SJonas Devlieghere Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D. 7267b844849SJonas Devlieghere >>> def pofoo_funct(debugger, command, result, internal_dict): 7277b844849SJonas Devlieghere ... cmd = "po [ModifyString(" + command + ") capitalizedString]" 7281441ffe6SDave Lee ... debugger.HandleCommand(cmd) 7297b844849SJonas Devlieghere ... 7307b844849SJonas Devlieghere >>> ^D 7317b844849SJonas Devlieghere (lldb) command script add pofoo -f pofoo_funct 7327b844849SJonas Devlieghere (lldb) pofoo aString 7337b844849SJonas Devlieghere $1 = 0x000000010010aa00 Hello Worldfoobar 7347b844849SJonas Devlieghere (lldb) pofoo anotherString 7357b844849SJonas Devlieghere $2 = 0x000000010010aba0 Let's Be Friendsfoobar 7367b844849SJonas Devlieghere 7377b844849SJonas DevlieghereUsing the lldb.py module in Python 7387b844849SJonas Devlieghere---------------------------------- 7397b844849SJonas Devlieghere 7407b844849SJonas DevlieghereLLDB has all of its core code build into a shared library which gets used by 74119ae9d01SAdrian Prantlthe `lldb` command line application. On macOS this shared library is a 7427b844849SJonas Devlieghereframework: LLDB.framework and on other unix variants the program is a shared 7437b844849SJonas Devliegherelibrary: lldb.so. LLDB also provides an lldb.py module that contains the 7447b844849SJonas Devliegherebindings from LLDB into Python. To use the LLDB.framework to create your own 7457b844849SJonas Devliegherestand-alone python programs, you will need to tell python where to look in 7467b844849SJonas Devlieghereorder to find this module. This is done by setting the PYTHONPATH environment 7477b844849SJonas Devliegherevariable, adding a path to the directory that contains the lldb.py python 7487b844849SJonas Devliegheremodule. The lldb driver program has an option to report the path to the lldb 7497b844849SJonas Devliegheremodule. You can use that to point to correct lldb.py: 7507b844849SJonas Devlieghere 7517b844849SJonas DevlieghereFor csh and tcsh: 7527b844849SJonas Devlieghere 7537b844849SJonas Devlieghere:: 7547b844849SJonas Devlieghere 7557b844849SJonas Devlieghere % setenv PYTHONPATH `lldb -P` 7567b844849SJonas Devlieghere 7577b844849SJonas DevlieghereFor sh and bash: 7587b844849SJonas Devlieghere 7597b844849SJonas Devlieghere:: 7607b844849SJonas Devlieghere 76159c954f7SShivam Gupta $ export PYTHONPATH=`lldb -P` 7627b844849SJonas Devlieghere 7637b844849SJonas DevlieghereAlternately, you can append the LLDB Python directory to the sys.path list 7647b844849SJonas Devliegheredirectly in your Python code before importing the lldb module. 7657b844849SJonas Devlieghere 7667b844849SJonas DevlieghereNow your python scripts are ready to import the lldb module. Below is a python 7677b844849SJonas Devliegherescript that will launch a program from the current working directory called 7687b844849SJonas Devlieghere"a.out", set a breakpoint at "main", and then run and hit the breakpoint, and 7697b844849SJonas Devlieghereprint the process, thread and frame objects if the process stopped: 7707b844849SJonas Devlieghere 7717b844849SJonas Devlieghere:: 7727b844849SJonas Devlieghere 773a54f160bSHarmen Stoppels #!/usr/bin/env python 7747b844849SJonas Devlieghere 7757b844849SJonas Devlieghere import lldb 7767b844849SJonas Devlieghere import os 7777b844849SJonas Devlieghere 7787b844849SJonas Devlieghere def disassemble_instructions(insts): 7797b844849SJonas Devlieghere for i in insts: 7807b844849SJonas Devlieghere print i 7817b844849SJonas Devlieghere 7827b844849SJonas Devlieghere # Set the path to the executable to debug 7837b844849SJonas Devlieghere exe = "./a.out" 7847b844849SJonas Devlieghere 7857b844849SJonas Devlieghere # Create a new debugger instance 7867b844849SJonas Devlieghere debugger = lldb.SBDebugger.Create() 7877b844849SJonas Devlieghere 7887b844849SJonas Devlieghere # When we step or continue, don't return from the function until the process 7897b844849SJonas Devlieghere # stops. Otherwise we would have to handle the process events ourselves which, while doable is 7907b844849SJonas Devlieghere #a little tricky. We do this by setting the async mode to false. 7917b844849SJonas Devlieghere debugger.SetAsync (False) 7927b844849SJonas Devlieghere 7937b844849SJonas Devlieghere # Create a target from a file and arch 7947b844849SJonas Devlieghere print "Creating a target for '%s'" % exe 7957b844849SJonas Devlieghere 7967b844849SJonas Devlieghere target = debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT) 7977b844849SJonas Devlieghere 7987b844849SJonas Devlieghere if target: 7997b844849SJonas Devlieghere # If the target is valid set a breakpoint at main 8007b844849SJonas Devlieghere main_bp = target.BreakpointCreateByName ("main", target.GetExecutable().GetFilename()); 8017b844849SJonas Devlieghere 8027b844849SJonas Devlieghere print main_bp 8037b844849SJonas Devlieghere 8047b844849SJonas Devlieghere # Launch the process. Since we specified synchronous mode, we won't return 8057b844849SJonas Devlieghere # from this function until we hit the breakpoint at main 8067b844849SJonas Devlieghere process = target.LaunchSimple (None, None, os.getcwd()) 8077b844849SJonas Devlieghere 8087b844849SJonas Devlieghere # Make sure the launch went ok 8097b844849SJonas Devlieghere if process: 8107b844849SJonas Devlieghere # Print some simple process info 8117b844849SJonas Devlieghere state = process.GetState () 8127b844849SJonas Devlieghere print process 8137b844849SJonas Devlieghere if state == lldb.eStateStopped: 8147b844849SJonas Devlieghere # Get the first thread 8157b844849SJonas Devlieghere thread = process.GetThreadAtIndex (0) 8167b844849SJonas Devlieghere if thread: 8177b844849SJonas Devlieghere # Print some simple thread info 8187b844849SJonas Devlieghere print thread 8197b844849SJonas Devlieghere # Get the first frame 8207b844849SJonas Devlieghere frame = thread.GetFrameAtIndex (0) 8217b844849SJonas Devlieghere if frame: 8227b844849SJonas Devlieghere # Print some simple frame info 8237b844849SJonas Devlieghere print frame 8247b844849SJonas Devlieghere function = frame.GetFunction() 8257b844849SJonas Devlieghere # See if we have debug info (a function) 8267b844849SJonas Devlieghere if function: 8277b844849SJonas Devlieghere # We do have a function, print some info for the function 8287b844849SJonas Devlieghere print function 8297b844849SJonas Devlieghere # Now get all instructions for this function and print them 8307b844849SJonas Devlieghere insts = function.GetInstructions(target) 8317b844849SJonas Devlieghere disassemble_instructions (insts) 8327b844849SJonas Devlieghere else: 8337b844849SJonas Devlieghere # See if we have a symbol in the symbol table for where we stopped 8347b844849SJonas Devlieghere symbol = frame.GetSymbol(); 8357b844849SJonas Devlieghere if symbol: 8367b844849SJonas Devlieghere # We do have a symbol, print some info for the symbol 8377b844849SJonas Devlieghere print symbol 8387b844849SJonas Devlieghere 8397b844849SJonas DevlieghereWriting lldb frame recognizers in Python 8407b844849SJonas Devlieghere---------------------------------------- 8417b844849SJonas Devlieghere 8427b844849SJonas DevlieghereFrame recognizers allow for retrieving information about special frames based 8437b844849SJonas Devlieghereon ABI, arguments or other special properties of that frame, even without 8447b844849SJonas Devliegheresource code or debug info. Currently, one use case is to extract function 8454fd3347dSKazu Hirataarguments that would otherwise be inaccessible, or augment existing arguments. 8467b844849SJonas Devlieghere 8477b844849SJonas DevlieghereAdding a custom frame recognizer is done by implementing a Python class and 8487b844849SJonas Devlieghereusing the 'frame recognizer add' command. The Python class should have a 8497b844849SJonas Devlieghere'get_recognized_arguments' method and it will receive an argument of type 8507b844849SJonas Devliegherelldb.SBFrame representing the current frame that we are trying to recognize. 8517b844849SJonas DevlieghereThe method should return a (possibly empty) list of lldb.SBValue objects that 8527b844849SJonas Devlieghererepresent the recognized arguments. 8537b844849SJonas Devlieghere 8547b844849SJonas DevlieghereAn example of a recognizer that retrieves the file descriptor values from libc 8557b844849SJonas Devliegherefunctions 'read', 'write' and 'close' follows: 8567b844849SJonas Devlieghere 8577b844849SJonas Devlieghere:: 8587b844849SJonas Devlieghere 8597b844849SJonas Devlieghere class LibcFdRecognizer(object): 8607b844849SJonas Devlieghere def get_recognized_arguments(self, frame): 8617b844849SJonas Devlieghere if frame.name in ["read", "write", "close"]: 8627b844849SJonas Devlieghere fd = frame.EvaluateExpression("$arg1").unsigned 8637b844849SJonas Devlieghere value = lldb.target.CreateValueFromExpression("fd", "(int)%d" % fd) 8647b844849SJonas Devlieghere return [value] 8657b844849SJonas Devlieghere return [] 8667b844849SJonas Devlieghere 86751ab17b9SRaphael IsemannThe file containing this implementation can be imported via ``command script import`` 86851ab17b9SRaphael Isemannand then we can register this recognizer with ``frame recognizer add``. 8697b844849SJonas DevlieghereIt's important to restrict the recognizer to the libc library (which is 8707b844849SJonas Devliegherelibsystem_kernel.dylib on macOS) to avoid matching functions with the same name 8717b844849SJonas Devliegherein other modules: 8727b844849SJonas Devlieghere 8737b844849SJonas Devlieghere:: 8747b844849SJonas Devlieghere 8757b844849SJonas Devlieghere (lldb) command script import .../fd_recognizer.py 8767b844849SJonas Devlieghere (lldb) frame recognizer add -l fd_recognizer.LibcFdRecognizer -n read -s libsystem_kernel.dylib 8777b844849SJonas Devlieghere 8787b844849SJonas DevlieghereWhen the program is stopped at the beginning of the 'read' function in libc, we can view the recognizer arguments in 'frame variable': 8797b844849SJonas Devlieghere 8807b844849SJonas Devlieghere:: 8817b844849SJonas Devlieghere 8827b844849SJonas Devlieghere (lldb) b read 8837b844849SJonas Devlieghere (lldb) r 8847b844849SJonas Devlieghere Process 1234 stopped 8857b844849SJonas Devlieghere * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.3 8867b844849SJonas Devlieghere frame #0: 0x00007fff06013ca0 libsystem_kernel.dylib`read 8877b844849SJonas Devlieghere (lldb) frame variable 8887b844849SJonas Devlieghere (int) fd = 3 8891b1d9815SJim Ingham 8901b1d9815SJim InghamWriting Target Stop-Hooks in Python: 8911b1d9815SJim Ingham------------------------------------ 8921b1d9815SJim Ingham 8931b1d9815SJim InghamStop hooks fire whenever the process stops just before control is returned to the 8941b1d9815SJim Inghamuser. Stop hooks can either be a set of lldb command-line commands, or can 8951b1d9815SJim Inghambe implemented by a suitably defined Python class. The Python based stop-hooks 8961b1d9815SJim Inghamcan also be passed as set of -key -value pairs when they are added, and those 8971b1d9815SJim Inghamwill get packaged up into a SBStructuredData Dictionary and passed to the 8981b1d9815SJim Inghamconstructor of the Python object managing the stop hook. This allows for 8991b1d9815SJim Inghamparametrization of the stop hooks. 9001b1d9815SJim Ingham 9011b1d9815SJim InghamTo add a Python-based stop hook, first define a class with the following methods: 9021b1d9815SJim Ingham 9031b1d9815SJim Ingham+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 9041b1d9815SJim Ingham| Name | Arguments | Description | 9051b1d9815SJim Ingham+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 90651ab17b9SRaphael Isemann| ``__init__`` | ``target: lldb.SBTarget`` | This is the constructor for the new stop-hook. | 90751ab17b9SRaphael Isemann| | ``extra_args: lldb.SBStructuredData`` | | 9081b1d9815SJim Ingham| | | | 90951ab17b9SRaphael Isemann| | | ``target`` is the SBTarget to which the stop hook is added. | 9101b1d9815SJim Ingham| | | | 91151ab17b9SRaphael Isemann| | | ``extra_args`` is an SBStructuredData object that the user can pass in when creating instances of this | 9121b1d9815SJim Ingham| | | breakpoint. It is not required, but allows for reuse of stop-hook classes. | 9131b1d9815SJim Ingham+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 91451ab17b9SRaphael Isemann| ``handle_stop`` | ``exe_ctx: lldb.SBExecutionContext`` | This is the called when the target stops. | 91551ab17b9SRaphael Isemann| | ``stream: lldb.SBStream`` | | 91651ab17b9SRaphael Isemann| | | ``exe_ctx`` argument will be filled with the current stop point for which the stop hook is | 9171b1d9815SJim Ingham| | | being evaluated. | 9181b1d9815SJim Ingham| | | | 91951ab17b9SRaphael Isemann| | | ``stream`` an lldb.SBStream, anything written to this stream will be written to the debugger console. | 9201b1d9815SJim Ingham| | | | 9211b1d9815SJim Ingham| | | The return value is a "Should Stop" vote from this thread. If the method returns either True or no return | 9221b1d9815SJim Ingham| | | this thread votes to stop. If it returns False, then the thread votes to continue after all the stop-hooks | 9231b1d9815SJim Ingham| | | are evaluated. | 9241b1d9815SJim Ingham| | | Note, the --auto-continue flag to 'target stop-hook add' overrides a True return value from the method. | 9251b1d9815SJim Ingham+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ 9261b1d9815SJim Ingham 9271b1d9815SJim InghamTo use this class in lldb, run the command: 9281b1d9815SJim Ingham 9291b1d9815SJim Ingham:: 9301b1d9815SJim Ingham 9311b1d9815SJim Ingham (lldb) command script import MyModule.py 9321b1d9815SJim Ingham (lldb) target stop-hook add -P MyModule.MyStopHook -k first -v 1 -k second -v 2 9331b1d9815SJim Ingham 9341b1d9815SJim Inghamwhere MyModule.py is the file containing the class definition MyStopHook. 935