jingham created this revision.
Herald added subscribers: lldb-commits, teemperor, abidh, jfb, srhines.
This change allows you to make a breakpoint resolver kernel in Python.
The breakpoint search mechanism in lldb works on top of a generic mechanism
that uses a pair of Searcher - with its associated SearchFilter - and Resolver.
The Searcher iterates through the contours of a target, stopping at a depth
(module, comp_unit, function...) specified by the Resolver. If the object at
the requested depth matches the search filter, then the Searcher calls the
Resolver's SearchCallback function, handing it a SymbolContext representing
that stage of the search.
In the case of a BreakpointResolver, if the Resolver finds any addresses in
that SymbolContext which it wants to break on, it calls AddLocation on its
owning Breakpoint to add that location to the breakpoint.
This change allows you to write a simple Python class to add whatever
collection of locations makes sense using whatever logic you want. The class
must provide an __callback__ method that takes a SBSymbolContext. This will
get called at each appropriate stage of the search. You can optionally provide
a __get_depth__ method that returns the search depth (which defaults to Module
if unspecified), and a get_short_help method that will be used in the
breakpoint description.
When objects of the given class are constructed to represent a specific
breakpoint, they are passed a StructuredData object which can be used to
parametrize that particular breakpoint. From the SB API's you can pass in an
arbitrary SBStructuredData. From the command line I added -k and -v options to
"break set" that you provide in pairs to build up a StructuredData::Dictionary
which is passed to the resolver. Also, from the command-line the -f and -s
options are used to construct the SearchFilter for the breakpoint's Searcher.
For instance, a simple full symbol name breakpoint can be implemented with:
> cat resolver.py
import lldb
class Resolver:
def __init__(self, bkpt, extra_args, dict):
self.bkpt = bkpt
self.extra_args = extra_args
def __callback__(self, sym_ctx):
sym_item = self.extra_args.GetValueForKey("symbol")
if not sym_item.IsValid():
return
sym_name = sym_item.GetStringValue(1000)
sym = sym_ctx.module.FindSymbol(sym_name, lldb.eSymbolTypeCode)
if sym.IsValid():
self.bkpt.AddLocation(sym.GetStartAddress())
def get_short_help(self):
return "I am a python breakpoint resolver"
> lldb a.out
(lldb) target create "a.out"
Current executable set to 'a.out' (x86_64).
(lldb) command script import resolver.py
(lldb) break set -P resolver.Resolver -k symbol -v break_on_me
(lldb) break set -P resolver.Resolver -k symbol -v break_on_me
Breakpoint 1: where = a.out`break_on_me at main.c:5, address =
0x0000000100000f40
(lldb) break list
Current breakpoints:
1: I am a python breakpoint resolver, locations = 1
1.1: where = a.out`break_on_me at main.c:5, address =
a.out[0x0000000100000f40], unresolved, hit count = 0
The functionality is advanced enough that this is useful, and I don't expect
that will change much. There are tests for all of this.
There are some future work items:
Docs are forthcoming.
Serialization is not all the way working, but I think it's worth getting the
current state of things in before I tackle that.
I also need to invent a way for the __init__ to vet its incoming arguments and
return an error - which will abort the breakpoint creation - if they don't have
some necessary entries.
Repository:
rLLDB LLDB
https://reviews.llvm.org/D51830
Files:
include/lldb/API/SBAddress.h
include/lldb/API/SBBreakpoint.h
include/lldb/API/SBStructuredData.h
include/lldb/API/SBSymbolContext.h
include/lldb/API/SBTarget.h
include/lldb/Breakpoint/BreakpointResolver.h
include/lldb/Breakpoint/BreakpointResolverScripted.h
include/lldb/Interpreter/ScriptInterpreter.h
include/lldb/Target/Target.h
include/lldb/lldb-defines.h
include/lldb/lldb-enumerations.h
lldb.xcodeproj/project.pbxproj
packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/Makefile
packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py
packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/main.c
packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py
packages/Python/lldbsuite/test/lldbutil.py
scripts/Python/python-swigsafecast.swig
scripts/Python/python-wrapper.swig
scripts/interface/SBBreakpoint.i
scripts/interface/SBStringList.i
scripts/interface/SBStructuredData.i
scripts/interface/SBTarget.i
source/API/SBBreakpoint.cpp
source/API/SBStructuredData.cpp
source/API/SBTarget.cpp
source/API/SystemInitializerFull.cpp
source/Breakpoint/BreakpointResolver.cpp
source/Breakpoint/BreakpointResolverScripted.cpp
source/Commands/CommandObjectBreakpoint.cpp
source/Core/SearchFilter.cpp
source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
source/Target/Target.cpp
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits