jingham created this revision.
jingham added a reviewer: clayborg.
Herald added subscribers: lldb-commits, abidh.

These are the promised docs for https://reviews.llvm.org/D51830.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D52065

Files:
  www/python-reference.html

Index: www/python-reference.html
===================================================================
--- www/python-reference.html
+++ www/python-reference.html
@@ -316,6 +316,167 @@
             </div>
 
       	</div>
+      	</div>
+		<div class="post">
+			<h1 class ="postheader">Using the Python API's to create custom breakpoints</h1>
+			<div class="postcontent">
+
+                <p>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.  
+                </p>
+                <p>
+                  In lldb, a breakpoint is composed of two parts, the Searcher, and the Resolver:
+                </p>
+                <p>
+                  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.
+                </p>
+                <p>
+                  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.
+                </p>
+                <p>
+                  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.
+                </p>
+                <p>
+                  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.
+                </p>
+                <p>
+                  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.
+                </p>
+                <p>
+                  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.
+                </p>
+                <p>
+                  The custom Resolver is provided as a Python class with the following methods:
+                </p>
+</tt></pre></code>
+                    <p><table class="stats" width="620" cellspacing="0">
+                    <tr>
+                        <td class="hed" width="10%">Name</td>
+                        <td class="hed" width="10%">Arguments</td>
+                        <td class="hed" width="80%">Description</td>
+                    </tr>
+
+
+                    <tr>
+                        <td class="content">
+                            <b>__init__</b>
+                        </td>
+                        <td class="content">
+                            <b>bkpt: lldb.SBBreakpoint</b>
+                            <b>extra_args: lldb.SBStructuredData</b>
+                        </td>
+                        <td class="content">
+                          <p>
+                            This is the constructor for the new Resolver.  
+                          </p>
+                          <p>
+                            <b>bkpt</b> is the breakpoint owning this Resolver.
+                          </p>
+                          <p>
+                            <b>extra_args</b> 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
+                        </td>
+                    </tr>
+
+                    <tr>
+                        <td class="content">
+                            <b>__callback__</b>
+                        </td>
+                        <td class="content">
+                            <b>sym_ctx: lldb.SBSymbolContext</b>
+                        </td>
+                        <td class="content">
+                            This is the Resolver callback.  
+                            The <b>sym_ctx</b> argument will be filled with the current stage
+                            of the search.  
+                          </p>
+                          <p>
+                            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 <b>sym_ctx</b> for new locations.  If the callback finds an address of interest, it
+                            can add it to the breakpoint with the <b>SBBreakpoint::AddLocation</b> method, using the breakpoint passed
+                            in to the <b>__init__</b> method.
+                        </td>
+                    </tr>
+                    <tr>
+                        <td class="content">
+                            <b>__get_depth__</b>
+                        </td>
+                        <td class="content">
+                            <b>None</b>
+                        </td>
+                        <td class="content">
+                            Specify the depth at which you wish your callback to get called.  The currently supported options are:
+                            <dl>
+                              <dt>lldb.eSearchDepthModule</dt> 
+                              <dt>lldb.eSearchDepthCompUnit</dt>
+                              <dt>lldb.eSearchDepthFunction</dt>
+                            </dl>  
+                            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 <b>lldb.eSearchDepthModule</b>.  This method is optional.  If not provided the search
+                            will be done at Module depth.
+                        </td>
+                    </tr>
+                    <tr>
+                        <td class="content">
+                            <b>get_short_help</b>
+                        </td>
+                        <td class="content">
+                            <b>None</b>
+                        </td>
+                        <td class="content">
+                            This is an optional method.  If provided, the returned string will be printed at the beginning of
+                            the description for this breakpoint.
+                        </td>
+                    </tr>
+                    </table>
+                   
+                    <p>To define a new breakpoint command defined by this class from the lldb command line, use the command:</p>
+
+<code><pre><tt>(lldb) <strong>breakpoint set -P MyModule.MyResolverClass</strong>
+</tt></pre></code>
+                   <p>You can also populate the extra_args SBStructuredData with a dictionary of key/value pairs with:</p>
+
+<code><pre><tt>(lldb) <strong>breakpoint set -P MyModule.MyResolverClass -k key_1 -v value_1 -k key_2 -v value_2</strong>
+</tt></pre></code>
+                   <p>You can specify a SearchFilter restricted to certain modules by passing in the &quot-s ModuleName&quot
+                     option - which can be specified multiple times.  You can specify a SearchFilter restricted to certain
+                     compile units by passing in the &quot-f CompUnitName&quot option.  This can also be specified more than
+                     once.  And you can mix the two to specify &quotthis comp unit in this module&quot.
+                     
+                   <p>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.
+                   </p>
+
+            </div>
 		<div class="post">
 			<h1 class ="postheader">Using the Python API's to create custom stepping logic</h1>
 			<div class="postcontent">
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to