Index: www/python-reference.html =================================================================== --- www/python-reference.html +++ www/python-reference.html @@ -316,6 +316,167 @@ + +
+

Using the Python API's to create custom breakpoints

+
+ +

Another use of the Python API's in lldb is to create a custom breakpoint resolver. This + allows you to implement your own logic to search the space of the code in a given Target + and set breakpoint locations wherever you think it appropriate. To understand how this works + you need to know a little about how lldb views breakpoints. +

+

+ In lldb, a breakpoint is composed of two parts, the Searcher, and the Resolver: +

+

+ The Searcher's job is to traverse in a structured way the code in the current target. It + proceeds from the Target, to search all the Modules in the Target, in each Module it can recurse + into the Compile Units in that module, and within each Compile Unit it can recurse over the Functions + it contains. +

+

+ The Searcher can be provided with a SearchFilter that it will use to restrict this search. For instance, if the + SearchFilter specifies a list of good Modules, the Searcher will not recurse into Modules that aren't on the list. +

+

+ The Searcher will also visit any new modules as they are added to the target. This happens, for instance, when + a new shared library gets added to the target in the course of running, or on rerunning if any of the currently + loaded modules have been changed. Note, in the latter case, all the locations set in the old module will get + deleted and you will be asked to recreate them in the new version of the module when your callback gets called + with that module. For this reason, you shouldn't + try to manage the locations you add to the breakpoint yourself. Note that the Breakpoint takes care of + deduplicating equal addresses in AddLocation, so you shouldn't need to worry about that anyway. +

+

+ The Resolver has two functions. The most important one is the callback it provides. This will get called at the appropriate time + in the course of the search. The callback is where the job of adding locations to the breakpoint gets done. + The other function is specifying to the Searcher at what depth in the above described recursion it wants to be + called. Setting a search depth also provides a stop for the recursion. For instance, if you request a Module depth + search, then the callback will be called for each Module as it gets added to the Target, but the searcher will not recurse into the + Compile Units in the module. +

+

+ One other slight sublety is that the depth at which you get called back is not necessarily the depth at which the + the SearchFilter is specified. For instance, if you are doing symbol searches, it is convenient to use the Module + depth for the search, since symbols are stored in the module. + But the SearchFilter might specify some subset of CompileUnits, so not all the symbols you might find in each module + will pass the search. However, you don't need to + handle this yourself. SBBreakpoint::AddLocation will only add locations that pass the Search Filter. +

+

+ At present, when defining a new Breakpoint type, you can only provide a custom Resolver. Although you can't provide a custom + SearchFilter, the API's that allow the definition of new scripted breakpoint types do allow you to create Search Filters + specified by a list of Modules, CompileUnits, or both. +

+

+ The custom Resolver is provided as a Python class with the following methods: +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameArgumentsDescription
+ __init__ + + bkpt: lldb.SBBreakpoint + extra_args: lldb.SBStructuredData + +

+ This is the constructor for the new Resolver. +

+

+ bkpt is the breakpoint owning this Resolver. +

+

+ extra_args is an SBStructuredData object that the user can pass in when creating instances of this + breakpoint. It is not required, but is quite handy. For instance if you were implementing a breakpoint on some + symbol name, you could write a generic symbol name based Resolver, and then allow the user to pass + in the particular symbol in the extra_args +

+ __callback__ + + sym_ctx: lldb.SBSymbolContext + + This is the Resolver callback. + The sym_ctx argument will be filled with the current stage + of the search. +

+

+ For instance, if you asked for a search depth of lldb.eSearchDepthCompUnit, then the + target, module and compile_unit fields of the sym_ctx will be filled. The callback should look just in the + context passed in sym_ctx for new locations. If the callback finds an address of interest, it + can add it to the breakpoint with the SBBreakpoint::AddLocation method, using the breakpoint passed + in to the __init__ method. +

+ __get_depth__ + + None + + Specify the depth at which you wish your callback to get called. The currently supported options are: +
+
lldb.eSearchDepthModule
+
lldb.eSearchDepthCompUnit
+
lldb.eSearchDepthFunction
+
+ For instance, if you are looking + up symbols, which are stored at the Module level, you will want to get called back module by module. + So you would want to return lldb.eSearchDepthModule. This method is optional. If not provided the search + will be done at Module depth. +
+ get_short_help + + None + + This is an optional method. If provided, the returned string will be printed at the beginning of + the description for this breakpoint. +
+ +

To define a new breakpoint command defined by this class from the lldb command line, use the command:

+ +
(lldb) breakpoint set -P MyModule.MyResolverClass
+
+

You can also populate the extra_args SBStructuredData with a dictionary of key/value pairs with:

+ +
(lldb) breakpoint set -P MyModule.MyResolverClass -k key_1 -v value_1 -k key_2 -v value_2
+
+

You can specify a SearchFilter restricted to certain modules by passing in the "-s ModuleName" + option - which can be specified multiple times. You can specify a SearchFilter restricted to certain + compile units by passing in the "-f CompUnitName" option. This can also be specified more than + once. And you can mix the two to specify "this comp unit in this module". + +

Another option, which allows you to pass in an arbitrary SBStructuredData object, is to use the SBTarget.CreateBreakpointFromScript API. + SBStructuredData has a handy SetFromJSON method that you can use to construct more complex data objects. + Your __init__ function gets passed this SBStructuredData object. +

+ +

Using the Python API's to create custom stepping logic