llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: None (rchamala) <details> <summary>Changes</summary> ## Summary - Adds 5 API test cases (`TestScriptedSymbolLocator.py`): locate_source_file, None fallthrough, invalid script class, info command, SBDebugger API - Adds test helpers (`source_locator.py`): `SourceLocator` and `NoneLocator` - Adds tutorial documentation (`custom-symbol-resolution.md`) - Adds Python base class template (`scripted_symbol_locator.py`) with all 4 callbacks documented plus `LocalCacheSymbolLocator` example - Adds automodapi section in `python_extensions.rst` and toctree entry in `python-reference.rst` **PR Stack:** #<!-- -->183674 → #<!-- -->183675 → #<!-- -->183676 → #<!-- -->183677 → **this** ## Test plan - [x] `ninja check-lldb` — no regressions - [x] `llvm-lit -sv lldb/test/API/functionalities/scripted_symbol_locator/` — all 5 tests pass --- Patch is 85.20 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/183678.diff 47 Files Affected: - (modified) lldb/bindings/python/CMakeLists.txt (+1) - (modified) lldb/bindings/python/python-swigsafecast.swig (+5) - (modified) lldb/bindings/python/python-wrapper.swig (+36) - (modified) lldb/docs/CMakeLists.txt (+1) - (modified) lldb/docs/python_extensions.rst (+8) - (modified) lldb/docs/use/python-reference.rst (+1) - (added) lldb/docs/use/tutorials/custom-symbol-resolution.md (+131) - (added) lldb/examples/python/templates/scripted_symbol_locator.py (+185) - (modified) lldb/include/lldb/API/SBDebugger.h (+20) - (modified) lldb/include/lldb/API/SBFileSpec.h (+5) - (modified) lldb/include/lldb/API/SBModule.h (+1) - (modified) lldb/include/lldb/API/SBModuleSpec.h (+9) - (modified) lldb/include/lldb/Core/PluginManager.h (+25) - (added) lldb/include/lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h (+52) - (modified) lldb/include/lldb/Interpreter/ScriptInterpreter.h (+13) - (modified) lldb/include/lldb/Symbol/LineEntry.h (+1-1) - (modified) lldb/include/lldb/lldb-forward.h (+3) - (modified) lldb/include/lldb/lldb-private-interfaces.h (+2) - (modified) lldb/source/API/SBDebugger.cpp (+29) - (modified) lldb/source/Commands/CommandObjectTarget.cpp (+131) - (modified) lldb/source/Core/Module.cpp (+1-1) - (modified) lldb/source/Core/PluginManager.cpp (+74-2) - (modified) lldb/source/Interpreter/ScriptInterpreter.cpp (+21) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt (+1) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp (+2) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h (+1) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp (+54) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h (+30) - (added) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.cpp (+109) - (added) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.h (+62) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h (+5) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp (+5) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h (+3) - (modified) lldb/source/Plugins/SymbolLocator/CMakeLists.txt (+1) - (modified) lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp (+1-1) - (added) lldb/source/Plugins/SymbolLocator/Scripted/CMakeLists.txt (+13) - (added) lldb/source/Plugins/SymbolLocator/Scripted/SymbolLocatorScripted.cpp (+166) - (added) lldb/source/Plugins/SymbolLocator/Scripted/SymbolLocatorScripted.h (+51) - (modified) lldb/source/Symbol/LineEntry.cpp (+18-1) - (modified) lldb/source/Target/StackFrame.cpp (+1-1) - (modified) lldb/source/Target/StackFrameList.cpp (+2-1) - (modified) lldb/source/Target/ThreadPlanStepRange.cpp (+2-2) - (added) lldb/test/API/functionalities/scripted_symbol_locator/Makefile (+8) - (added) lldb/test/API/functionalities/scripted_symbol_locator/TestScriptedSymbolLocator.py (+229) - (added) lldb/test/API/functionalities/scripted_symbol_locator/main.c (+4) - (added) lldb/test/API/functionalities/scripted_symbol_locator/source_locator.py (+44) - (modified) lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp (+20) ``````````diff diff --git a/lldb/bindings/python/CMakeLists.txt b/lldb/bindings/python/CMakeLists.txt index 2ebcf5a8e7aca..294f32fa05ba9 100644 --- a/lldb/bindings/python/CMakeLists.txt +++ b/lldb/bindings/python/CMakeLists.txt @@ -114,6 +114,7 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_frame_provider.py" "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_process.py" "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py" + "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_symbol_locator.py" "${LLDB_SOURCE_DIR}/examples/python/templates/operating_system.py" "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_thread_plan.py" ) diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig index a86dc44ce4106..fdf8de3d28aa2 100644 --- a/lldb/bindings/python/python-swigsafecast.swig +++ b/lldb/bindings/python/python-swigsafecast.swig @@ -147,6 +147,11 @@ PythonObject SWIGBridge::ToSWIGWrapper( return ToSWIGHelper(module_spec_sb.release(), SWIGTYPE_p_lldb__SBModuleSpec); } +PythonObject SWIGBridge::ToSWIGWrapper(const ModuleSpec &module_spec) { + return ToSWIGHelper(new lldb::SBModuleSpec(module_spec), + SWIGTYPE_p_lldb__SBModuleSpec); +} + PythonObject SWIGBridge::ToSWIGWrapper(lldb::DescriptionLevel level) { return PythonInteger((int64_t) level); } diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index bf59569920470..c881cf9a5286e 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -595,6 +595,42 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFrameList(PyObject *d return sb_ptr; } +void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFileSpec(PyObject *data) { + lldb::SBFileSpec *sb_ptr = NULL; + + int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr, + SWIGTYPE_p_lldb__SBFileSpec, 0); + + if (valid_cast == -1) + return NULL; + + return sb_ptr; +} + +void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBModule(PyObject *data) { + lldb::SBModule *sb_ptr = NULL; + + int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr, + SWIGTYPE_p_lldb__SBModule, 0); + + if (valid_cast == -1) + return NULL; + + return sb_ptr; +} + +void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBModuleSpec(PyObject *data) { + lldb::SBModuleSpec *sb_ptr = NULL; + + int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr, + SWIGTYPE_p_lldb__SBModuleSpec, 0); + + if (valid_cast == -1) + return NULL; + + return sb_ptr; +} + bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallCommand( const char *python_function_name, const char *session_dictionary_name, lldb::DebuggerSP debugger, const char *args, diff --git a/lldb/docs/CMakeLists.txt b/lldb/docs/CMakeLists.txt index bbecf606f1f8f..760f7e9bd121c 100644 --- a/lldb/docs/CMakeLists.txt +++ b/lldb/docs/CMakeLists.txt @@ -31,6 +31,7 @@ if (LLDB_ENABLE_PYTHON AND SPHINX_FOUND) COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_frame_provider.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_process.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" + COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_symbol_locator.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/operating_system.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_thread_plan.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" COMMENT "Copying lldb.py to pretend its a Python package.") diff --git a/lldb/docs/python_extensions.rst b/lldb/docs/python_extensions.rst index 8420187efcdcc..c02675ffb309d 100644 --- a/lldb/docs/python_extensions.rst +++ b/lldb/docs/python_extensions.rst @@ -38,6 +38,14 @@ Scripted Platform Plugins :skip: ABCMeta :no-inheritance-diagram: +Scripted Symbol Locator Plugins +----------------------------------- + +.. automodapi:: lldb.plugins.scripted_symbol_locator + :no-heading: + :skip: ABCMeta, LocalCacheSymbolLocator + :no-inheritance-diagram: + Scripted Thread Plan Plugins ------------------------------- diff --git a/lldb/docs/use/python-reference.rst b/lldb/docs/use/python-reference.rst index afca07520d8ad..3e7d56f4a2096 100644 --- a/lldb/docs/use/python-reference.rst +++ b/lldb/docs/use/python-reference.rst @@ -28,3 +28,4 @@ The following tutorials and documentation demonstrate various Python capabilitie tutorials/implementing-standalone-scripts tutorials/custom-frame-recognizers tutorials/extending-target-stop-hooks + tutorials/custom-symbol-resolution diff --git a/lldb/docs/use/tutorials/custom-symbol-resolution.md b/lldb/docs/use/tutorials/custom-symbol-resolution.md new file mode 100644 index 0000000000000..9d3edd2f7e57e --- /dev/null +++ b/lldb/docs/use/tutorials/custom-symbol-resolution.md @@ -0,0 +1,131 @@ +# Finding Symbols With a Scripted Symbol Locator + +The **Scripted Symbol Locator** lets you write a Python class that tells LLDB +where to find source files for your debug targets. This is useful when your +build artifacts live in a custom location, such as a symbol server or a local +build-ID-indexed cache. + +## Quick Start + +1. **Write a locator class.** Create a Python file (e.g., `my_locator.py`) + with a class that implements the methods you need: + + ```python + import os + import lldb + from lldb.plugins.scripted_symbol_locator import ScriptedSymbolLocator + + class MyLocator(ScriptedSymbolLocator): + def __init__(self, exe_ctx, args): + super().__init__(exe_ctx, args) + self.cache_dir = None + if self.args and self.args.IsValid(): + d = self.args.GetValueForKey("cache_dir") + if d and d.IsValid(): + self.cache_dir = d.GetStringValue(4096) + + def locate_source_file(self, module, original_source_file): + """Return the resolved file spec, or None to fall through.""" + if not self.cache_dir: + return None + uuid = module.GetUUIDString() + basename = os.path.basename(original_source_file) + candidate = os.path.join(self.cache_dir, uuid, "src", basename) + if os.path.exists(candidate): + return lldb.SBFileSpec(candidate, True) + return None + ``` + +2. **Import the script and register the locator globally:** + + ``` + (lldb) command script import /path/to/my_locator.py + (lldb) target symbols scripted register \ + -C my_locator.MyLocator \ + -k cache_dir -v /path/to/cache + ``` + +3. **Debug normally.** When LLDB resolves source files for any target, + your `locate_source_file` method will be called automatically. + +## Available Methods + +Your locator class must implement `__init__` and `locate_source_file`. + +| Method | Called When | +|--------|------------| +| `locate_source_file(module, path)` | LLDB resolves a source file path in debug info | + +### Method Signatures + +```python +def __init__(self, exe_ctx: lldb.SBExecutionContext, + args: lldb.SBStructuredData) -> None: + ... + +def locate_source_file(self, module: lldb.SBModule, + original_source_file: str) -> Optional[lldb.SBFileSpec]: + ... +``` + +## Global Registration + +Scripted symbol locators are registered **globally** (not per-target), +following the Debuginfod model. Multiple locators can be registered; +each is called in order until one returns a result. To filter by +platform/architecture, inspect the module's triple or UUID in each +callback and return `None` for non-matching modules. + +### Commands + +| Command | Description | +|---------|-------------| +| `target symbols scripted register -C <class> [-k <key> -v <value> ...]` | Register a locator globally | +| `target symbols scripted clear` | Clear all registered locators | +| `target symbols scripted info` | List all registered locators | + +### SB API + +You can also register locators programmatically via `SBDebugger`: + +```python +import lldb + +args = lldb.SBStructuredData() +args.SetFromJSON('{"cache_dir": "/path/to/cache"}') +error = debugger.RegisterScriptedSymbolLocator( + "my_locator.MyLocator", args) + +debugger.ClearScriptedSymbolLocators() +``` + +## Caching + +Source file resolutions are cached per `(module UUID, source file path)` pair +within each locator instance. The cache is cleared when: + +- All locators are cleared (via `clear` or `ClearScriptedSymbolLocators()`) + +This means your `locate_source_file` method is called at most once per +unique `(UUID, path)` combination per locator instance. + +## Base Class Template + +LLDB ships a base class template at `lldb.plugins.scripted_symbol_locator`. +You can import and subclass it: + +```python +from lldb.plugins.scripted_symbol_locator import ScriptedSymbolLocator + +class MyLocator(ScriptedSymbolLocator): + def __init__(self, exe_ctx, args): + super().__init__(exe_ctx, args) + + def locate_source_file(self, module, original_source_file): + # Your implementation here + return None +``` + +The base class handles argument extraction. See +`lldb/examples/python/templates/scripted_symbol_locator.py` for the full +template with docstrings. diff --git a/lldb/examples/python/templates/scripted_symbol_locator.py b/lldb/examples/python/templates/scripted_symbol_locator.py new file mode 100644 index 0000000000000..71e5d6bf808af --- /dev/null +++ b/lldb/examples/python/templates/scripted_symbol_locator.py @@ -0,0 +1,185 @@ +from abc import ABCMeta, abstractmethod +import os + +import lldb + + +class ScriptedSymbolLocator(metaclass=ABCMeta): + """ + The base class for a scripted symbol locator. + + Scripted symbol locators are registered globally (not per-target) + and are consulted for all symbol/source resolution requests across + all targets. Multiple locators can be registered; each is called + in order until one returns a result. + + All callback methods are optional and return ``None`` (or ``False`` + for ``download_object_and_symbol_file``) to fall through to the + next locator or LLDB's default resolution. + + To filter by platform/architecture, inspect the module's triple + or UUID in each callback and return ``None`` for non-matching + modules. + + Configuration:: + + (lldb) command script import /path/to/my_locator.py + (lldb) target symbols scripted register -C my_locator.MyLocator \\ + [-k key -v value ...] + """ + + @abstractmethod + def __init__(self, exe_ctx, args): + """Construct a scripted symbol locator. + + Args: + exe_ctx (lldb.SBExecutionContext): The execution context for + the scripted symbol locator. This will be empty (no target) + since locators are registered globally. + args (lldb.SBStructuredData): A Dictionary holding arbitrary + key/value pairs used by the scripted symbol locator. + """ + self.args = None + if isinstance(args, lldb.SBStructuredData) and args.IsValid(): + self.args = args + + def locate_source_file(self, module, original_source_file): + """Locate the source file for a given module. + + Called when LLDB resolves source file paths during stack frame + display, breakpoint resolution, or source listing. This is the + primary method for implementing source file remapping based on + build IDs. + + The module is a fully loaded ``SBModule`` (not an ``SBModuleSpec``), + so you can access its UUID, file path, platform file path, + symbol file path, sections, and symbols. + + Results are cached per (module UUID, source file) pair per + locator instance, so this method is called at most once per + unique combination. + + Args: + module (lldb.SBModule): The loaded module containing debug + info. Use ``module.GetUUIDString()`` to get the build ID + for looking up the correct source revision. + original_source_file (str): The original source file path + as recorded in the debug info. + + Returns: + lldb.SBFileSpec: The resolved file spec, or None to fall + through to the next locator or LLDB's default resolution. + """ + return None + + def locate_executable_object_file(self, module_spec): + """Locate the executable object file for a given module spec. + + Called when LLDB needs to find the executable binary for a module + (e.g., when loading a core dump or attaching to a process). + + Args: + module_spec (lldb.SBModuleSpec): The module specification + containing UUID, architecture, and file path hints. + + Returns: + lldb.SBModuleSpec: A module spec with the resolved file path, + or None to fall through. + """ + return None + + def locate_executable_symbol_file(self, module_spec): + """Locate the symbol file for a given module spec. + + Called when LLDB needs to find debug symbols (e.g., .dSYM, .debug, + or separate .pdb files) for a module. + + Args: + module_spec (lldb.SBModuleSpec): The module specification + containing UUID, architecture, and file path hints. + + Returns: + lldb.SBFileSpec: The resolved symbol file path, or None + to fall through. + """ + return None + + def download_object_and_symbol_file(self, module_spec): + """Download the object file and/or symbol file for a module. + + Called when LLDB needs to download both the executable and its + symbols (e.g., from a symbol server). + + Args: + module_spec (lldb.SBModuleSpec): The module specification. + This may be modified in place to set the resolved paths. + + Returns: + bool: True if files were successfully downloaded, False + to fall through. + """ + return False + + +class LocalCacheSymbolLocator(ScriptedSymbolLocator): + """Example locator that resolves source files from a local cache directory. + + Demonstrates how to subclass ``ScriptedSymbolLocator`` to implement + custom source file resolution. This locator looks up source files + in a local directory structure organized by build ID (UUID):: + + <cache_dir>/ + <uuid>/ + src/ + main.cpp + ... + + Usage:: + + (lldb) command script import scripted_symbol_locator + (lldb) target symbols scripted register \\ + -C scripted_symbol_locator.LocalCacheSymbolLocator \\ + -k cache_dir -v "/path/to/cache" + (lldb) target create --core /path/to/minidump.dmp + (lldb) bt + + The locator searches for: + - Source files: ``<cache_dir>/<uuid>/src/<basename>`` + """ + + cache_dir = None + + def __init__(self, exe_ctx, args): + super().__init__(exe_ctx, args) + + # Allow cache_dir to be set via structured data args. + if self.args: + cache_dir_val = self.args.GetValueForKey("cache_dir") + if cache_dir_val and cache_dir_val.IsValid(): + val = cache_dir_val.GetStringValue(256) + if val: + LocalCacheSymbolLocator.cache_dir = val + + def _get_cache_path(self, uuid_str, *components): + """Build a path under the cache directory for a given UUID. + + Args: + uuid_str (str): The module's UUID string. + *components: Additional path components (e.g., filename). + + Returns: + str: The full path, or None if cache_dir is not set or the + UUID is empty. + """ + if not self.cache_dir or not uuid_str: + return None + return os.path.join(self.cache_dir, uuid_str, *components) + + def locate_source_file(self, module, original_source_file): + """Look up source files under ``<cache_dir>/<uuid>/src/``.""" + uuid_str = module.GetUUIDString() + basename = os.path.basename(original_source_file) + path = self._get_cache_path(uuid_str, "src", basename) + if path and os.path.exists(path): + return lldb.SBFileSpec(path, True) + return None diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 688fc9197965c..006d23ceb9490 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -667,6 +667,26 @@ class LLDB_API SBDebugger { SBTrace LoadTraceFromFile(SBError &error, const SBFileSpec &trace_description_file); + /// Register a scripted symbol locator globally. + /// + /// Scripted symbol locators are consulted for all symbol/source + /// resolution requests across all targets. Multiple locators can be + /// registered; each is called in order until one returns a result. + /// + /// \param[in] class_name + /// The Python class implementing the symbol locator. + /// + /// \param[in] args + /// Optional structured data arguments passed to the locator. + /// + /// \return + /// An SBError indicating success or failure. + lldb::SBError RegisterScriptedSymbolLocator(const char *class_name, + lldb::SBStructuredData &args); + + /// Clear all registered scripted symbol locators. + void ClearScriptedSymbolLocators(); + protected: friend class lldb_private::CommandPluginInterfaceImplementation; friend class lldb_private::python::SWIGBridge; diff --git a/lldb/include/lldb/API/SBFileSpec.h b/lldb/include/lldb/API/SBFileSpec.h index 36641843aabeb..4b0b640dd4dbc 100644 --- a/lldb/include/lldb/API/SBFileSpec.h +++ b/lldb/include/lldb/API/SBFileSpec.h @@ -11,6 +11,10 @@ #include "lldb/API/SBDefines.h" +namespace lldb_private { +class ScriptInterpreter; +} + namespace lldb { class LLDB_API SBFileSpec { @@ -79,6 +83,7 @@ class LLDB_API SBFileSpec { friend class SBThread; friend class SBTrace; friend class SBSaveCoreOptions; + friend class lldb_private::ScriptInterpreter; SBFileSpec(const lldb_private::FileSpec &fspec); diff --git a/lldb/include/lldb/API/SBModule.h b/lldb/include/lldb/API/SBModule.h index 4009ca1461e51..3e8e5b99f6404 100644 --- a/lldb/include/lldb/API/SBModule.h +++ b/lldb/include/lldb/API/SBModule.h @@ -311,6 +311,7 @@ class LLDB_API SBModule { friend class SBType; friend class lldb_private::python::SWIGBridge; + friend class lldb_private::ScriptInterpreter; explicit SBModule(const lldb::ModuleSP &module_sp); diff --git a/lldb/include/lldb/API/SBModuleSpec.h b/lldb/include/lldb/API/SBModuleSpec.h index 0e7f0f3489596..d1252cb8e9c8e 100644 --- a/lldb/include/lldb/API/SBModuleSpec.h +++ b/lldb/include/lldb/API/SBModuleSpec.h @@ -12,6 +12,13 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBFileSpec.h" +namespace lldb_private { +class ScriptInterpreter; +namespace python { +class SWIGBridge; +} // namespace python +} // namespace lldb_private + namespace lldb { class LLDB_API SBModuleSpec { @@ -102,6 +109,8 @@ class LLDB_API SBModuleSpec { friend class SBModule; friend class SBPlatform; friend class SBTarget; + friend class lldb_private::ScriptInterpreter; + friend class lldb_private::python::SWIGBridge; SBModuleSpec(const lldb_private::ModuleSpec &module_spec); diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index 4d116f52460ff..2e3aeed8718... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/183678 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
