134 lines · plain
1Scripting Bridge API2====================3 4The SB APIs constitute the stable C++ API that lldb presents to external5clients, and which get processed by SWIG to produce the Python bindings to6lldb. As such it is important that they not suffer from the binary7incompatibilities that C++ is so susceptible to. We've established a few rules8to ensure that this happens.9 10Extending the SB API11--------------------12 13The classes in the SB API's are all called SB<SomeName>, where SomeName is in14CamelCase starting with an upper case letter. The method names are all15CamelCase with initial capital letter as well.16 17All the SB API classes are non-virtual, single inheritance classes. They should18only include SBDefines.h or other SB headers as needed. There should be no19inlined method implementations in the header files, they should all be in the20implementation files. And there should be no direct ivar access.21 22You also need to choose the ivars for the class with care, since you can't add23or remove ivars without breaking binary compatibility. In some cases, the SB24class is a thin wrapper around an internal lldb_private object. In that case,25the class can have a single ivar, which is either a pointer, shared_ptr or26unique_ptr to the object in the lldb_private API. All the lldb_private classes27that get used this way are declared as opaque classes in lldb_forward.h, which28is included in SBDefines.h. So if you need an SB class to wrap an lldb_private29class that isn't in lldb_forward.h, add it there rather than making a direct30opaque declaration in the SB classes .h file.31 32If the SB Class needs some state of its own, as well as the backing object,33don't include that as a direct ivar in the SB Class. Instead, make an Impl34class in the SB's .cpp file, and then make the SB object hold a shared or35unique pointer to the Impl object. The theory behind this is that if you need36more state in the SB object, those needs are likely to change over time, and37this way the Impl class can pick up members without changing the size of the38object. An example of this is the SBValue class. Please note that you should39not put this Impl class in the lldb namespace. Failure to do so leads to40leakage of weak-linked symbols in the SBAPI.41 42In order to fit into the Python API's, we need to be able to default construct43all the SB objects. Since the ivars of the classes are all pointers of one sort44or other, this can easily be done, but it means all the methods must be45prepared to handle their opaque implementation pointer being empty, and doing46something reasonable. We also always have an "IsValid" method on all the SB47classes to report whether the object is empty or not.48 49Another piece of the SB API infrastructure is the Python (or other script50interpreter) customization. SWIG allows you to add property access, iterators51and documentation to classes. We place the property accessors and iterators in52a file dedicated to extensions to existing SB classes at53"bindings/interface/SB<ClassName>Extensions.i". The documentation is similarly54located at "bindings/interface/SB<ClassName>Docstrings.i". These two files, in55addition to the actual header SB<ClassName>.h, forms the interface that lldb56exposes to users through the scripting languages.57 58There are some situations where you may want to add functionality to the SB API59only for use in C++. To prevent SWIG from generating bindings to these60functions, you can use a C macro guard, like so:61 62::63 64 #ifndef SWIG65 int GetResourceCPPOnly() const;66 #endif67 68In this case, ``GetResourceCPPOnly`` will not be generated for Python or other69scripting languages. If you wanted to add a resource specifically only for the70SWIG case, you can invert the condition and use ``#ifdef SWIG`` instead. When71building the LLDB framework for macOS, the headers are processed with72``unifdef`` prior to being copied into the framework bundle to remove macros73involving SWIG.74 75Another good principle when adding SB API methods is: if you find yourself76implementing a significant algorithm in the SB API method, you should not do77that, but instead look for and then add it - if not found - as a method in the78underlying lldb_private class, and then call that from your SB API method.79If it was a useful algorithm, it's very likely it already exists80because the lldb_private code also needed to do it. And if it doesn't at81present, if it was a useful thing to do, it's likely someone will later need82it in lldb_private and then we end up with two implementations of the same83algorithm. If we keep the SB API code to just what's needed to manage the SB84objects and requests, we won't get into this situation.85 86Lifetime87--------88Many SB API methods will return strings in the form of ``const char *`` values.89Once created, these strings are guaranteed to live until the end of the90debugging session. LLDB owns these strings, clients should not attempt to free91them. Doing so may cause LLDB to crash.92Note that this only affects the C++ API as scripting languages usually93will usually create native string types from the ``const char *`` value.94 95API Instrumentation96-------------------97 98The reproducer infrastructure requires API methods to be instrumented so that99they can be captured and replayed. Instrumentation consists of two macros,100``LLDB_REGISTER`` and ``LLDB_RECORD``. Both can be automatically generated with101the ``lldb-instr`` utility.102 103To add instrumentation for a given file, pass it to the ``lldb-instr`` tool.104Like other clang-based tools it requires a compilation database105(``compile_commands.json``) to be present in the current working directory.106 107::108 109 $ ./bin/lldb-instr /path/to/lldb/source/API/SBDebugger.cpp110 111 112The tool will automatically insert ``LLDB_RECORD`` macros inline, however you113will need to run ``clang-format`` over the processed file, as the tool114(intentionally) makes no attempt to get that right.115 116The ``LLDB_REGISTER`` macros are printed to standard out between curly braces.117You'll have to copy-paste those into the corresponding ``RegisterMethods``118function in the implementation file. This function is fully specialized in the119corresponding type.120 121::122 123 template <> void RegisterMethods<SBDebugger>(Registry &R) {124 ...125 }126 127 128When adding a new class, you'll also have to add a call to ``RegisterMethods``129in the ``SBRegistry`` constructor.130 131The tool can be used incrementally. However, it will ignore existing macros132even if their signature is wrong. It will only generate a ``LLDB_REGISTER`` if133it emitted a corresponding ``LLDB_RECORD`` macro.134