llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Med Ismail Bennani (medismailben) <details> <summary>Changes</summary> This patch re-lands #<!-- -->105449 and fixes the various test failures. --- Patch is 36.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/109498.diff 22 Files Affected: - (modified) lldb/bindings/python/python-swigsafecast.swig (+1-1) - (modified) lldb/bindings/python/python-wrapper.swig (+13-98) - (modified) lldb/include/lldb/API/SBExecutionContext.h (+2) - (added) lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h (+33) - (modified) lldb/include/lldb/Interpreter/ScriptInterpreter.h (+8-18) - (modified) lldb/include/lldb/Target/Target.h (+1-2) - (modified) lldb/include/lldb/lldb-forward.h (+3) - (modified) lldb/source/Interpreter/ScriptInterpreter.cpp (+6) - (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 (+19) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h (+38-6) - (added) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp (+75) - (added) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h (+51) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h (+2-11) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp (+5-51) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h (+2-9) - (modified) lldb/source/Target/Target.cpp (+32-10) - (modified) lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py (+2-2) - (modified) lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py (+1-1) - (modified) lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp (+6-15) ``````````diff diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig index 0127ac6bfa4681..7a4f7e81f1cc3b 100644 --- a/lldb/bindings/python/python-swigsafecast.swig +++ b/lldb/bindings/python/python-swigsafecast.swig @@ -33,7 +33,7 @@ PythonObject SWIGBridge::ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp) { SWIGTYPE_p_lldb__SBBreakpoint); } -PythonObject SWIGBridge::ToSWIGWrapper(Status status) { +PythonObject SWIGBridge::ToSWIGWrapper(Status&& status) { return ToSWIGHelper(new lldb::SBError(std::move(status)), SWIGTYPE_p_lldb__SBError); } diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 810673aaec5d19..961fb2d1a76178 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -301,104 +301,6 @@ unsigned int lldb_private::python::SWIGBridge::LLDBSwigPythonCallBreakpointResol return ret_val; } -PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedStopHook( - lldb::TargetSP target_sp, const char *python_class_name, - const char *session_dictionary_name, const StructuredDataImpl &args_impl, - Status &error) { - if (python_class_name == NULL || python_class_name[0] == '\0') { - error = Status::FromErrorString("Empty class name."); - return PythonObject(); - } - if (!session_dictionary_name) { - error = Status::FromErrorString("No session dictionary"); - return PythonObject(); - } - - PyErr_Cleaner py_err_cleaner(true); - - auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>( - session_dictionary_name); - auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>( - python_class_name, dict); - - if (!pfunc.IsAllocated()) { - error = Status::FromErrorStringWithFormat("Could not find class: %s.", - python_class_name); - return PythonObject(); - } - - PythonObject result = - pfunc(SWIGBridge::ToSWIGWrapper(target_sp), SWIGBridge::ToSWIGWrapper(args_impl), dict); - - if (result.IsAllocated()) { - // Check that the handle_stop callback is defined: - auto callback_func = result.ResolveName<PythonCallable>("handle_stop"); - if (callback_func.IsAllocated()) { - if (auto args_info = callback_func.GetArgInfo()) { - size_t num_args = (*args_info).max_positional_args; - if (num_args != 2) { - error = Status::FromErrorStringWithFormat( - "Wrong number of args for " - "handle_stop callback, should be 2 (excluding self), got: %zu", - num_args); - return PythonObject(); - } else - return result; - } else { - error = Status::FromErrorString( - "Couldn't get num arguments for handle_stop " - "callback."); - return PythonObject(); - } - return result; - } else { - error = Status::FromErrorStringWithFormat( - "Class \"%s\" is missing the required " - "handle_stop callback.", - python_class_name); - } - } - return PythonObject(); -} - -bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop( - void *implementor, lldb::ExecutionContextRefSP exc_ctx_sp, - lldb::StreamSP stream) { - // handle_stop will return a bool with the meaning "should_stop"... - // If you return nothing we'll assume we are going to stop. - // Also any errors should return true, since we should stop on error. - - PyErr_Cleaner py_err_cleaner(false); - PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor)); - auto pfunc = self.ResolveName<PythonCallable>("handle_stop"); - - if (!pfunc.IsAllocated()) - return true; - - std::shared_ptr<lldb::SBStream> sb_stream = std::make_shared<lldb::SBStream>(); - PythonObject sb_stream_arg = SWIGBridge::ToSWIGWrapper(sb_stream); - PythonObject result = - pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg); - - if (PyErr_Occurred()) { - stream->PutCString("Python error occurred handling stop-hook."); - PyErr_Print(); - PyErr_Clear(); - return true; - } - - // Now add the result to the output stream. SBStream only - // makes an internally help StreamString which I can't interpose, so I - // have to copy it over here. - stream->PutCString(sb_stream->GetData()); - sb_stream_arg.release(); - - if (result.get() == Py_False) - return false; - else - return true; -} - // wrapper that calls an optional instance member of an object taking no // arguments static PyObject *LLDBSwigPython_CallOptionalMember( @@ -677,6 +579,19 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyOb return sb_ptr; } +void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject * + data) { + lldb::SBExecutionContext *sb_ptr = NULL; + + int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr, + SWIGTYPE_p_lldb__SBExecutionContext, 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/include/lldb/API/SBExecutionContext.h b/lldb/include/lldb/API/SBExecutionContext.h index e8de2ebe58785e..e1e08fe3f4aae4 100644 --- a/lldb/include/lldb/API/SBExecutionContext.h +++ b/lldb/include/lldb/API/SBExecutionContext.h @@ -16,6 +16,7 @@ #include <vector> namespace lldb_private { +class ScriptInterpreter; namespace python { class SWIGBridge; } @@ -55,6 +56,7 @@ class LLDB_API SBExecutionContext { protected: friend class lldb_private::python::SWIGBridge; + friend class lldb_private::ScriptInterpreter; lldb_private::ExecutionContextRef *get() const; diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h new file mode 100644 index 00000000000000..a829e62351fe85 --- /dev/null +++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h @@ -0,0 +1,33 @@ +//===-- ScriptedStopHookInterface.h -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTOPHOOKINTERFACE_H +#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTOPHOOKINTERFACE_H + +#include "lldb/lldb-private.h" + +#include "ScriptedInterface.h" + +namespace lldb_private { +class ScriptedStopHookInterface : public ScriptedInterface { +public: + virtual llvm::Expected<StructuredData::GenericSP> + CreatePluginObject(llvm::StringRef class_name, lldb::TargetSP target_sp, + const StructuredDataImpl &args_sp) = 0; + + /// "handle_stop" will return a bool with the meaning "should_stop"... + /// If nothing is returned, we'll assume we are going to stop. + /// Also any errors should return true, since we should stop on error. + virtual llvm::Expected<bool> HandleStop(ExecutionContext &exe_ctx, + lldb::StreamSP &output_sp) { + return true; + } +}; +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTOPHOOKINTERFACE_H diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index addb1394ab5652..901ecf3012d51d 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -14,6 +14,7 @@ #include "lldb/API/SBData.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" +#include "lldb/API/SBExecutionContext.h" #include "lldb/API/SBLaunchInfo.h" #include "lldb/API/SBMemoryRegionInfo.h" #include "lldb/API/SBStream.h" @@ -271,24 +272,6 @@ class ScriptInterpreter : public PluginInterface { return lldb::eSearchDepthModule; } - virtual StructuredData::GenericSP - CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, - const StructuredDataImpl &args_data, Status &error) { - error = - Status::FromErrorString("Creating scripted stop-hooks with the current " - "script interpreter is not supported."); - return StructuredData::GenericSP(); - } - - // This dispatches to the handle_stop method of the stop-hook class. It - // returns a "should_stop" bool. - virtual bool - ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, - ExecutionContext &exc_ctx, - lldb::StreamSP stream_sp) { - return true; - } - virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { return StructuredData::ObjectSP(); @@ -561,6 +544,10 @@ class ScriptInterpreter : public PluginInterface { return {}; } + virtual lldb::ScriptedStopHookInterfaceSP CreateScriptedStopHookInterface() { + return {}; + } + virtual StructuredData::ObjectSP CreateStructuredDataFromScriptObject(ScriptObject obj) { return {}; @@ -587,6 +574,9 @@ class ScriptInterpreter : public PluginInterface { std::optional<MemoryRegionInfo> GetOpaqueTypeFromSBMemoryRegionInfo( const lldb::SBMemoryRegionInfo &mem_region) const; + lldb::ExecutionContextRefSP GetOpaqueTypeFromSBExecutionContext( + const lldb::SBExecutionContext &exe_ctx) const; + protected: Debugger &m_debugger; lldb::ScriptLanguage m_script_lang; diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 50df01aac74004..e4848f19e64d62 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -1391,8 +1391,7 @@ class Target : public std::enable_shared_from_this<Target>, /// This holds the dictionary of keys & values that can be used to /// parametrize any given callback's behavior. StructuredDataImpl m_extra_args; - /// This holds the python callback object. - StructuredData::GenericSP m_implementation_sp; + lldb::ScriptedStopHookInterfaceSP m_interface_sp; /// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer /// and fill it with commands, and SetSpecifier to set the specifier shared diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 5fb288ad43af48..d09edeeccaff1a 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -190,6 +190,7 @@ class ScriptInterpreterLocker; class ScriptedMetadata; class ScriptedPlatformInterface; class ScriptedProcessInterface; +class ScriptedStopHookInterface; class ScriptedThreadInterface; class ScriptedThreadPlanInterface; class ScriptedSyntheticChildren; @@ -408,6 +409,8 @@ typedef std::unique_ptr<lldb_private::ScriptedPlatformInterface> ScriptedPlatformInterfaceUP; typedef std::unique_ptr<lldb_private::ScriptedProcessInterface> ScriptedProcessInterfaceUP; +typedef std::shared_ptr<lldb_private::ScriptedStopHookInterface> + ScriptedStopHookInterfaceSP; typedef std::shared_ptr<lldb_private::ScriptedThreadInterface> ScriptedThreadInterfaceSP; typedef std::shared_ptr<lldb_private::ScriptedThreadPlanInterface> diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp index 8b55221da6e761..559b8301c10106 100644 --- a/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -125,6 +125,12 @@ ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo( return *mem_region.m_opaque_up.get(); } +lldb::ExecutionContextRefSP +ScriptInterpreter::GetOpaqueTypeFromSBExecutionContext( + const lldb::SBExecutionContext &exe_ctx) const { + return exe_ctx.m_exe_ctx_sp; +} + lldb::ScriptLanguage ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) { if (language.equals_insensitive(LanguageToString(eScriptLanguageNone))) diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt index 6ba714ed1c263e..ee5e48ad5cdc37 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt @@ -25,6 +25,7 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces PLUGIN ScriptedPlatformPythonInterface.cpp ScriptedProcessPythonInterface.cpp ScriptedPythonInterface.cpp + ScriptedStopHookPythonInterface.cpp ScriptedThreadPlanPythonInterface.cpp ScriptedThreadPythonInterface.cpp diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp index 38b644366080e4..1fd32993e385eb 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp @@ -28,6 +28,7 @@ void ScriptInterpreterPythonInterfaces::Initialize() { OperatingSystemPythonInterface::Initialize(); ScriptedPlatformPythonInterface::Initialize(); ScriptedProcessPythonInterface::Initialize(); + ScriptedStopHookPythonInterface::Initialize(); ScriptedThreadPlanPythonInterface::Initialize(); } @@ -35,6 +36,7 @@ void ScriptInterpreterPythonInterfaces::Terminate() { OperatingSystemPythonInterface::Terminate(); ScriptedPlatformPythonInterface::Terminate(); ScriptedProcessPythonInterface::Terminate(); + ScriptedStopHookPythonInterface::Terminate(); ScriptedThreadPlanPythonInterface::Terminate(); } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h index 36b521480cc85c..26c80b75686918 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h @@ -18,6 +18,7 @@ #include "OperatingSystemPythonInterface.h" #include "ScriptedPlatformPythonInterface.h" #include "ScriptedProcessPythonInterface.h" +#include "ScriptedStopHookPythonInterface.h" #include "ScriptedThreadPlanPythonInterface.h" namespace lldb_private { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp index a8e1d09da0bf12..cf11c06e8a95d4 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp @@ -159,4 +159,23 @@ ScriptedPythonInterface::ExtractValueFromPythonObject< return m_interpreter.GetOpaqueTypeFromSBMemoryRegionInfo(*sb_mem_reg_info); } +template <> +lldb::ExecutionContextRefSP +ScriptedPythonInterface::ExtractValueFromPythonObject< + lldb::ExecutionContextRefSP>(python::PythonObject &p, Status &error) { + + lldb::SBExecutionContext *sb_exe_ctx = + reinterpret_cast<lldb::SBExecutionContext *>( + python::LLDBSWIGPython_CastPyObjectToSBExecutionContext(p.get())); + + if (!sb_exe_ctx) { + error = Status::FromErrorStringWithFormat( + "Couldn't cast lldb::SBExecutionContext to " + "lldb::ExecutionContextRefSP."); + return {}; + } + + return m_interpreter.GetOpaqueTypeFromSBExecutionContext(*sb_exe_ctx); +} + #endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h index c715295eb9ff02..4b9f463ef5605d 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h @@ -180,12 +180,35 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { llvm::Expected<PythonObject> expected_return_object = create_error("Resulting object is not initialized."); - std::apply( - [&init, &expected_return_object](auto &&...args) { - llvm::consumeError(expected_return_object.takeError()); - expected_return_object = init(args...); - }, - transformed_args); + // This relax the requirement on the number of argument for + // initializing scripting extension if the size of the interface + // parameter pack contains 1 less element than the extension maximum + // number of positional arguments for this initializer. + // + // This addresses the cases where the embedded interpreter session + // dictionary is passed to the extension initializer which is not used + // most of the time. + size_t num_args = sizeof...(Args); + if (num_args != arg_info->max_positional_args) { + if (num_args != arg_info->max_positional_args - 1) + return create_error("Passed arguments ({0}) doesn't match the number " + "of expected arguments ({1}).", + num_args, arg_info->max_positional_args); + + std::apply( + [&init, &expected_return_object](auto &&...args) { + llvm::consumeError(expected_return_object.takeError()); + expected_return_object = init(args...); + }, + std::tuple_cat(transformed_args, std::make_tuple(dict))); + } else { + std::apply( + [&init, &expected_return_object](auto &&...args) { + llvm::consumeError(expected_return_object.takeError()); + expected_return_object = init(args...); + }, + transformed_args); + } if (!expected_return_object) return expected_return_object.takeError(); @@ -405,6 +428,10 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { return python::SWIGBridge::ToSWIGWrapper(arg); } + python::PythonObject Transform(lldb::TargetSP arg) { + return python::SWIGBridge::ToSWIGWrapper(arg); + } + python::PythonObject Transform(lldb::ProcessSP arg) { return python::SWIGBridge::ToSWIGWrapper(arg); } @@ -557,6 +584,11 @@ std::optional<MemoryRegionInfo> ScriptedPythonInterface::ExtractValueFromPythonObject< std::optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error); +template <> +lldb::ExecutionContextRefSP +ScriptedPythonInterface::ExtractValueFromPythonObject< + lldb::ExecutionContextRefSP>(python::PythonObject &p, Status &error); + } // namespace lldb_private #endif // LLDB_ENABLE_PYTHON diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp new file mode 100644 index 00000000000000..eb052c24bab6da --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp @@ -0,0 +1,75 @@ +//===-- ScriptedStopHookPythonInterface.cpp -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/PluginManager.h" +#include "lldb/Host/Config.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/Log.h" +#include "lldb/lldb-enumerations.h" + +#if LLDB_ENABLE_PYTHON + +// clang-format off +// LLDB Python header must be included first +#include "../lldb-python.h" +//clang-format on + +#include "../SWIGPythonBridge.h" +#include "../ScriptInterpreterPythonImpl.h" +#include "ScriptedStopHookPythonInterface.h" + +using namespa... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/109498 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits