[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
DavidSpickett wrote: Once my comments are addressed this will be good to land. Only concern was changing the default behaviour, and this PR does not go anywhere near that now. https://github.com/llvm/llvm-project/pull/143126 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
@@ -88,3 +88,10 @@ def test_save_core_via_process_plugin(self): os.unlink(core) except OSError: pass + +def test_help(self): +"""Test that help shows minidump as an option in plugin-names.""" DavidSpickett wrote: It's more that it shows all plugins capable of writing a core and for now that is just minidump. https://github.com/llvm/llvm-project/pull/143126 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
@@ -16,4 +16,4 @@ run DavidSpickett wrote: I think you need a test for the error when a specific plugin name is given, vs when no name is given. https://github.com/llvm/llvm-project/pull/143126 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)
https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/144731 >From 3c9a3e5e9af0c9d58783c11490bda473ada84ef3 Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Wed, 18 Jun 2025 16:41:40 +0100 Subject: [PATCH 1/8] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected --- .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 266 -- 1 file changed, 110 insertions(+), 156 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 0f18abb47591d..1810c07652a2b 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -236,199 +236,140 @@ static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream, return true; } -static std::optional -GetDemangledBasename(const SymbolContext &sc) { +static llvm::Expected> +GetAndValidateInfo(const SymbolContext &sc) { Mangled mangled = sc.GetPossiblyInlinedFunctionName(); if (!mangled) -return std::nullopt; +return llvm::createStringError("Function does not have a mangled name."); auto demangled_name = mangled.GetDemangledName().GetStringRef(); if (demangled_name.empty()) -return std::nullopt; +return llvm::createStringError("Function does not have a demangled name."); const std::optional &info = mangled.GetDemangledInfo(); if (!info) -return std::nullopt; +return llvm::createStringError("Function does not have demangled info."); // Function without a basename is nonsense. if (!info->hasBasename()) -return std::nullopt; +return llvm::createStringError("Info do not have basename range."); - return demangled_name.slice(info->BasenameRange.first, - info->BasenameRange.second); + return std::make_pair(demangled_name, *info); } -static std::optional -GetDemangledTemplateArguments(const SymbolContext &sc) { - Mangled mangled = sc.GetPossiblyInlinedFunctionName(); - if (!mangled) -return std::nullopt; +static llvm::Expected +GetDemangledBasename(const SymbolContext &sc) { + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); - auto demangled_name = mangled.GetDemangledName().GetStringRef(); - if (demangled_name.empty()) -return std::nullopt; + auto [demangled_name, info] = *info_or_err; - const std::optional &info = mangled.GetDemangledInfo(); - if (!info) -return std::nullopt; + return demangled_name.slice(info.BasenameRange.first, + info.BasenameRange.second); +} - // Function without a basename is nonsense. - if (!info->hasBasename()) -return std::nullopt; +static llvm::Expected +GetDemangledTemplateArguments(const SymbolContext &sc) { + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); + + auto [demangled_name, info] = *info_or_err; - if (info->ArgumentsRange.first < info->BasenameRange.second) -return std::nullopt; + if (info.ArgumentsRange.first < info.BasenameRange.second) +return llvm::createStringError("Arguments in info are invalid."); - return demangled_name.slice(info->BasenameRange.second, - info->ArgumentsRange.first); + return demangled_name.slice(info.BasenameRange.second, + info.ArgumentsRange.first); } -static std::optional +static llvm::Expected GetDemangledReturnTypeLHS(const SymbolContext &sc) { - Mangled mangled = sc.GetPossiblyInlinedFunctionName(); - if (!mangled) -return std::nullopt; + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); - auto demangled_name = mangled.GetDemangledName().GetStringRef(); - if (demangled_name.empty()) -return std::nullopt; + auto [demangled_name, info] = *info_or_err; - const std::optional &info = mangled.GetDemangledInfo(); - if (!info) -return std::nullopt; + if (info.ScopeRange.first >= demangled_name.size()) +return llvm::createStringError("Scope range is invalid."); - // Function without a basename is nonsense. - if (!info->hasBasename()) -return std::nullopt; - - if (info->ScopeRange.first >= demangled_name.size()) -return std::nullopt; - - return demangled_name.substr(0, info->ScopeRange.first); + return demangled_name.substr(0, info.ScopeRange.first); } -static std::optional +static llvm::Expected GetDemangledFunctionQualifiers(const SymbolContext &sc) { - Mangled mangled = sc.GetPossiblyInlinedFunctionName(); - if (!mangled) -return std::nullopt; + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); - auto demangled_name = mangled.GetDemangledName().GetStringRef(); - if (demangled_name.empty()) -return std::nullopt; + auto [demangled_name, info] = *info_or_err; - const std::
[Lldb-commits] [lldb] [lldb][AIX] Added base file for AIX Register Context (PR #144645)
https://github.com/DavidSpickett edited https://github.com/llvm/llvm-project/pull/144645 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][target] Add progress report for wait-attaching to process (PR #144768)
DavidSpickett wrote: Though I cannot reproduce the failure, so it could be to do with the high load when run on the bots. Some process being deprioritised. https://github.com/llvm/llvm-project/pull/144768 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Socket::CreatePair (PR #145015)
https://github.com/labath created https://github.com/llvm/llvm-project/pull/145015 It creates a pair of connected sockets using the simplest mechanism for the given platform (TCP on windows, socketpair(2) elsewhere). Main motivation is to remove the ugly platform-specific code in ProcessGDBRemote::LaunchAndConnectToDebugserver, but it can also be used in other places where we need to create a pair of connected sockets. >From 54ef8f5e1ff3f3ea28605ffb9a90f0b0aa6b52af Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 19 Jun 2025 21:44:02 +0200 Subject: [PATCH] [lldb] Add Socket::CreatePair It creates a pair of connected sockets using the simplest mechanism for the given platform (TCP on windows, socketpair(2) elsewhere). Main motivation is to remove the ugly platform-specific code in ProcessGDBRemote::LaunchAndConnectToDebugserver, but it can also be used in other places where we need to create a pair of connected sockets. --- lldb/include/lldb/Host/Socket.h | 4 +++ lldb/include/lldb/Host/common/TCPSocket.h | 4 +++ lldb/include/lldb/Host/posix/DomainSocket.h | 4 +++ lldb/source/Host/common/Socket.cpp| 17 + lldb/source/Host/common/TCPSocket.cpp | 28 +++ lldb/source/Host/posix/DomainSocket.cpp | 29 +++ .../gdb-remote/GDBRemoteCommunication.cpp | 36 +-- lldb/unittests/Core/CommunicationTest.cpp | 26 -- lldb/unittests/Host/SocketTest.cpp| 35 ++ 9 files changed, 144 insertions(+), 39 deletions(-) diff --git a/lldb/include/lldb/Host/Socket.h b/lldb/include/lldb/Host/Socket.h index c313aa4f6d26b..14a9660ed30b7 100644 --- a/lldb/include/lldb/Host/Socket.h +++ b/lldb/include/lldb/Host/Socket.h @@ -106,6 +106,10 @@ class Socket : public IOObject { static std::unique_ptr Create(const SocketProtocol protocol, Status &error); + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(std::optional protocol = std::nullopt); + virtual Status Connect(llvm::StringRef name) = 0; virtual Status Listen(llvm::StringRef name, int backlog) = 0; diff --git a/lldb/include/lldb/Host/common/TCPSocket.h b/lldb/include/lldb/Host/common/TCPSocket.h index cb950c0015ea6..e81cb82dbcba1 100644 --- a/lldb/include/lldb/Host/common/TCPSocket.h +++ b/lldb/include/lldb/Host/common/TCPSocket.h @@ -23,6 +23,10 @@ class TCPSocket : public Socket { TCPSocket(NativeSocket socket, bool should_close); ~TCPSocket() override; + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(); + // returns port number or 0 if error uint16_t GetLocalPortNumber() const; diff --git a/lldb/include/lldb/Host/posix/DomainSocket.h b/lldb/include/lldb/Host/posix/DomainSocket.h index a840d474429ec..c3a6a64bbdef8 100644 --- a/lldb/include/lldb/Host/posix/DomainSocket.h +++ b/lldb/include/lldb/Host/posix/DomainSocket.h @@ -19,6 +19,10 @@ class DomainSocket : public Socket { DomainSocket(NativeSocket socket, bool should_close); explicit DomainSocket(bool should_close); + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(); + Status Connect(llvm::StringRef name) override; Status Listen(llvm::StringRef name, int backlog) override; diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp index 5c5cd653c3d9e..c9dec0f8ea22a 100644 --- a/lldb/source/Host/common/Socket.cpp +++ b/lldb/source/Host/common/Socket.cpp @@ -234,6 +234,23 @@ std::unique_ptr Socket::Create(const SocketProtocol protocol, return socket_up; } +llvm::Expected, std::unique_ptr>> +Socket::CreatePair(std::optional protocol) { + constexpr SocketProtocol kBestProtocol = + LLDB_ENABLE_POSIX ? ProtocolUnixDomain : ProtocolTcp; + switch (protocol.value_or(kBestProtocol)) { + case ProtocolTcp: +return TCPSocket::CreatePair(); +#if LLDB_ENABLE_POSIX + case ProtocolUnixDomain: + case ProtocolUnixAbstract: +return DomainSocket::CreatePair(); +#endif + default: +return llvm::createStringError("Unsupported protocol"); + } +} + llvm::Expected> Socket::TcpConnect(llvm::StringRef host_and_port) { Log *log = GetLog(LLDBLog::Connection); diff --git a/lldb/source/Host/common/TCPSocket.cpp b/lldb/source/Host/common/TCPSocket.cpp index 3d0dea1c61dd6..34f249746149e 100644 --- a/lldb/source/Host/common/TCPSocket.cpp +++ b/lldb/source/Host/common/TCPSocket.cpp @@ -52,6 +52,34 @@ TCPSocket::TCPSocket(NativeSocket socket, bool should_close) TCPSocket::~TCPSocket() { CloseListenSockets(); } +llvm::Expected< +std::pair, std::unique_ptr>> +TCPSocket::CreatePair() { + auto listen_socket_up = std::make_unique(true); + if (Status error = listen_socket_up->Listen("localhost:0", 5); error.Fail()) +return error.takeError(); + + std::string connect_address = + llvm::StringRef(listen_socket_up->GetListeningConnectionURI()[0]) + .split("://")
[Lldb-commits] [lldb] [lldb] Add Socket::CreatePair (PR #145015)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) Changes It creates a pair of connected sockets using the simplest mechanism for the given platform (TCP on windows, socketpair(2) elsewhere). Main motivation is to remove the ugly platform-specific code in ProcessGDBRemote::LaunchAndConnectToDebugserver, but it can also be used in other places where we need to create a pair of connected sockets. --- Full diff: https://github.com/llvm/llvm-project/pull/145015.diff 9 Files Affected: - (modified) lldb/include/lldb/Host/Socket.h (+4) - (modified) lldb/include/lldb/Host/common/TCPSocket.h (+4) - (modified) lldb/include/lldb/Host/posix/DomainSocket.h (+4) - (modified) lldb/source/Host/common/Socket.cpp (+17) - (modified) lldb/source/Host/common/TCPSocket.cpp (+28) - (modified) lldb/source/Host/posix/DomainSocket.cpp (+29) - (modified) lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (+8-28) - (modified) lldb/unittests/Core/CommunicationTest.cpp (+15-11) - (modified) lldb/unittests/Host/SocketTest.cpp (+35) ``diff diff --git a/lldb/include/lldb/Host/Socket.h b/lldb/include/lldb/Host/Socket.h index c313aa4f6d26b..14a9660ed30b7 100644 --- a/lldb/include/lldb/Host/Socket.h +++ b/lldb/include/lldb/Host/Socket.h @@ -106,6 +106,10 @@ class Socket : public IOObject { static std::unique_ptr Create(const SocketProtocol protocol, Status &error); + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(std::optional protocol = std::nullopt); + virtual Status Connect(llvm::StringRef name) = 0; virtual Status Listen(llvm::StringRef name, int backlog) = 0; diff --git a/lldb/include/lldb/Host/common/TCPSocket.h b/lldb/include/lldb/Host/common/TCPSocket.h index cb950c0015ea6..e81cb82dbcba1 100644 --- a/lldb/include/lldb/Host/common/TCPSocket.h +++ b/lldb/include/lldb/Host/common/TCPSocket.h @@ -23,6 +23,10 @@ class TCPSocket : public Socket { TCPSocket(NativeSocket socket, bool should_close); ~TCPSocket() override; + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(); + // returns port number or 0 if error uint16_t GetLocalPortNumber() const; diff --git a/lldb/include/lldb/Host/posix/DomainSocket.h b/lldb/include/lldb/Host/posix/DomainSocket.h index a840d474429ec..c3a6a64bbdef8 100644 --- a/lldb/include/lldb/Host/posix/DomainSocket.h +++ b/lldb/include/lldb/Host/posix/DomainSocket.h @@ -19,6 +19,10 @@ class DomainSocket : public Socket { DomainSocket(NativeSocket socket, bool should_close); explicit DomainSocket(bool should_close); + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(); + Status Connect(llvm::StringRef name) override; Status Listen(llvm::StringRef name, int backlog) override; diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp index 5c5cd653c3d9e..c9dec0f8ea22a 100644 --- a/lldb/source/Host/common/Socket.cpp +++ b/lldb/source/Host/common/Socket.cpp @@ -234,6 +234,23 @@ std::unique_ptr Socket::Create(const SocketProtocol protocol, return socket_up; } +llvm::Expected, std::unique_ptr>> +Socket::CreatePair(std::optional protocol) { + constexpr SocketProtocol kBestProtocol = + LLDB_ENABLE_POSIX ? ProtocolUnixDomain : ProtocolTcp; + switch (protocol.value_or(kBestProtocol)) { + case ProtocolTcp: +return TCPSocket::CreatePair(); +#if LLDB_ENABLE_POSIX + case ProtocolUnixDomain: + case ProtocolUnixAbstract: +return DomainSocket::CreatePair(); +#endif + default: +return llvm::createStringError("Unsupported protocol"); + } +} + llvm::Expected> Socket::TcpConnect(llvm::StringRef host_and_port) { Log *log = GetLog(LLDBLog::Connection); diff --git a/lldb/source/Host/common/TCPSocket.cpp b/lldb/source/Host/common/TCPSocket.cpp index 3d0dea1c61dd6..34f249746149e 100644 --- a/lldb/source/Host/common/TCPSocket.cpp +++ b/lldb/source/Host/common/TCPSocket.cpp @@ -52,6 +52,34 @@ TCPSocket::TCPSocket(NativeSocket socket, bool should_close) TCPSocket::~TCPSocket() { CloseListenSockets(); } +llvm::Expected< +std::pair, std::unique_ptr>> +TCPSocket::CreatePair() { + auto listen_socket_up = std::make_unique(true); + if (Status error = listen_socket_up->Listen("localhost:0", 5); error.Fail()) +return error.takeError(); + + std::string connect_address = + llvm::StringRef(listen_socket_up->GetListeningConnectionURI()[0]) + .split("://") + .second.str(); + + auto connect_socket_up = std::make_unique(true); + if (Status error = connect_socket_up->Connect(connect_address); error.Fail()) +return error.takeError(); + + // Connection has already been made above, so a short timeout is sufficient. + Socket *accept_socket; + if (Status error = + listen_socket_up->Accept(std::chrono::seconds(1), accept_socket); + error.Fail()) +return error.takeError(); + + return std::make_pair( + s
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/143126 >From fc849bd4e831f9dc6f53be3a8508e1eb33f4151c Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Fri, 6 Jun 2025 13:15:41 +0100 Subject: [PATCH 1/2] [lldb] add plugin names to process save-core error output. show the plugin names in when running `help plugin save-core` --- lldb/include/lldb/Core/PluginManager.h| 2 ++ lldb/source/Commands/CommandObjectProcess.cpp | 24 - lldb/source/Core/PluginManager.cpp| 27 +++ lldb/source/Symbol/SaveCoreOptions.cpp| 17 +--- .../process_save_core/TestProcessSaveCore.py | 7 + ...ommand-process-save-core-not-a-plugin.test | 2 +- 6 files changed, 69 insertions(+), 10 deletions(-) diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index e7b169103..0e917025ba41e 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -270,6 +270,8 @@ class PluginManager { static Status SaveCore(const lldb::ProcessSP &process_sp, lldb_private::SaveCoreOptions &core_options); + static std::vector GetSaveCorePluginNames(); + // ObjectContainer static bool RegisterPlugin( llvm::StringRef name, llvm::StringRef description, diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index b1f243c9e2777..0a1744277d7dc 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -1281,7 +1281,27 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed { ~CommandOptions() override = default; llvm::ArrayRef GetDefinitions() override { - return llvm::ArrayRef(g_process_save_core_options); + if (!m_opt_def.empty()) +return llvm::ArrayRef(m_opt_def); + + auto orig = llvm::ArrayRef(g_process_save_core_options); + m_opt_def.resize(orig.size()); + llvm::copy(g_process_save_core_options, m_opt_def.data()); + for (OptionDefinition &value : m_opt_def) { +llvm::StringRef opt_name = value.long_option; +if (opt_name != "plugin-name") + continue; + +std::vector plugin_names = +PluginManager::GetSaveCorePluginNames(); +m_plugin_enums.resize(plugin_names.size()); +for (auto [num, val] : llvm::zip(plugin_names, m_plugin_enums)) { + val.string_value = num.data(); +} +value.enum_values = llvm::ArrayRef(m_plugin_enums); +break; + } + return llvm::ArrayRef(m_opt_def); } Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, @@ -1312,6 +1332,8 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed { // Instance variables to hold the values for command options. SaveCoreOptions m_core_dump_options; +llvm::SmallVector m_plugin_enums; +std::vector m_opt_def; }; protected: diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index 5d44434033c55..94d66f0f929cd 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -843,11 +843,28 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, } // Check to see if any of the object file plugins tried and failed to save. - // If none ran, set the error message. - if (error.Success()) -error = Status::FromErrorString( -"no ObjectFile plugins were able to save a core for this process"); - return error; + // if any failure, return the error message. + if (error.Fail()) +return error; + + // Report only for the plugin that was specified. + if (!plugin_name.empty()) +return Status::FromErrorStringWithFormatv( +"The \"{}\" plugin is not able to save a core for this process.", +plugin_name); + + return Status::FromErrorString( + "no ObjectFile plugins were able to save a core for this process"); +} + +std::vector PluginManager::GetSaveCorePluginNames() { + std::vector plugin_names; + auto instances = GetObjectFileInstances().GetSnapshot(); + for (auto &instance : instances) { +if (instance.save_core) + plugin_names.emplace_back(instance.name); + } + return plugin_names; } #pragma mark ObjectContainer diff --git a/lldb/source/Symbol/SaveCoreOptions.cpp b/lldb/source/Symbol/SaveCoreOptions.cpp index d884b00a47b00..0f9dbb73c1721 100644 --- a/lldb/source/Symbol/SaveCoreOptions.cpp +++ b/lldb/source/Symbol/SaveCoreOptions.cpp @@ -21,9 +21,20 @@ Status SaveCoreOptions::SetPluginName(const char *name) { return error; } - if (!PluginManager::IsRegisteredObjectFilePluginName(name)) { -return Status::FromErrorStringWithFormat( -"plugin name '%s' is not a valid ObjectFile plugin name", name); + std::vector plugin_names = + PluginManager::GetSaveCorePluginNames(); + if (llvm::find(plugin_name
[Lldb-commits] [lldb] [lldb] Use Socket::CreatePair for launching debugserver (PR #145017)
https://github.com/labath created https://github.com/llvm/llvm-project/pull/145017 This lets get rid of platform-specific code in ProcessGDBRemote and use the same code path (module differences in socket types) everywhere. It also unlocks further cleanups in the debugserver launching code. Depends on #145015. (This PR consists of two commits, the first of which is equivalent to #145015. For reviewing, I recommend only looking at the second commit (if you have comments on the first commit, please put them on the first PR.) >From 54ef8f5e1ff3f3ea28605ffb9a90f0b0aa6b52af Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 19 Jun 2025 21:44:02 +0200 Subject: [PATCH 1/2] [lldb] Add Socket::CreatePair It creates a pair of connected sockets using the simplest mechanism for the given platform (TCP on windows, socketpair(2) elsewhere). Main motivation is to remove the ugly platform-specific code in ProcessGDBRemote::LaunchAndConnectToDebugserver, but it can also be used in other places where we need to create a pair of connected sockets. --- lldb/include/lldb/Host/Socket.h | 4 +++ lldb/include/lldb/Host/common/TCPSocket.h | 4 +++ lldb/include/lldb/Host/posix/DomainSocket.h | 4 +++ lldb/source/Host/common/Socket.cpp| 17 + lldb/source/Host/common/TCPSocket.cpp | 28 +++ lldb/source/Host/posix/DomainSocket.cpp | 29 +++ .../gdb-remote/GDBRemoteCommunication.cpp | 36 +-- lldb/unittests/Core/CommunicationTest.cpp | 26 -- lldb/unittests/Host/SocketTest.cpp| 35 ++ 9 files changed, 144 insertions(+), 39 deletions(-) diff --git a/lldb/include/lldb/Host/Socket.h b/lldb/include/lldb/Host/Socket.h index c313aa4f6d26b..14a9660ed30b7 100644 --- a/lldb/include/lldb/Host/Socket.h +++ b/lldb/include/lldb/Host/Socket.h @@ -106,6 +106,10 @@ class Socket : public IOObject { static std::unique_ptr Create(const SocketProtocol protocol, Status &error); + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(std::optional protocol = std::nullopt); + virtual Status Connect(llvm::StringRef name) = 0; virtual Status Listen(llvm::StringRef name, int backlog) = 0; diff --git a/lldb/include/lldb/Host/common/TCPSocket.h b/lldb/include/lldb/Host/common/TCPSocket.h index cb950c0015ea6..e81cb82dbcba1 100644 --- a/lldb/include/lldb/Host/common/TCPSocket.h +++ b/lldb/include/lldb/Host/common/TCPSocket.h @@ -23,6 +23,10 @@ class TCPSocket : public Socket { TCPSocket(NativeSocket socket, bool should_close); ~TCPSocket() override; + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(); + // returns port number or 0 if error uint16_t GetLocalPortNumber() const; diff --git a/lldb/include/lldb/Host/posix/DomainSocket.h b/lldb/include/lldb/Host/posix/DomainSocket.h index a840d474429ec..c3a6a64bbdef8 100644 --- a/lldb/include/lldb/Host/posix/DomainSocket.h +++ b/lldb/include/lldb/Host/posix/DomainSocket.h @@ -19,6 +19,10 @@ class DomainSocket : public Socket { DomainSocket(NativeSocket socket, bool should_close); explicit DomainSocket(bool should_close); + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(); + Status Connect(llvm::StringRef name) override; Status Listen(llvm::StringRef name, int backlog) override; diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp index 5c5cd653c3d9e..c9dec0f8ea22a 100644 --- a/lldb/source/Host/common/Socket.cpp +++ b/lldb/source/Host/common/Socket.cpp @@ -234,6 +234,23 @@ std::unique_ptr Socket::Create(const SocketProtocol protocol, return socket_up; } +llvm::Expected, std::unique_ptr>> +Socket::CreatePair(std::optional protocol) { + constexpr SocketProtocol kBestProtocol = + LLDB_ENABLE_POSIX ? ProtocolUnixDomain : ProtocolTcp; + switch (protocol.value_or(kBestProtocol)) { + case ProtocolTcp: +return TCPSocket::CreatePair(); +#if LLDB_ENABLE_POSIX + case ProtocolUnixDomain: + case ProtocolUnixAbstract: +return DomainSocket::CreatePair(); +#endif + default: +return llvm::createStringError("Unsupported protocol"); + } +} + llvm::Expected> Socket::TcpConnect(llvm::StringRef host_and_port) { Log *log = GetLog(LLDBLog::Connection); diff --git a/lldb/source/Host/common/TCPSocket.cpp b/lldb/source/Host/common/TCPSocket.cpp index 3d0dea1c61dd6..34f249746149e 100644 --- a/lldb/source/Host/common/TCPSocket.cpp +++ b/lldb/source/Host/common/TCPSocket.cpp @@ -52,6 +52,34 @@ TCPSocket::TCPSocket(NativeSocket socket, bool should_close) TCPSocket::~TCPSocket() { CloseListenSockets(); } +llvm::Expected< +std::pair, std::unique_ptr>> +TCPSocket::CreatePair() { + auto listen_socket_up = std::make_unique(true); + if (Status error = listen_socket_up->Listen("localhost:0", 5); error.Fail()) +return error.takeError(); + + std::string connect
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
da-viper wrote: The mach-o plugin works but the pecoff is an alias to minidump https://github.com/llvm/llvm-project/blob/4ec6d127c1857e77d70236b15b03d23ba1283a3d/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp#L6642-L6670 https://github.com/llvm/llvm-project/blob/4ec6d127c1857e77d70236b15b03d23ba1283a3d/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp#L358-L365 https://github.com/llvm/llvm-project/pull/143126 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)
@@ -2008,38 +1979,54 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable( return true; } case FormatEntity::Entry::Type::FunctionReturnRight: { -std::optional return_rhs = GetDemangledReturnTypeRHS(sc); -if (!return_rhs) +auto return_rhs_or_err = GetDemangledReturnTypeRHS(sc); +if (!return_rhs_or_err) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_rhs_or_err.takeError(), + "Failed to handle ${function.return-right} frame-format " + "variable: {0}"); return false; +} -s << *return_rhs; +s << *return_rhs_or_err; return true; } case FormatEntity::Entry::Type::FunctionReturnLeft: { -std::optional return_lhs = GetDemangledReturnTypeLHS(sc); -if (!return_lhs) +auto return_lhs_or_err = GetDemangledReturnTypeLHS(sc); +if (!return_lhs_or_err) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_lhs_or_err.takeError(), + "Failed to handle ${function.return-left} frame-format " + "variable: {0}"); return false; +} -s << *return_lhs; +s << *return_lhs_or_err; return true; } case FormatEntity::Entry::Type::FunctionQualifiers: { -std::optional quals = GetDemangledFunctionQualifiers(sc); -if (!quals) +auto quals_or_err = GetDemangledFunctionQualifiers(sc); +if (!quals_or_err) { + LLDB_LOG_ERROR( + GetLog(LLDBLog::Language), quals_or_err.takeError(), + "Failed to handle ${function.qualifiers} frame-format variable: {0}"); Michael137 wrote: Apologies, I think you need to escape the `{` here. Since that's the syntax for specifying the format index. I think `{{` is the way to do that https://github.com/llvm/llvm-project/pull/144731 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/144998 Starting with https://github.com/llvm/llvm-project/pull/124790, Clang emits `DW_AT_object_pointer` encoded as integer constants rather than DIE references. This patch accounts for this. >From 22e8f644c3cd8856e1663bdf71aab4fa621f75bf Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 29 Jan 2025 12:15:35 + Subject: [PATCH] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer Starting with https://github.com/llvm/llvm-project/pull/124790, Clang emits `DW_AT_object_pointer` encoded as integer constants rather than DIE references. This patch accounts for this. --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 47 +++-- .../x86/explicit-member-function-quals.cpp| 21 +- .../DWARF/DWARFASTParserClangTests.cpp| 196 ++ 3 files changed, 244 insertions(+), 20 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 4f79c8aa3f811..7d699434ca3c8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -174,23 +174,46 @@ DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram, if (!decl_ctx_die.IsStructUnionOrClass()) return {}; - if (DWARFDIE object_parameter = - subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer)) -return object_parameter; + // The DW_AT_object_pointer may be either encoded as a reference to a DIE, + // in which case that's the object parameter we want. Or it can be a constant + // index of the parameter. + std::optional object_pointer_index; + DWARFFormValue form_value; + if (subprogram.GetDIE()->GetAttributeValue( + subprogram.GetCU(), DW_AT_object_pointer, form_value, + /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) { +if (auto ref = form_value.Reference()) + return ref; + +object_pointer_index = form_value.Unsigned(); + } + + // Try to find the DW_TAG_formal_parameter via object_pointer_index. + DWARFDIE object_pointer; + size_t param_index = 0; + for (const auto &child : subprogram.children()) { +if (child.Tag() != DW_TAG_formal_parameter) + continue; - // If no DW_AT_object_pointer was specified, assume the implicit object - // parameter is the first parameter to the function, is called "this" and is - // artificial (which is what most compilers would generate). - auto children = subprogram.children(); - auto it = llvm::find_if(children, [](const DWARFDIE &child) { -return child.Tag() == DW_TAG_formal_parameter; - }); +if (param_index == object_pointer_index.value_or(0)) + object_pointer = child; + +++param_index; + } - if (it == children.end()) + // No formal parameter found for object pointer index. + // Nothing to be done. + if (!object_pointer) return {}; - DWARFDIE object_pointer = *it; + // We found the object pointer encoded via DW_AT_object_pointer. + // No need for the remaining heuristics. + if (object_pointer_index) +return object_pointer; + // If no DW_AT_object_pointer was specified, assume the implicit object + // parameter is the first parameter to the function, is called "this" and is + // artificial (which is what most compilers would generate). if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) return {}; diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp index 33001db69f83e..f89f0f4a4f0bf 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp @@ -1,4 +1,9 @@ // XFAIL: * +// +// FIXME: Explicit object parameter is not shown in +// type lookup output. This is because we don't attach +// valid source locations to decls in the DWARF AST, +// so the ParmVarDecl::isExplicitObjectParameter fails. // Tests that we correctly deduce the CV-quals and storage // class of explicit object member functions. @@ -8,15 +13,15 @@ // // CHECK: (lldb) type lookup Foo // CHECK-NEXT: struct Foo { -// CHECK-NEXT: void Method(Foo); -// CHECK-NEXT: void cMethod(const Foo &) const; -// CHECK-NEXT: void vMethod(volatile Foo &) volatile; -// CHECK-NEXT: void cvMethod(const volatile Foo &) const volatile; +// CHECK-NEXT: void Method(this Foo); +// CHECK-NEXT: void cMethod(this const Foo &) const; +// CHECK-NEXT: void vMethod(this volatile Foo &) volatile; +// CHECK-NEXT: void cvMethod(this const volatile Foo &) const volatile; // CHECK-NEXT: } struct Foo { - void Method(this Foo) {} - void cMethod(this Foo const &) {} - void vMethod(this Foo volatile &) {} - void cvMethod(this Foo
[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)
https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/144731 >From 3c9a3e5e9af0c9d58783c11490bda473ada84ef3 Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Wed, 18 Jun 2025 16:41:40 +0100 Subject: [PATCH 1/9] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected --- .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 266 -- 1 file changed, 110 insertions(+), 156 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 0f18abb47591d..1810c07652a2b 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -236,199 +236,140 @@ static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream, return true; } -static std::optional -GetDemangledBasename(const SymbolContext &sc) { +static llvm::Expected> +GetAndValidateInfo(const SymbolContext &sc) { Mangled mangled = sc.GetPossiblyInlinedFunctionName(); if (!mangled) -return std::nullopt; +return llvm::createStringError("Function does not have a mangled name."); auto demangled_name = mangled.GetDemangledName().GetStringRef(); if (demangled_name.empty()) -return std::nullopt; +return llvm::createStringError("Function does not have a demangled name."); const std::optional &info = mangled.GetDemangledInfo(); if (!info) -return std::nullopt; +return llvm::createStringError("Function does not have demangled info."); // Function without a basename is nonsense. if (!info->hasBasename()) -return std::nullopt; +return llvm::createStringError("Info do not have basename range."); - return demangled_name.slice(info->BasenameRange.first, - info->BasenameRange.second); + return std::make_pair(demangled_name, *info); } -static std::optional -GetDemangledTemplateArguments(const SymbolContext &sc) { - Mangled mangled = sc.GetPossiblyInlinedFunctionName(); - if (!mangled) -return std::nullopt; +static llvm::Expected +GetDemangledBasename(const SymbolContext &sc) { + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); - auto demangled_name = mangled.GetDemangledName().GetStringRef(); - if (demangled_name.empty()) -return std::nullopt; + auto [demangled_name, info] = *info_or_err; - const std::optional &info = mangled.GetDemangledInfo(); - if (!info) -return std::nullopt; + return demangled_name.slice(info.BasenameRange.first, + info.BasenameRange.second); +} - // Function without a basename is nonsense. - if (!info->hasBasename()) -return std::nullopt; +static llvm::Expected +GetDemangledTemplateArguments(const SymbolContext &sc) { + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); + + auto [demangled_name, info] = *info_or_err; - if (info->ArgumentsRange.first < info->BasenameRange.second) -return std::nullopt; + if (info.ArgumentsRange.first < info.BasenameRange.second) +return llvm::createStringError("Arguments in info are invalid."); - return demangled_name.slice(info->BasenameRange.second, - info->ArgumentsRange.first); + return demangled_name.slice(info.BasenameRange.second, + info.ArgumentsRange.first); } -static std::optional +static llvm::Expected GetDemangledReturnTypeLHS(const SymbolContext &sc) { - Mangled mangled = sc.GetPossiblyInlinedFunctionName(); - if (!mangled) -return std::nullopt; + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); - auto demangled_name = mangled.GetDemangledName().GetStringRef(); - if (demangled_name.empty()) -return std::nullopt; + auto [demangled_name, info] = *info_or_err; - const std::optional &info = mangled.GetDemangledInfo(); - if (!info) -return std::nullopt; + if (info.ScopeRange.first >= demangled_name.size()) +return llvm::createStringError("Scope range is invalid."); - // Function without a basename is nonsense. - if (!info->hasBasename()) -return std::nullopt; - - if (info->ScopeRange.first >= demangled_name.size()) -return std::nullopt; - - return demangled_name.substr(0, info->ScopeRange.first); + return demangled_name.substr(0, info.ScopeRange.first); } -static std::optional +static llvm::Expected GetDemangledFunctionQualifiers(const SymbolContext &sc) { - Mangled mangled = sc.GetPossiblyInlinedFunctionName(); - if (!mangled) -return std::nullopt; + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); - auto demangled_name = mangled.GetDemangledName().GetStringRef(); - if (demangled_name.empty()) -return std::nullopt; + auto [demangled_name, info] = *info_or_err; - const std::
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
@@ -88,3 +88,10 @@ def test_save_core_via_process_plugin(self): os.unlink(core) except OSError: pass + +def test_help(self): +"""Test that help shows minidump as an option in plugin-names.""" +self.expect( +"help process save-core", +substrs=["process save-core", "", "Values:", "minidump"], DavidSpickett wrote: What's the full help look like now? I wonder where this "Values: " comes from. Just want to make sure it's not leftover from a previous version of this PR where we called the names "values" in the error message. https://github.com/llvm/llvm-project/pull/143126 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
@@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp + +CXXFLAGS_EXTRAS := -std=c++14 -O0 labath wrote: -O0 shouldn't be necessary and -std=c++14 should be set [here](https://github.com/llvm/llvm-project/blob/e970f59e6b20dddc4369735affb79ca9be240c1c/lldb/packages/Python/lldbsuite/test/make/Makefile.rules#L350). If that doesn't work for you, may you need to change something over there. https://github.com/llvm/llvm-project/pull/143177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
@@ -239,122 +240,39 @@ VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName(ConstString name) { bool lldb_private::formatters::LibStdcppStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - const bool scalar_is_load_addr = true; - auto [addr_of_string, addr_type] = - valobj.IsPointerOrReferenceType() - ? valobj.GetPointerValue() - : valobj.GetAddressOf(scalar_is_load_addr); - if (addr_of_string != LLDB_INVALID_ADDRESS) { -switch (addr_type) { -case eAddressTypeLoad: { - ProcessSP process_sp(valobj.GetProcessSP()); - if (!process_sp) -return false; - - StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); - Status error; - lldb::addr_t addr_of_data = - process_sp->ReadPointerFromMemory(addr_of_string, error); - if (error.Fail() || addr_of_data == 0 || - addr_of_data == LLDB_INVALID_ADDRESS) -return false; - options.SetLocation(addr_of_data); - options.SetTargetSP(valobj.GetTargetSP()); - options.SetStream(&stream); - options.SetNeedsZeroTermination(false); - options.SetBinaryZeroIsTerminator(true); - lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory( - addr_of_string + process_sp->GetAddressByteSize(), error); - if (error.Fail()) -return false; - options.SetSourceSize(size_of_data); - options.SetHasSourceSize(true); - - if (!StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF8>(options)) { -stream.Printf("Summary Unavailable"); -return true; - } else -return true; -} break; -case eAddressTypeHost: - break; -case eAddressTypeInvalid: -case eAddressTypeFile: - break; -} - } - return false; + ValueObjectSP dataplus = valobj.GetChildMemberWithName("_M_dataplus"); + if (!dataplus) +return false; + ValueObjectSP ptr = dataplus->GetChildMemberWithName("_M_p"); + if (!ptr) +return false; + + Address valobj_addr = ptr->GetPointerValue().address; + if (!valobj_addr.IsValid()) +return false; + + StringPrinter::ReadStringAndDumpToStreamOptions printer_opts(valobj); + printer_opts.SetLocation(valobj_addr); + printer_opts.SetTargetSP(valobj.GetTargetSP()); + printer_opts.SetStream(&stream); + + if (!StringPrinter::ReadStringAndDumpToStream< + StringPrinter::StringElementType::ASCII>(printer_opts)) +stream.Printf("Summary Unavailable"); labath wrote: Could this be something like `stream << ptr->GetSummaryAsCString()` ? I think that's more-or-less how the string summaries work... https://github.com/llvm/llvm-project/pull/143177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
@@ -239,122 +240,39 @@ VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName(ConstString name) { bool lldb_private::formatters::LibStdcppStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - const bool scalar_is_load_addr = true; - auto [addr_of_string, addr_type] = - valobj.IsPointerOrReferenceType() - ? valobj.GetPointerValue() - : valobj.GetAddressOf(scalar_is_load_addr); - if (addr_of_string != LLDB_INVALID_ADDRESS) { -switch (addr_type) { -case eAddressTypeLoad: { - ProcessSP process_sp(valobj.GetProcessSP()); - if (!process_sp) -return false; - - StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); - Status error; - lldb::addr_t addr_of_data = - process_sp->ReadPointerFromMemory(addr_of_string, error); - if (error.Fail() || addr_of_data == 0 || - addr_of_data == LLDB_INVALID_ADDRESS) -return false; - options.SetLocation(addr_of_data); - options.SetTargetSP(valobj.GetTargetSP()); - options.SetStream(&stream); - options.SetNeedsZeroTermination(false); - options.SetBinaryZeroIsTerminator(true); - lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory( - addr_of_string + process_sp->GetAddressByteSize(), error); - if (error.Fail()) -return false; - options.SetSourceSize(size_of_data); - options.SetHasSourceSize(true); - - if (!StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF8>(options)) { -stream.Printf("Summary Unavailable"); -return true; - } else -return true; -} break; -case eAddressTypeHost: - break; -case eAddressTypeInvalid: -case eAddressTypeFile: - break; -} - } - return false; + ValueObjectSP dataplus = valobj.GetChildMemberWithName("_M_dataplus"); + if (!dataplus) +return false; + ValueObjectSP ptr = dataplus->GetChildMemberWithName("_M_p"); labath wrote: Btw, there's a (relatively new) `GetChildAtNamePath` to simplify this. https://github.com/llvm/llvm-project/pull/143177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
@@ -16,4 +16,4 @@ run DavidSpickett wrote: This needs to be done. https://github.com/llvm/llvm-project/pull/143126 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
DavidSpickett wrote: Ok so they aren't lying then. I suppose pecoff -> Windows and on Windows they use minidump among other things. https://github.com/llvm/llvm-project/pull/143126 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][darwin] force BuiltinHeadersInSystemModules to be always false (PR #144913)
Michael137 wrote: @ian-twilightcoder to chime in on the details again. Happy to give it a shot if nothing breaks (I assume you tried running the API test-suite locally?) https://github.com/llvm/llvm-project/pull/144913 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/144998 >From 22e8f644c3cd8856e1663bdf71aab4fa621f75bf Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 29 Jan 2025 12:15:35 + Subject: [PATCH 1/2] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer Starting with https://github.com/llvm/llvm-project/pull/124790, Clang emits `DW_AT_object_pointer` encoded as integer constants rather than DIE references. This patch accounts for this. --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 47 +++-- .../x86/explicit-member-function-quals.cpp| 21 +- .../DWARF/DWARFASTParserClangTests.cpp| 196 ++ 3 files changed, 244 insertions(+), 20 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 4f79c8aa3f811..7d699434ca3c8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -174,23 +174,46 @@ DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram, if (!decl_ctx_die.IsStructUnionOrClass()) return {}; - if (DWARFDIE object_parameter = - subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer)) -return object_parameter; + // The DW_AT_object_pointer may be either encoded as a reference to a DIE, + // in which case that's the object parameter we want. Or it can be a constant + // index of the parameter. + std::optional object_pointer_index; + DWARFFormValue form_value; + if (subprogram.GetDIE()->GetAttributeValue( + subprogram.GetCU(), DW_AT_object_pointer, form_value, + /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) { +if (auto ref = form_value.Reference()) + return ref; + +object_pointer_index = form_value.Unsigned(); + } + + // Try to find the DW_TAG_formal_parameter via object_pointer_index. + DWARFDIE object_pointer; + size_t param_index = 0; + for (const auto &child : subprogram.children()) { +if (child.Tag() != DW_TAG_formal_parameter) + continue; - // If no DW_AT_object_pointer was specified, assume the implicit object - // parameter is the first parameter to the function, is called "this" and is - // artificial (which is what most compilers would generate). - auto children = subprogram.children(); - auto it = llvm::find_if(children, [](const DWARFDIE &child) { -return child.Tag() == DW_TAG_formal_parameter; - }); +if (param_index == object_pointer_index.value_or(0)) + object_pointer = child; + +++param_index; + } - if (it == children.end()) + // No formal parameter found for object pointer index. + // Nothing to be done. + if (!object_pointer) return {}; - DWARFDIE object_pointer = *it; + // We found the object pointer encoded via DW_AT_object_pointer. + // No need for the remaining heuristics. + if (object_pointer_index) +return object_pointer; + // If no DW_AT_object_pointer was specified, assume the implicit object + // parameter is the first parameter to the function, is called "this" and is + // artificial (which is what most compilers would generate). if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) return {}; diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp index 33001db69f83e..f89f0f4a4f0bf 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp @@ -1,4 +1,9 @@ // XFAIL: * +// +// FIXME: Explicit object parameter is not shown in +// type lookup output. This is because we don't attach +// valid source locations to decls in the DWARF AST, +// so the ParmVarDecl::isExplicitObjectParameter fails. // Tests that we correctly deduce the CV-quals and storage // class of explicit object member functions. @@ -8,15 +13,15 @@ // // CHECK: (lldb) type lookup Foo // CHECK-NEXT: struct Foo { -// CHECK-NEXT: void Method(Foo); -// CHECK-NEXT: void cMethod(const Foo &) const; -// CHECK-NEXT: void vMethod(volatile Foo &) volatile; -// CHECK-NEXT: void cvMethod(const volatile Foo &) const volatile; +// CHECK-NEXT: void Method(this Foo); +// CHECK-NEXT: void cMethod(this const Foo &) const; +// CHECK-NEXT: void vMethod(this volatile Foo &) volatile; +// CHECK-NEXT: void cvMethod(this const volatile Foo &) const volatile; // CHECK-NEXT: } struct Foo { - void Method(this Foo) {} - void cMethod(this Foo const &) {} - void vMethod(this Foo volatile &) {} - void cvMethod(this Foo const volatile &) {} + [[gnu::always_inline]] void Method(this Foo) {} + [[gnu::always_inline]] void cMethod(this Foo const &) {} + [[gnu::always_inline]] void vMethod(this Foo volat
[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes Starting with https://github.com/llvm/llvm-project/pull/124790, Clang emits `DW_AT_object_pointer` encoded as integer constants rather than DIE references. This patch accounts for this. --- Full diff: https://github.com/llvm/llvm-project/pull/144998.diff 3 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+35-12) - (modified) lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp (+13-8) - (modified) lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp (+196) ``diff diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 4f79c8aa3f811..7d699434ca3c8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -174,23 +174,46 @@ DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram, if (!decl_ctx_die.IsStructUnionOrClass()) return {}; - if (DWARFDIE object_parameter = - subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer)) -return object_parameter; + // The DW_AT_object_pointer may be either encoded as a reference to a DIE, + // in which case that's the object parameter we want. Or it can be a constant + // index of the parameter. + std::optional object_pointer_index; + DWARFFormValue form_value; + if (subprogram.GetDIE()->GetAttributeValue( + subprogram.GetCU(), DW_AT_object_pointer, form_value, + /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) { +if (auto ref = form_value.Reference()) + return ref; + +object_pointer_index = form_value.Unsigned(); + } + + // Try to find the DW_TAG_formal_parameter via object_pointer_index. + DWARFDIE object_pointer; + size_t param_index = 0; + for (const auto &child : subprogram.children()) { +if (child.Tag() != DW_TAG_formal_parameter) + continue; - // If no DW_AT_object_pointer was specified, assume the implicit object - // parameter is the first parameter to the function, is called "this" and is - // artificial (which is what most compilers would generate). - auto children = subprogram.children(); - auto it = llvm::find_if(children, [](const DWARFDIE &child) { -return child.Tag() == DW_TAG_formal_parameter; - }); +if (param_index == object_pointer_index.value_or(0)) + object_pointer = child; + +++param_index; + } - if (it == children.end()) + // No formal parameter found for object pointer index. + // Nothing to be done. + if (!object_pointer) return {}; - DWARFDIE object_pointer = *it; + // We found the object pointer encoded via DW_AT_object_pointer. + // No need for the remaining heuristics. + if (object_pointer_index) +return object_pointer; + // If no DW_AT_object_pointer was specified, assume the implicit object + // parameter is the first parameter to the function, is called "this" and is + // artificial (which is what most compilers would generate). if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) return {}; diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp index 33001db69f83e..f89f0f4a4f0bf 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp @@ -1,4 +1,9 @@ // XFAIL: * +// +// FIXME: Explicit object parameter is not shown in +// type lookup output. This is because we don't attach +// valid source locations to decls in the DWARF AST, +// so the ParmVarDecl::isExplicitObjectParameter fails. // Tests that we correctly deduce the CV-quals and storage // class of explicit object member functions. @@ -8,15 +13,15 @@ // // CHECK: (lldb) type lookup Foo // CHECK-NEXT: struct Foo { -// CHECK-NEXT: void Method(Foo); -// CHECK-NEXT: void cMethod(const Foo &) const; -// CHECK-NEXT: void vMethod(volatile Foo &) volatile; -// CHECK-NEXT: void cvMethod(const volatile Foo &) const volatile; +// CHECK-NEXT: void Method(this Foo); +// CHECK-NEXT: void cMethod(this const Foo &) const; +// CHECK-NEXT: void vMethod(this volatile Foo &) volatile; +// CHECK-NEXT: void cvMethod(this const volatile Foo &) const volatile; // CHECK-NEXT: } struct Foo { - void Method(this Foo) {} - void cMethod(this Foo const &) {} - void vMethod(this Foo volatile &) {} - void cvMethod(this Foo const volatile &) {} + [[gnu::always_inline]] void Method(this Foo) {} + [[gnu::always_inline]] void cMethod(this Foo const &) {} + [[gnu::always_inline]] void vMethod(this Foo volatile &) {} + [[gnu::always_inline]] void cvMethod(this Foo const volatile &) {} } f; diff --git a/lldb/uni
[Lldb-commits] [lldb] [lldb][AIX] Added base file for AIX Register Context (PR #144645)
@@ -0,0 +1,62 @@ +//===-- NativeRegisterContextAIX.h *- C++ -*-===// DavidSpickett wrote: Make line 1 line up with line 7, they should be the same length. https://github.com/llvm/llvm-project/pull/144645 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] Added base file for AIX Register Context (PR #144645)
@@ -0,0 +1,54 @@ +//===-- NativeRegisterContextAIX.cpp ===// DavidSpickett wrote: Add more `-` so that line 1 ends at the same place line 7 does. https://github.com/llvm/llvm-project/pull/144645 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] Added base file for AIX Register Context (PR #144645)
https://github.com/DavidSpickett approved this pull request. Looks a lot like the existing ppc Linux class, which makes sense, same architecture. With the comment formatting fixed, this LGTM. https://github.com/llvm/llvm-project/pull/144645 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] Added base file for AIX Register Context (PR #144645)
@@ -0,0 +1,54 @@ +//===-- NativeRegisterContextAIX.cpp ===// HemangGadhavi wrote: Done Thanks. https://github.com/llvm/llvm-project/pull/144645 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] Added base file for AIX Register Context (PR #144645)
@@ -0,0 +1,62 @@ +//===-- NativeRegisterContextAIX.h *- C++ -*-===// HemangGadhavi wrote: Done Thanks. https://github.com/llvm/llvm-project/pull/144645 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
DavidSpickett wrote: Just add the new tests and this will be good to go. Figure out whether the other plugins are lying later :) https://github.com/llvm/llvm-project/pull/143126 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Use Socket::CreatePair for launching debugserver (PR #145017)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) Changes This lets get rid of platform-specific code in ProcessGDBRemote and use the same code path (module differences in socket types) everywhere. It also unlocks further cleanups in the debugserver launching code. Depends on #145015. (This PR consists of two commits, the first of which is equivalent to #145015. For reviewing, I recommend only looking at the second commit (if you have comments on the first commit, please put them on the first PR.) --- Full diff: https://github.com/llvm/llvm-project/pull/145017.diff 10 Files Affected: - (modified) lldb/include/lldb/Host/Socket.h (+4) - (modified) lldb/include/lldb/Host/common/TCPSocket.h (+4) - (modified) lldb/include/lldb/Host/posix/DomainSocket.h (+4) - (modified) lldb/source/Host/common/Socket.cpp (+17) - (modified) lldb/source/Host/common/TCPSocket.cpp (+28) - (modified) lldb/source/Host/posix/DomainSocket.cpp (+29) - (modified) lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (+8-28) - (modified) lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (+55-90) - (modified) lldb/unittests/Core/CommunicationTest.cpp (+15-11) - (modified) lldb/unittests/Host/SocketTest.cpp (+35) ``diff diff --git a/lldb/include/lldb/Host/Socket.h b/lldb/include/lldb/Host/Socket.h index c313aa4f6d26b..14a9660ed30b7 100644 --- a/lldb/include/lldb/Host/Socket.h +++ b/lldb/include/lldb/Host/Socket.h @@ -106,6 +106,10 @@ class Socket : public IOObject { static std::unique_ptr Create(const SocketProtocol protocol, Status &error); + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(std::optional protocol = std::nullopt); + virtual Status Connect(llvm::StringRef name) = 0; virtual Status Listen(llvm::StringRef name, int backlog) = 0; diff --git a/lldb/include/lldb/Host/common/TCPSocket.h b/lldb/include/lldb/Host/common/TCPSocket.h index cb950c0015ea6..e81cb82dbcba1 100644 --- a/lldb/include/lldb/Host/common/TCPSocket.h +++ b/lldb/include/lldb/Host/common/TCPSocket.h @@ -23,6 +23,10 @@ class TCPSocket : public Socket { TCPSocket(NativeSocket socket, bool should_close); ~TCPSocket() override; + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(); + // returns port number or 0 if error uint16_t GetLocalPortNumber() const; diff --git a/lldb/include/lldb/Host/posix/DomainSocket.h b/lldb/include/lldb/Host/posix/DomainSocket.h index a840d474429ec..c3a6a64bbdef8 100644 --- a/lldb/include/lldb/Host/posix/DomainSocket.h +++ b/lldb/include/lldb/Host/posix/DomainSocket.h @@ -19,6 +19,10 @@ class DomainSocket : public Socket { DomainSocket(NativeSocket socket, bool should_close); explicit DomainSocket(bool should_close); + static llvm::Expected< + std::pair, std::unique_ptr>> + CreatePair(); + Status Connect(llvm::StringRef name) override; Status Listen(llvm::StringRef name, int backlog) override; diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp index 5c5cd653c3d9e..c9dec0f8ea22a 100644 --- a/lldb/source/Host/common/Socket.cpp +++ b/lldb/source/Host/common/Socket.cpp @@ -234,6 +234,23 @@ std::unique_ptr Socket::Create(const SocketProtocol protocol, return socket_up; } +llvm::Expected, std::unique_ptr>> +Socket::CreatePair(std::optional protocol) { + constexpr SocketProtocol kBestProtocol = + LLDB_ENABLE_POSIX ? ProtocolUnixDomain : ProtocolTcp; + switch (protocol.value_or(kBestProtocol)) { + case ProtocolTcp: +return TCPSocket::CreatePair(); +#if LLDB_ENABLE_POSIX + case ProtocolUnixDomain: + case ProtocolUnixAbstract: +return DomainSocket::CreatePair(); +#endif + default: +return llvm::createStringError("Unsupported protocol"); + } +} + llvm::Expected> Socket::TcpConnect(llvm::StringRef host_and_port) { Log *log = GetLog(LLDBLog::Connection); diff --git a/lldb/source/Host/common/TCPSocket.cpp b/lldb/source/Host/common/TCPSocket.cpp index 3d0dea1c61dd6..34f249746149e 100644 --- a/lldb/source/Host/common/TCPSocket.cpp +++ b/lldb/source/Host/common/TCPSocket.cpp @@ -52,6 +52,34 @@ TCPSocket::TCPSocket(NativeSocket socket, bool should_close) TCPSocket::~TCPSocket() { CloseListenSockets(); } +llvm::Expected< +std::pair, std::unique_ptr>> +TCPSocket::CreatePair() { + auto listen_socket_up = std::make_unique(true); + if (Status error = listen_socket_up->Listen("localhost:0", 5); error.Fail()) +return error.takeError(); + + std::string connect_address = + llvm::StringRef(listen_socket_up->GetListeningConnectionURI()[0]) + .split("://") + .second.str(); + + auto connect_socket_up = std::make_unique(true); + if (Status error = connect_socket_up->Connect(connect_address); error.Fail()) +return error.takeError(); + + // Connection has already been made above, so a short timeout is sufficient. + Socket *accept_socket
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
labath wrote: > Another aside: Does anyone know why the [libstdc++ `std::__cxx11::string` > summaries](https://github.com/llvm/llvm-project/blob/802fa92aee3565768887615108aa3e924d4e0fc7/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp#L240-L358) > weren't using the string summary? They were initially added in > [D13964](https://reviews.llvm.org/D13964), but it doesn't provide a reason to > do so. Note that the summary for a `std::string v = "foo"` was the format > string one (`${var._M_dataplus._M_p}`). Only when printing a reference or > pointer to a string, `LibStdcppStringSummaryProvider` was called. I tried to > use this function for all libstdc++ strings, but this broke when using > `-D_GLIBCXX_USE_CXX11_ABI=0` (on MinGW). On the other hand, > `${var._M_dataplus._M_p}` works with both ABIs. Well, the commit says (I haven't verified this) that the std::string formatter at the time was written in python, so this could have been a way to avoid the python dependency. As for the implementation, a possible reason (again, I don't know if that's the case) could be to make the formatter work in the case where you don't have debug info for std::string -- it looks like it avoids looking at any type information, which means it could work even with a forward declaration -- but that it would break when the ABI changes, as you've noticed. I don't think we need to concern ourselves with that though. Your new implementation is fine. https://github.com/llvm/llvm-project/pull/143177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] Added base file for AIX Register Context (PR #144645)
https://github.com/DhruvSrivastavaX approved this pull request. https://github.com/llvm/llvm-project/pull/144645 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -326,11 +326,15 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) { if (thread_info != m_threads_stepping_with_breakpoint.end() && thread_info->second == regctx.GetPC()) { thread->SetStoppedByTrace(); - Status brkpt_error = RemoveBreakpoint(thread_info->second); - if (brkpt_error.Fail()) -LLDB_LOG(log, "pid = {0} remove stepping breakpoint: {1}", - thread_info->first, brkpt_error); - m_threads_stepping_with_breakpoint.erase(thread_info); + while (thread_info != m_threads_stepping_with_breakpoint.end() { DavidSpickett wrote: In that case, NativeProcessLinux also needs to be changed. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -32,6 +32,31 @@ class RegisterValue; class Stream; class Target; class UnwindPlan; +class EmulateInstruction; + +using BreakpointLocations = std::vector; + +class SingleStepBreakpointLocationsPredictor { +public: + SingleStepBreakpointLocationsPredictor( + std::unique_ptr emulator_up) + : m_emulator_up{std::move(emulator_up)} {} + + virtual BreakpointLocations GetBreakpointLocations(Status &status); + + virtual unsigned GetBreakpointSize(lldb::addr_t, Status &) { return 4; } dlav-sc wrote: addressed https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -0,0 +1,90 @@ +""" +Test software step-inst +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestSoftwareStep(TestBase): +@skipIf(archs=no_match(re.compile("rv*"))) +def test_cas(self): dlav-sc wrote: Added comments for all the tests. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -14471,3 +14471,14 @@ bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { unwind_plan.SetReturnAddressRegister(dwarf_lr); return true; } + +unsigned ARMSingleStepBreakpointLocationsPredictor::GetBreakpointSize( +lldb::addr_t bp_addr, Status &error) { + auto flags = m_emulator_up->ReadRegisterUnsigned( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_ADDRESS, + nullptr); + if (flags == LLDB_INVALID_ADDRESS) +error = Status("Reading flags failed!"); + + return (flags & 0x20) ? /* Thumb mode */ 2 : /* Arm mode */ 4; dlav-sc wrote: Makes sense, it now returns Expected https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -0,0 +1,90 @@ +""" +Test software step-inst +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestSoftwareStep(TestBase): +@skipIf(archs=no_match(re.compile("rv*"))) dlav-sc wrote: I didn't think about performance here, I just want to ensure this works with any riscv configuration (rv32, rv64, rv64gc, rv64gvc and so on). I can't really say whether your idea about `skipIf` is good, because I think I don't know python well enough to judge here. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -23,7 +23,7 @@ class NativeProcessSoftwareSingleStep { protected: // List of thread ids stepping with a breakpoint with the address of // the relevan breakpoint - std::map m_threads_stepping_with_breakpoint; + std::multimap m_threads_stepping_with_breakpoint; dlav-sc wrote: To properly handle `lr`/`sc` sequence, `lldb` sometimes needs to set multiple breakpoints. This means there can now be several breakpoints corresponding to the same thread. I use `std::multimap` here because it allows multiple values with the same key, unlike `std::map` which requires unique keys. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -0,0 +1,90 @@ +""" +Test software step-inst dlav-sc wrote: addressed https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -32,6 +32,31 @@ class RegisterValue; class Stream; class Target; class UnwindPlan; +class EmulateInstruction; + +using BreakpointLocations = std::vector; + +class SingleStepBreakpointLocationsPredictor { +public: + SingleStepBreakpointLocationsPredictor( + std::unique_ptr emulator_up) + : m_emulator_up{std::move(emulator_up)} {} + + virtual BreakpointLocations GetBreakpointLocations(Status &status); + + virtual unsigned GetBreakpointSize(lldb::addr_t, Status &) { return 4; } + + virtual ~SingleStepBreakpointLocationsPredictor() = default; + +protected: + lldb::addr_t GetSequentiallyNextInstructionPC(Status &error); dlav-sc wrote: I mean next in the binary. I've added a comment about it. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -588,7 +588,100 @@ EmulateInstruction::GetInternalRegisterNumber(RegisterContext *reg_ctx, return LLDB_INVALID_REGNUM; } +std::unique_ptr +EmulateInstruction::CreateBreakpointLocationPredictor( +std::unique_ptr emulator_up) { + auto creator = + emulator_up->GetSingleStepBreakpointLocationsPredictorCreator(); + return creator(std::move(emulator_up)); +} + +std::optional EmulateInstruction::ReadPC() { + bool success = false; + auto addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, + LLDB_INVALID_ADDRESS, &success); + return success ? std::optional(addr) : std::nullopt; +} + +bool EmulateInstruction::WritePC(lldb::addr_t addr) { + EmulateInstruction::Context ctx; + ctx.type = eContextAdvancePC; + ctx.SetNoArgs(); + return WriteRegisterUnsigned(ctx, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC, addr); +} + bool EmulateInstruction::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { unwind_plan.Clear(); return false; } + +BreakpointLocations +SingleStepBreakpointLocationsPredictor::GetBreakpointLocations(Status &status) { + if (!m_emulator_up->ReadInstruction()) { +// try to get at least the size of next instruction to set breakpoint. +lldb::addr_t next_pc = GetSequentiallyNextInstructionPC(status); +return BreakpointLocations{next_pc}; + } + + auto entry_pc = m_emulator_up->ReadPC(); + if (!entry_pc) { +status = Status("Can't read PC"); +return {}; + } + + m_emulation_result = m_emulator_up->EvaluateInstruction( + eEmulateInstructionOptionAutoAdvancePC); + + lldb::addr_t next_pc = GetBreakpointLocationAddress(*entry_pc, status); + return BreakpointLocations{next_pc}; +} + +lldb::addr_t +SingleStepBreakpointLocationsPredictor::GetSequentiallyNextInstructionPC( +Status &error) { + auto instr_size = m_emulator_up->GetLastInstrSize(); + if (!instr_size) { +error = Status("Read instruction failed!"); +return LLDB_INVALID_ADDRESS; + } + + auto pc = m_emulator_up->ReadPC(); + if (!pc) { +error = Status("Can't read PC"); +return LLDB_INVALID_ADDRESS; + } + + lldb::addr_t next_pc = *pc + *instr_size; + return next_pc; +} + +lldb::addr_t +SingleStepBreakpointLocationsPredictor::GetBreakpointLocationAddress( +lldb::addr_t entry_pc, Status &error) { + auto addr = m_emulator_up->ReadPC(); + if (!addr) { +error = Status("Can't read PC"); +return LLDB_INVALID_ADDRESS; + } + lldb::addr_t pc = *addr; + + if (m_emulation_result) { +assert(entry_pc != pc && "Emulation was successfull but PC wasn't updated"); +return pc; + } + + if (entry_pc == pc) { +// Emulate instruction failed and it haven't changed PC. Advance PC with +// the size of the current opcode because the emulation of all +// PC modifying instruction should be successful. The failure most +// likely caused by a not supported instruction which don't modify PC. +return pc + m_emulator_up->GetOpcode().GetByteSize(); dlav-sc wrote: addressed https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -32,6 +32,31 @@ class RegisterValue; class Stream; class Target; class UnwindPlan; +class EmulateInstruction; + +using BreakpointLocations = std::vector; + +class SingleStepBreakpointLocationsPredictor { +public: + SingleStepBreakpointLocationsPredictor( + std::unique_ptr emulator_up) + : m_emulator_up{std::move(emulator_up)} {} + + virtual BreakpointLocations GetBreakpointLocations(Status &status); + + virtual unsigned GetBreakpointSize(lldb::addr_t, Status &) { return 4; } + + virtual ~SingleStepBreakpointLocationsPredictor() = default; + +protected: + lldb::addr_t GetSequentiallyNextInstructionPC(Status &error); + + lldb::addr_t GetBreakpointLocationAddress(lldb::addr_t entry_pc, +Status &error); + + std::unique_ptr m_emulator_up; + bool m_emulation_result = false; dlav-sc wrote: This value is only used in one place, in `SingleStepBreakpointLocationsPredictor::GetBreakpointLocationAddress` function . I tried to preserve the original logic, so it might look a bit weird now... https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -16,6 +16,16 @@ namespace lldb_private { +class ARMSingleStepBreakpointLocationsPredictor +: public SingleStepBreakpointLocationsPredictor { +public: + ARMSingleStepBreakpointLocationsPredictor( + std::unique_ptr emulator_up) + : SingleStepBreakpointLocationsPredictor{std::move(emulator_up)} {} dlav-sc wrote: Honestly, I'm not sure what you mean 😅. I need a constructor that takes a `std::unique_ptr`. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -326,11 +326,15 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) { if (thread_info != m_threads_stepping_with_breakpoint.end() && thread_info->second == regctx.GetPC()) { thread->SetStoppedByTrace(); - Status brkpt_error = RemoveBreakpoint(thread_info->second); - if (brkpt_error.Fail()) -LLDB_LOG(log, "pid = {0} remove stepping breakpoint: {1}", - thread_info->first, brkpt_error); - m_threads_stepping_with_breakpoint.erase(thread_info); + while (thread_info != m_threads_stepping_with_breakpoint.end() { dlav-sc wrote: Since `m_threads_stepping_with_breakpoint` is now a `std::multimap` that can store multiple breakpoints per thread, I need a loop to delete all breakpoints that corresponds to desired thread. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -87,34 +87,10 @@ static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton, return length; } -static lldb::addr_t ReadFlags(NativeRegisterContext ®siter_context) { - const RegisterInfo *flags_info = regsiter_context.GetRegisterInfo( - eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); - return regsiter_context.ReadRegisterAsUnsigned(flags_info, - LLDB_INVALID_ADDRESS); -} - -static int GetSoftwareBreakpointSize(const ArchSpec &arch, - lldb::addr_t next_flags) { - if (arch.GetMachine() == llvm::Triple::arm) { -if (next_flags & 0x20) - // Thumb mode - return 2; -// Arm mode -return 4; - } - if (arch.IsMIPS() || arch.GetTriple().isPPC64() || - arch.GetTriple().isRISCV() || arch.GetTriple().isLoongArch()) -return 4; - return 0; dlav-sc wrote: Yeah, I see. I've added a check, see the `GetSingleStepBreakpointLocationsPredictorCreator` function. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -0,0 +1,90 @@ +""" +Test software step-inst +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestSoftwareStep(TestBase): +@skipIf(archs=no_match(re.compile("rv*"))) +def test_cas(self): +self.build() +(target, process, cur_thread, bkpt) = lldbutil.run_to_name_breakpoint( +self, "cas" +) +entry_pc = cur_thread.GetFrameAtIndex(0).GetPC() + +self.runCmd("thread step-inst") +self.expect( +"thread list", +substrs=["stopped", "stop reason = instruction step into"], +) + +pc = cur_thread.GetFrameAtIndex(0).GetPC() +self.assertTrue((pc - entry_pc) > 0x10) + +@skipIf(archs=no_match(re.compile("rv*"))) +def test_branch_cas(self): +self.build(dictionary={"C_SOURCES": "branch.c", "EXE": "branch.x"}) +(target, process, cur_thread, bkpt) = lldbutil.run_to_name_breakpoint( +self, "branch_cas", exe_name="branch.x" +) +entry_pc = cur_thread.GetFrameAtIndex(0).GetPC() + +self.runCmd("thread step-inst") +self.expect( +"thread list", +substrs=["stopped", "stop reason = instruction step into"], +) + +pc = cur_thread.GetFrameAtIndex(0).GetPC() +self.assertTrue((pc - entry_pc) > 0x10) + +@skipIf(archs=no_match(re.compile("rv*"))) +def test_incomplete_sequence_without_lr(self): +self.build( +dictionary={ +"C_SOURCES": "incomplete_sequence_without_lr.c", +"EXE": "incomplete_lr.x", +} +) +(target, process, cur_thread, bkpt) = lldbutil.run_to_name_breakpoint( +self, "incomplete_cas", exe_name="incomplete_lr.x" +) +entry_pc = cur_thread.GetFrameAtIndex(0).GetPC() + +self.runCmd("thread step-inst") + +self.expect( +"thread list", +substrs=["stopped", "stop reason = instruction step into"], +) + +pc = cur_thread.GetFrameAtIndex(0).GetPC() +self.assertTrue((pc - entry_pc) == 0x4) + +@skipIf(archs=no_match(re.compile("rv*"))) +def test_incomplete_sequence_without_sc(self): +self.build( +dictionary={ +"C_SOURCES": "incomplete_sequence_without_sc.c", +"EXE": "incomplete_sc.x", +} +) +(target, process, cur_thread, bkpt) = lldbutil.run_to_name_breakpoint( +self, "incomplete_cas", exe_name="incomplete_sc.x" +) +entry_pc = cur_thread.GetFrameAtIndex(0).GetPC() + +self.runCmd("thread step-inst") + +self.expect( +"thread list", +substrs=["stopped", "stop reason = instruction step into"], +) + +pc = cur_thread.GetFrameAtIndex(0).GetPC() +self.assertTrue((pc - entry_pc) == 0x4) dlav-sc wrote: addressed https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -0,0 +1,90 @@ +""" +Test software step-inst +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestSoftwareStep(TestBase): +@skipIf(archs=no_match(re.compile("rv*"))) +def test_cas(self): +self.build() +(target, process, cur_thread, bkpt) = lldbutil.run_to_name_breakpoint( +self, "cas" +) +entry_pc = cur_thread.GetFrameAtIndex(0).GetPC() + +self.runCmd("thread step-inst") +self.expect( +"thread list", +substrs=["stopped", "stop reason = instruction step into"], +) + +pc = cur_thread.GetFrameAtIndex(0).GetPC() +self.assertTrue((pc - entry_pc) > 0x10) dlav-sc wrote: >From what I understand, lldb runs the same test twice: the first one with the >default dwarf debug info embedded in the binary (`dwarf` mode) and the second >one with a binary compiled using `-dwarf-split`, which stores debug info in a >separate file (`dwo` mode) (I might be mistaken about this exact workflow.) I actually noticed a while back (about a year or more ago) that `-dwarf-split` doesn't work properly for riscv. `Clang` had been failing during compilation with an error stating that `-dwarf-split` is unsupported for riscv. However, more recently, clang seems to start compile something, but I'm not sure if the output is valid - some `dwo` tests show strange behavior, which might be related to issues with split debug info. Regarding this specific test, it works as expected with standard `dwarf`, but there are problems with `dwo`: * The test with incomplete `lr`/`sc` passes with `dwo` * The branch test behaves strangely (doesn't even stop after step instruction) * The standard `lr`/`sc` sequence test works but shows different PC offsets (`pc - entry_pc`) After examining the binary a bit, looks like it uses different relocations than the dwarf version, resulting in 1-2 extra instructions in atomic sequences. This explains the different offsets in the same test but with different debug info formats . This seems odd to me, as I wouldn't expect `-dwarf-split` to affect code generation. I've been meaning to investigate` -dwarf-split` more thoroughly. For now we could temporarily exclude `dwo` tests at all from consideration and use the offsets that corresponds to the standard `dwarf` case. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -0,0 +1,90 @@ +""" +Test software step-inst +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestSoftwareStep(TestBase): +@skipIf(archs=no_match(re.compile("rv*"))) +def test_cas(self): +self.build() +(target, process, cur_thread, bkpt) = lldbutil.run_to_name_breakpoint( +self, "cas" +) +entry_pc = cur_thread.GetFrameAtIndex(0).GetPC() + +self.runCmd("thread step-inst") +self.expect( +"thread list", +substrs=["stopped", "stop reason = instruction step into"], +) + +pc = cur_thread.GetFrameAtIndex(0).GetPC() +self.assertTrue((pc - entry_pc) > 0x10) + +@skipIf(archs=no_match(re.compile("rv*"))) +def test_branch_cas(self): dlav-sc wrote: Added comments for all the tests. https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
@@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp + +CXXFLAGS_EXTRAS := -std=c++14 -O0 Nerixyz wrote: Yes, that worked! https://github.com/llvm/llvm-project/pull/143177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -16,6 +16,16 @@ namespace lldb_private { +class ARMSingleStepBreakpointLocationsPredictor +: public SingleStepBreakpointLocationsPredictor { +public: + ARMSingleStepBreakpointLocationsPredictor( + std::unique_ptr emulator_up) + : SingleStepBreakpointLocationsPredictor{std::move(emulator_up)} {} DavidSpickett wrote: ``` class SingleStepBreakpointLocationsPredictor { public: SingleStepBreakpointLocationsPredictor( std::unique_ptr emulator_up) : m_emulator_up{std::move(emulator_up)} {} ``` Seems like you just pass on to this. Can this sub-class not just use the base class constructor? https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AArch64][Linux] Show MTE store only setting in mte_ctrl (PR #145033)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) Changes This controls whether tag checking is performed for loads and stores, or stores only. It requires a specific architecture feature which we detect with a HWCAP3 and cpuinfo feature. Live process tests look for this and adjust expectations accordingly, core file tests are using an updated file with this feature enabled. The size of the core file has increased and there's nothing I can do about that. Could be the presence of new architecure features or kernel changes since I last generated them. I can generate a smaller file that has the tag segment, but that segment does not actually contain tag data. So that's no use. (and I will fix handling of such files later) --- Full diff: https://github.com/llvm/llvm-project/pull/145033.diff 13 Files Affected: - (modified) lldb/packages/Python/lldbsuite/test/lldbtest.py (+3) - (modified) lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp (+2-1) - (modified) lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp (+4-1) - (modified) lldb/source/Plugins/Process/Utility/AuxVector.cpp (+1) - (modified) lldb/source/Plugins/Process/Utility/AuxVector.h (+1) - (modified) lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp (+39-13) - (modified) lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h (+16-9) - (modified) lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp (+9-4) - (modified) lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py (+22-10) - (modified) lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py (+7-4) - (modified) lldb/test/API/linux/aarch64/mte_core_file/core.mte () - (modified) lldb/test/API/linux/aarch64/mte_core_file/core.nomte () - (modified) lldb/test/API/linux/aarch64/mte_core_file/main.c (+1-1) ``diff diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index a4ff96e4158ce..a47ffabdecd0e 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -1380,6 +1380,9 @@ def isAArch64SMEFA64(self): def isAArch64MTE(self): return self.isAArch64() and "mte" in self.getCPUInfo() +def isAArch64MTEStoreOnly(self): +return self.isAArch64() and "mtestoreonly" in self.getCPUInfo() + def isAArch64GCS(self): return self.isAArch64() and "gcs" in self.getCPUInfo() diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp index 7adc00622ec2d..d21dac221aa22 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp @@ -44,7 +44,8 @@ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( NativeProcessFreeBSD &process = native_thread.GetProcess(); g_register_flags_detector.DetectFields( process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0), -process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0)); +process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0), +/*hwcap3=*/0); } return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread); diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index 884c7d4b9e359..b1c7421bef8d5 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -162,10 +162,13 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS); +std::optional auxv_at_hwcap3 = +process.GetAuxValue(AuxVector::AUXV_AT_HWCAP3); std::lock_guard lock(g_register_flags_detector_mutex); if (!g_register_flags_detector.HasDetected()) g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0), - auxv_at_hwcap2.value_or(0)); + auxv_at_hwcap2.value_or(0), + auxv_at_hwcap3.value_or(0)); auto register_info_up = std::make_unique(target_arch, opt_regsets); diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/lldb/source/Plugins/Process/Utility/AuxVector.cpp index f495ffb1924e7..50500a8593e1d 100644 --- a/lldb/source/Plugins/Process/Utility/AuxVector.cpp +++ b/lldb/source/Plugins/Process/Utility/AuxVector.cpp @@ -84,6 +84,7 @@ const char *AuxVector::GetEntryName(EntryType type) const { case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break; case ENT
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
@@ -299,6 +299,8 @@ def parseOptionsAndInitTestdirs(): configuration.libcxx_library_dir = args.libcxx_library_dir configuration.cmake_build_type = args.cmake_build_type.lower() +configuration.target_triple = args.target_triple + Nerixyz wrote: There's no `-stdlib`, but detection through `_MSVC_STL_VERSION` works. https://github.com/llvm/llvm-project/pull/143177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/143177 >From 9f957946e2538c8a0c0f6d772ae9c5d1946ec694 Mon Sep 17 00:00:00 2001 From: Nerixyz Date: Wed, 18 Jun 2025 21:49:16 +0200 Subject: [PATCH] [LLDB] Add type summaries for MSVC STL strings --- .../lldb/DataFormatters/StringPrinter.h | 15 ++ lldb/packages/Python/lldbsuite/test/dotest.py | 41 + .../Python/lldbsuite/test/test_categories.py | 1 + .../Plugins/Language/CPlusPlus/CMakeLists.txt | 1 + .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 138 + .../Plugins/Language/CPlusPlus/LibStdcpp.cpp | 127 ++-- .../Plugins/Language/CPlusPlus/LibStdcpp.h| 4 +- .../Plugins/Language/CPlusPlus/MsvcStl.cpp| 143 ++ .../Plugins/Language/CPlusPlus/MsvcStl.h | 35 + .../msvcstl/string/Makefile | 3 + .../string/TestDataFormatterStdString.py | 118 +++ .../msvcstl/string/main.cpp | 40 + .../msvcstl/u8string/Makefile | 4 + .../u8string/TestDataFormatterStdU8String.py | 31 .../msvcstl/u8string/main.cpp | 14 ++ 15 files changed, 570 insertions(+), 145 deletions(-) create mode 100644 lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp create mode 100644 lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/Makefile create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/TestDataFormatterStdString.py create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/main.cpp create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/Makefile create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/TestDataFormatterStdU8String.py create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/main.cpp diff --git a/lldb/include/lldb/DataFormatters/StringPrinter.h b/lldb/include/lldb/DataFormatters/StringPrinter.h index 4169f53e63f38..4ebe712be60e1 100644 --- a/lldb/include/lldb/DataFormatters/StringPrinter.h +++ b/lldb/include/lldb/DataFormatters/StringPrinter.h @@ -152,6 +152,21 @@ class StringPrinter { template static bool ReadBufferAndDumpToStream(const ReadBufferAndDumpToStreamOptions &options); + + template + static constexpr uint64_t ElementByteSize() { +switch (element_type) { +case StringElementType::ASCII: +case StringElementType::UTF8: + return 1; +case StringElementType::UTF16: + return 2; +case StringElementType::UTF32: + return 3; +default: + return 0; +} + } }; } // namespace formatters diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py index d7f274ac4f60e..90c8e32afa507 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest.py +++ b/lldb/packages/Python/lldbsuite/test/dotest.py @@ -831,6 +831,46 @@ def checkLibstdcxxSupport(): configuration.skip_categories.append("libstdcxx") +def canRunMsvcStlTests(): +from lldbsuite.test import lldbplatformutil + +platform = lldbplatformutil.getPlatform() +if platform != "windows": +return False, f"Don't know how to build with MSVC's STL on {platform}" + +with tempfile.NamedTemporaryFile() as f: +cmd = [configuration.compiler, "-xc++", "-o", f.name, "-E", "-"] +p = subprocess.Popen( +cmd, +stdin=subprocess.PIPE, +stdout=subprocess.PIPE, +stderr=subprocess.PIPE, +universal_newlines=True, +) +_, stderr = p.communicate( +""" +#include +#ifndef _MSVC_STL_VERSION +#error _MSVC_STL_VERSION not defined +#endif +""" +) +if not p.returncode: +return True, "Compiling with MSVC STL" +return (False, f"Not compiling with MSVC STL: {stderr}") + + +def checkMsvcStlSupport(): +result, reason = canRunMsvcStlTests() +if result: +return # msvcstl supported +if "msvcstl" in configuration.categories_list: +return # msvcstl category explicitly requested, let it run. +if configuration.verbose: +print(f"msvcstl tests will not be run because: {reason}") +configuration.skip_categories.append("msvcstl") + + def canRunWatchpointTests(): from lldbsuite.test import lldbplatformutil @@ -1044,6 +1084,7 @@ def run_suite(): checkLibcxxSupport() checkLibstdcxxSupport() +checkMsvcStlSupport() checkWatchpointSupport() checkDebugInfoSupport() checkDebugServerSupport() diff --git a/lldb/packages/Python/lldbsuite/test/test_categories.py b/lldb/packages/Python/lldbsuite/test/test_categories.py index b585f695adeab
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
@@ -299,6 +299,8 @@ def parseOptionsAndInitTestdirs(): configuration.libcxx_library_dir = args.libcxx_library_dir configuration.cmake_build_type = args.cmake_build_type.lower() +configuration.target_triple = args.target_triple + labath wrote: I'd very much like to avoid adding this argument. Maybe you could do something like `canRunLibcxxTests`, which tries to compile? It'd also be nice if there was a way to run these tests even if the default clang configuration does not use it. Is there any equivalent to `-stdlib=libc++` which would force the usage of the MSVC STL? https://github.com/llvm/llvm-project/pull/143177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
https://github.com/dlav-sc updated https://github.com/llvm/llvm-project/pull/127505 >From 2520b8d7884d320ed7923685b1a3e8652a7e8f5f Mon Sep 17 00:00:00 2001 From: Daniil Avdeev Date: Fri, 23 May 2025 13:27:46 + Subject: [PATCH 1/3] [lldb][RISCV] handle lr/sc single step lldb-server had limited support for single-stepping through the lr/sc atomic sequence. This patch enhances that support for all possible atomic sequences. --- lldb/include/lldb/Core/EmulateInstruction.h | 45 +++ lldb/source/Core/EmulateInstruction.cpp | 93 + .../Instruction/ARM/EmulateInstructionARM.cpp | 11 ++ .../Instruction/ARM/EmulateInstructionARM.h | 18 +++ .../LoongArch/EmulateInstructionLoongArch.cpp | 122 +++--- .../LoongArch/EmulateInstructionLoongArch.h | 2 - .../RISCV/EmulateInstructionRISCV.cpp | 117 ++--- .../RISCV/EmulateInstructionRISCV.h | 37 +- .../Process/FreeBSD/NativeProcessFreeBSD.cpp | 14 +- .../NativeProcessSoftwareSingleStep.cpp | 108 +++- .../Utility/NativeProcessSoftwareSingleStep.h | 2 +- .../LoongArch/TestLoongArchEmulator.cpp | 36 +++--- 12 files changed, 422 insertions(+), 183 deletions(-) diff --git a/lldb/include/lldb/Core/EmulateInstruction.h b/lldb/include/lldb/Core/EmulateInstruction.h index b459476883fc5..0e3564206ccb8 100644 --- a/lldb/include/lldb/Core/EmulateInstruction.h +++ b/lldb/include/lldb/Core/EmulateInstruction.h @@ -32,6 +32,31 @@ class RegisterValue; class Stream; class Target; class UnwindPlan; +class EmulateInstruction; + +using BreakpointLocations = std::vector; + +class SingleStepBreakpointLocationsPredictor { +public: + SingleStepBreakpointLocationsPredictor( + std::unique_ptr emulator_up) + : m_emulator_up{std::move(emulator_up)} {} + + virtual BreakpointLocations GetBreakpointLocations(Status &status); + + virtual unsigned GetBreakpointSize(lldb::addr_t, Status &) { return 4; } + + virtual ~SingleStepBreakpointLocationsPredictor() = default; + +protected: + lldb::addr_t GetSequentiallyNextInstructionPC(Status &error); + + lldb::addr_t GetBreakpointLocationAddress(lldb::addr_t entry_pc, +Status &error); + + std::unique_ptr m_emulator_up; + bool m_emulation_result = false; +}; /// \class EmulateInstruction EmulateInstruction.h /// "lldb/Core/EmulateInstruction.h" @@ -497,7 +522,19 @@ class EmulateInstruction : public PluginInterface { static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx, const RegisterInfo ®_info); + static std::unique_ptr + CreateBreakpointLocationPredictor( + std::unique_ptr emulator_up); + + // Helper functions + std::optional ReadPC(); + bool WritePC(lldb::addr_t addr); + protected: + using BreakpointLocationsPredictorCreator = + std::function( + std::unique_ptr)>; + ArchSpec m_arch; void *m_baton = nullptr; ReadMemoryCallback m_read_mem_callback = &ReadMemoryDefault; @@ -508,6 +545,14 @@ class EmulateInstruction : public PluginInterface { Opcode m_opcode; private: + virtual BreakpointLocationsPredictorCreator + GetSingleStepBreakpointLocationsPredictorCreator() { +return [](std::unique_ptr emulator_up) { + return std::make_unique( + std::move(emulator_up)); +}; + } + // For EmulateInstruction only EmulateInstruction(const EmulateInstruction &) = delete; const EmulateInstruction &operator=(const EmulateInstruction &) = delete; diff --git a/lldb/source/Core/EmulateInstruction.cpp b/lldb/source/Core/EmulateInstruction.cpp index d240b4d3b3310..3bc7beff8ac7f 100644 --- a/lldb/source/Core/EmulateInstruction.cpp +++ b/lldb/source/Core/EmulateInstruction.cpp @@ -588,7 +588,100 @@ EmulateInstruction::GetInternalRegisterNumber(RegisterContext *reg_ctx, return LLDB_INVALID_REGNUM; } +std::unique_ptr +EmulateInstruction::CreateBreakpointLocationPredictor( +std::unique_ptr emulator_up) { + auto creator = + emulator_up->GetSingleStepBreakpointLocationsPredictorCreator(); + return creator(std::move(emulator_up)); +} + +std::optional EmulateInstruction::ReadPC() { + bool success = false; + auto addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, + LLDB_INVALID_ADDRESS, &success); + return success ? std::optional(addr) : std::nullopt; +} + +bool EmulateInstruction::WritePC(lldb::addr_t addr) { + EmulateInstruction::Context ctx; + ctx.type = eContextAdvancePC; + ctx.SetNoArgs(); + return WriteRegisterUnsigned(ctx, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC, addr); +} + bool EmulateInstruction::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { unwind_plan.Clear(); return false; } + +BreakpointLocations +SingleStepBreakpointLocationsPredictor::GetBreakpointLocations(Status &status) { + if (!m_emulator_up->ReadInstruction()
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/143177 >From d80694278209cfc1c88414b1f5eb8e9980ebb3fa Mon Sep 17 00:00:00 2001 From: Nerixyz Date: Wed, 18 Jun 2025 21:49:16 +0200 Subject: [PATCH] [LLDB] Add type summaries for MSVC STL strings --- .../lldb/DataFormatters/StringPrinter.h | 15 ++ lldb/packages/Python/lldbsuite/test/dotest.py | 40 + .../Python/lldbsuite/test/test_categories.py | 1 + .../Plugins/Language/CPlusPlus/CMakeLists.txt | 1 + .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 138 + .../Plugins/Language/CPlusPlus/LibStdcpp.cpp | 127 ++-- .../Plugins/Language/CPlusPlus/LibStdcpp.h| 4 +- .../Plugins/Language/CPlusPlus/MsvcStl.cpp| 143 ++ .../Plugins/Language/CPlusPlus/MsvcStl.h | 35 + .../msvcstl/string/Makefile | 3 + .../string/TestDataFormatterStdString.py | 118 +++ .../msvcstl/string/main.cpp | 40 + .../msvcstl/u8string/Makefile | 4 + .../u8string/TestDataFormatterStdU8String.py | 31 .../msvcstl/u8string/main.cpp | 14 ++ 15 files changed, 569 insertions(+), 145 deletions(-) create mode 100644 lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp create mode 100644 lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/Makefile create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/TestDataFormatterStdString.py create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/main.cpp create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/Makefile create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/TestDataFormatterStdU8String.py create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/main.cpp diff --git a/lldb/include/lldb/DataFormatters/StringPrinter.h b/lldb/include/lldb/DataFormatters/StringPrinter.h index 4169f53e63f38..4ebe712be60e1 100644 --- a/lldb/include/lldb/DataFormatters/StringPrinter.h +++ b/lldb/include/lldb/DataFormatters/StringPrinter.h @@ -152,6 +152,21 @@ class StringPrinter { template static bool ReadBufferAndDumpToStream(const ReadBufferAndDumpToStreamOptions &options); + + template + static constexpr uint64_t ElementByteSize() { +switch (element_type) { +case StringElementType::ASCII: +case StringElementType::UTF8: + return 1; +case StringElementType::UTF16: + return 2; +case StringElementType::UTF32: + return 3; +default: + return 0; +} + } }; } // namespace formatters diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py index d7f274ac4f60e..768fdb390cede 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest.py +++ b/lldb/packages/Python/lldbsuite/test/dotest.py @@ -831,6 +831,45 @@ def checkLibstdcxxSupport(): configuration.skip_categories.append("libstdcxx") +def canRunMsvcStlTests(): +from lldbsuite.test import lldbplatformutil + +platform = lldbplatformutil.getPlatform() +if platform != "windows": +return False, f"Don't know how to build with MSVC's STL on {platform}" + +with tempfile.NamedTemporaryFile() as f: +cmd = [configuration.compiler, "-xc++", "-o", f.name, "-E", "-"] +p = subprocess.Popen( +cmd, +stdin=subprocess.PIPE, +stdout=subprocess.PIPE, +stderr=subprocess.PIPE, +universal_newlines=True, +) +_, stderr = p.communicate( +""" +#include +#ifndef _MSVC_STL_VERSION +#error _MSVC_STL_VERSION not defined +#endif +""" +) +if not p.returncode: +return True, "Compiling with MSVC STL" +return (False, f"Not compiling with MSVC STL: {stderr}") + +def checkMsvcStlSupport(): +result, reason = canRunMsvcStlTests() +if result: +return # msvcstl supported +if "msvcstl" in configuration.categories_list: +return # msvcstl category explicitly requested, let it run. +if configuration.verbose: +print(f"msvcstl tests will not be run because: {reason}") +configuration.skip_categories.append("msvcstl") + + def canRunWatchpointTests(): from lldbsuite.test import lldbplatformutil @@ -1044,6 +1083,7 @@ def run_suite(): checkLibcxxSupport() checkLibstdcxxSupport() +checkMsvcStlSupport() checkWatchpointSupport() checkDebugInfoSupport() checkDebugServerSupport() diff --git a/lldb/packages/Python/lldbsuite/test/test_categories.py b/lldb/packages/Python/lldbsuite/test/test_categories.py index b585f695adeab..
[Lldb-commits] [lldb] [lldb][AArch64][Linux] Show MTE store only setting in mte_ctrl (PR #145033)
https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/145033 This controls whether tag checking is performed for loads and stores, or stores only. It requires a specific architecture feature which we detect with a HWCAP3 and cpuinfo feature. Live process tests look for this and adjust expectations accordingly, core file tests are using an updated file with this feature enabled. The size of the core file has increased and there's nothing I can do about that. Could be the presence of new architecure features or kernel changes since I last generated them. I can generate a smaller file that has the tag segment, but that segment does not actually contain tag data. So that's no use. (and I will fix handling of such files later) >From ba8fcf4ef14e25b8a628b994988d6a67bdbea7df Mon Sep 17 00:00:00 2001 From: David Spickett Date: Thu, 19 Jun 2025 10:43:48 + Subject: [PATCH 1/2] [lldb][AArch64] Add HWCAP3 to register field detection This will be used to detect the presence of Arm's new Memory Tagging store only checking feature. This commit just adds the plubming to get that value into the detection function. FreeBSD has not allocated a number for HWCAP3 and already has AT_ARGV defined as 29. So instead of attempting to read from FreeBSD processes, I've explictly passed nullopt. We don't want to be reading some other entry accidentally. If/when FreeBSD adds HWCAP3 we can handle it like we do for AUXV_FREEBSD_AT_HWCAP. No extra tests here, those will be coming with the next change for MTE support. --- .../NativeRegisterContextFreeBSD_arm64.cpp| 3 +- .../NativeRegisterContextLinux_arm64.cpp | 5 ++- .../Plugins/Process/Utility/AuxVector.cpp | 1 + .../Plugins/Process/Utility/AuxVector.h | 1 + .../Utility/RegisterFlagsDetector_arm64.cpp | 36 +-- .../Utility/RegisterFlagsDetector_arm64.h | 25 - .../RegisterContextPOSIXCore_arm64.cpp| 13 --- 7 files changed, 59 insertions(+), 25 deletions(-) diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp index 7adc00622ec2d..d21dac221aa22 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp @@ -44,7 +44,8 @@ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( NativeProcessFreeBSD &process = native_thread.GetProcess(); g_register_flags_detector.DetectFields( process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0), -process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0)); +process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0), +/*hwcap3=*/0); } return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread); diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index 884c7d4b9e359..b1c7421bef8d5 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -162,10 +162,13 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS); +std::optional auxv_at_hwcap3 = +process.GetAuxValue(AuxVector::AUXV_AT_HWCAP3); std::lock_guard lock(g_register_flags_detector_mutex); if (!g_register_flags_detector.HasDetected()) g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0), - auxv_at_hwcap2.value_or(0)); + auxv_at_hwcap2.value_or(0), + auxv_at_hwcap3.value_or(0)); auto register_info_up = std::make_unique(target_arch, opt_regsets); diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/lldb/source/Plugins/Process/Utility/AuxVector.cpp index f495ffb1924e7..50500a8593e1d 100644 --- a/lldb/source/Plugins/Process/Utility/AuxVector.cpp +++ b/lldb/source/Plugins/Process/Utility/AuxVector.cpp @@ -84,6 +84,7 @@ const char *AuxVector::GetEntryName(EntryType type) const { case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break; case ENTRY_NAME(AUXV_AT_RANDOM); break; case ENTRY_NAME(AUXV_AT_HWCAP2); break; +case ENTRY_NAME(AUXV_AT_HWCAP3); break; case ENTRY_NAME(AUXV_AT_EXECFN); break; case ENTRY_NAME(AUXV_AT_SYSINFO);break; case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break; diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.h b/lldb/source/Plugins/Process/Utility/AuxVector.h index 2670b34f6b0af..7733e0ffc6832 100644 --- a/lldb/source/Plugins/Process/Utility/AuxVector.h +++ b/lldb/source/Plugins/Process/Utility/AuxVec
[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)
https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/144731 >From 3c9a3e5e9af0c9d58783c11490bda473ada84ef3 Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Wed, 18 Jun 2025 16:41:40 +0100 Subject: [PATCH 01/10] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected --- .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 266 -- 1 file changed, 110 insertions(+), 156 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 0f18abb47591d..1810c07652a2b 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -236,199 +236,140 @@ static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream, return true; } -static std::optional -GetDemangledBasename(const SymbolContext &sc) { +static llvm::Expected> +GetAndValidateInfo(const SymbolContext &sc) { Mangled mangled = sc.GetPossiblyInlinedFunctionName(); if (!mangled) -return std::nullopt; +return llvm::createStringError("Function does not have a mangled name."); auto demangled_name = mangled.GetDemangledName().GetStringRef(); if (demangled_name.empty()) -return std::nullopt; +return llvm::createStringError("Function does not have a demangled name."); const std::optional &info = mangled.GetDemangledInfo(); if (!info) -return std::nullopt; +return llvm::createStringError("Function does not have demangled info."); // Function without a basename is nonsense. if (!info->hasBasename()) -return std::nullopt; +return llvm::createStringError("Info do not have basename range."); - return demangled_name.slice(info->BasenameRange.first, - info->BasenameRange.second); + return std::make_pair(demangled_name, *info); } -static std::optional -GetDemangledTemplateArguments(const SymbolContext &sc) { - Mangled mangled = sc.GetPossiblyInlinedFunctionName(); - if (!mangled) -return std::nullopt; +static llvm::Expected +GetDemangledBasename(const SymbolContext &sc) { + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); - auto demangled_name = mangled.GetDemangledName().GetStringRef(); - if (demangled_name.empty()) -return std::nullopt; + auto [demangled_name, info] = *info_or_err; - const std::optional &info = mangled.GetDemangledInfo(); - if (!info) -return std::nullopt; + return demangled_name.slice(info.BasenameRange.first, + info.BasenameRange.second); +} - // Function without a basename is nonsense. - if (!info->hasBasename()) -return std::nullopt; +static llvm::Expected +GetDemangledTemplateArguments(const SymbolContext &sc) { + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); + + auto [demangled_name, info] = *info_or_err; - if (info->ArgumentsRange.first < info->BasenameRange.second) -return std::nullopt; + if (info.ArgumentsRange.first < info.BasenameRange.second) +return llvm::createStringError("Arguments in info are invalid."); - return demangled_name.slice(info->BasenameRange.second, - info->ArgumentsRange.first); + return demangled_name.slice(info.BasenameRange.second, + info.ArgumentsRange.first); } -static std::optional +static llvm::Expected GetDemangledReturnTypeLHS(const SymbolContext &sc) { - Mangled mangled = sc.GetPossiblyInlinedFunctionName(); - if (!mangled) -return std::nullopt; + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); - auto demangled_name = mangled.GetDemangledName().GetStringRef(); - if (demangled_name.empty()) -return std::nullopt; + auto [demangled_name, info] = *info_or_err; - const std::optional &info = mangled.GetDemangledInfo(); - if (!info) -return std::nullopt; + if (info.ScopeRange.first >= demangled_name.size()) +return llvm::createStringError("Scope range is invalid."); - // Function without a basename is nonsense. - if (!info->hasBasename()) -return std::nullopt; - - if (info->ScopeRange.first >= demangled_name.size()) -return std::nullopt; - - return demangled_name.substr(0, info->ScopeRange.first); + return demangled_name.substr(0, info.ScopeRange.first); } -static std::optional +static llvm::Expected GetDemangledFunctionQualifiers(const SymbolContext &sc) { - Mangled mangled = sc.GetPossiblyInlinedFunctionName(); - if (!mangled) -return std::nullopt; + auto info_or_err = GetAndValidateInfo(sc); + if (!info_or_err) +return info_or_err.takeError(); - auto demangled_name = mangled.GetDemangledName().GetStringRef(); - if (demangled_name.empty()) -return std::nullopt; + auto [demangled_name, info] = *info_or_err; - const std
[Lldb-commits] [lldb] [lldb][AArch64][Linux] Show MTE store only setting in mte_ctrl (PR #145033)
DavidSpickett wrote: And if you want to test this, you need Arm's FVP and to add the following shrinkwrap settings: ``` +-C cluster0.memory_tagging_support_level: 4 +-C cluster1.memory_tagging_support_level: 4 +-C bp.dram_metadata.is_enabled: 1 ``` I did this on top of the v9.5-a config. But it should be reviewable by referring to the kernel patches and the core file tests I've added. https://github.com/llvm/llvm-project/pull/145033 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AArch64] Add HWCAP3 to register field detection (PR #145029)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) Changes This will be used to detect the presence of Arm's new Memory Tagging store only checking feature. This commit just adds the plumbing to get that value into the detection function. FreeBSD has not allocated a number for HWCAP3 and already has AT_ARGV defined as 29. So instead of attempting to read from FreeBSD processes, I've explicitly passed nullopt. We don't want to be reading some other entry accidentally. If/when FreeBSD adds HWCAP3 we can handle it like we do for AUXV_FREEBSD_AT_HWCAP. No extra tests here, those will be coming with the next change for MTE support. --- Full diff: https://github.com/llvm/llvm-project/pull/145029.diff 7 Files Affected: - (modified) lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp (+2-1) - (modified) lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp (+4-1) - (modified) lldb/source/Plugins/Process/Utility/AuxVector.cpp (+1) - (modified) lldb/source/Plugins/Process/Utility/AuxVector.h (+1) - (modified) lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp (+26-10) - (modified) lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h (+16-9) - (modified) lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp (+9-4) ``diff diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp index 7adc00622ec2d..0e23a3acbaa82 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp @@ -44,7 +44,8 @@ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( NativeProcessFreeBSD &process = native_thread.GetProcess(); g_register_flags_detector.DetectFields( process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0), -process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0)); +process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0), +/*hwcap3=*/std::nullopt); } return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread); diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index 884c7d4b9e359..b1c7421bef8d5 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -162,10 +162,13 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS); +std::optional auxv_at_hwcap3 = +process.GetAuxValue(AuxVector::AUXV_AT_HWCAP3); std::lock_guard lock(g_register_flags_detector_mutex); if (!g_register_flags_detector.HasDetected()) g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0), - auxv_at_hwcap2.value_or(0)); + auxv_at_hwcap2.value_or(0), + auxv_at_hwcap3.value_or(0)); auto register_info_up = std::make_unique(target_arch, opt_regsets); diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/lldb/source/Plugins/Process/Utility/AuxVector.cpp index f495ffb1924e7..50500a8593e1d 100644 --- a/lldb/source/Plugins/Process/Utility/AuxVector.cpp +++ b/lldb/source/Plugins/Process/Utility/AuxVector.cpp @@ -84,6 +84,7 @@ const char *AuxVector::GetEntryName(EntryType type) const { case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break; case ENTRY_NAME(AUXV_AT_RANDOM); break; case ENTRY_NAME(AUXV_AT_HWCAP2); break; +case ENTRY_NAME(AUXV_AT_HWCAP3); break; case ENTRY_NAME(AUXV_AT_EXECFN); break; case ENTRY_NAME(AUXV_AT_SYSINFO);break; case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break; diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.h b/lldb/source/Plugins/Process/Utility/AuxVector.h index 2670b34f6b0af..7733e0ffc6832 100644 --- a/lldb/source/Plugins/Process/Utility/AuxVector.h +++ b/lldb/source/Plugins/Process/Utility/AuxVector.h @@ -57,6 +57,7 @@ class AuxVector { AUXV_AT_BASE_PLATFORM = 24, ///< String identifying real platforms. AUXV_AT_RANDOM = 25,///< Address of 16 random bytes. AUXV_AT_HWCAP2 = 26,///< Extension of AT_HWCAP. +AUXV_AT_HWCAP3 = 29,///< Extension of AT_HWCAP. AUXV_AT_EXECFN = 31,///< Filename of executable. AUXV_AT_SYSINFO = 32, ///< Pointer to the global system page used for system /// calls and other nice things. diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp b/lldb/source/Plugins/Process/Utility/Reg
[Lldb-commits] [lldb] [lldb] Fix qEcho message handling (PR #145072)
github-actions[bot] wrote: :warning: Python code formatter, darker found issues in your code. :warning: You can test this locally with the following command: ``bash darker --check --diff -r HEAD~1...HEAD lldb/packages/Python/lldbsuite/test/gdbclientutils.py lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py `` View the diff from darker here. ``diff --- test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py 2025-06-20 16:46:24.00 + +++ test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py 2025-06-20 16:51:58.524928 + @@ -396,12 +396,12 @@ return [self.RESPONSE_NONE] def A(self, packet): return "E28" -#self.runCmd("log enable -f /tmp/lldb.log gdb-remote all") -#self.runCmd("settings set plugin.process.gdb-remote.packet-timeout 1") +# self.runCmd("log enable -f /tmp/lldb.log gdb-remote all") +# self.runCmd("settings set plugin.process.gdb-remote.packet-timeout 1") self.server.responder = MyResponder() target = self.createTarget("a.yaml") # NB: apparently GDB packets are using "/" on Windows too exe_path = self.getBuildArtifact("a").replace(os.path.sep, "/") `` https://github.com/llvm/llvm-project/pull/145072 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix qEcho message handling (PR #145072)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: None (eleviant) Changes Patch fixes the sync-on-timeout logic in lldb and switches to qEcho based ping, instead of qC. This fixes vRun message case, when there is no process yet and qC returns an error. --- Full diff: https://github.com/llvm/llvm-project/pull/145072.diff 4 Files Affected: - (modified) lldb/packages/Python/lldbsuite/test/gdbclientutils.py (+10) - (modified) lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (+2-1) - (modified) lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (+1-1) - (modified) lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py (+74) ``diff diff --git a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py index 753de22b9cfee..b603c35c8df09 100644 --- a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py +++ b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py @@ -92,6 +92,9 @@ class MockGDBServerResponder: class RESPONSE_DISCONNECT: pass +class RESPONSE_NONE: +pass + def __init__(self): self.packetLog = [] @@ -181,6 +184,8 @@ def respond(self, packet): return self.qQueryGDBServer() if packet == "qHostInfo": return self.qHostInfo() +if packet.startswith("qEcho"): +return self.qEcho(int(packet.split(":")[1])) if packet == "qGetWorkingDir": return self.qGetWorkingDir() if packet == "qOffsets": @@ -237,6 +242,9 @@ def qProcessInfo(self): def qHostInfo(self): return "ptrsize:8;endian:little;" +def qEcho(self): +return "E04" + def qQueryGDBServer(self): return "E04" @@ -655,6 +663,8 @@ def _handlePacket(self, packet): if not isinstance(response, list): response = [response] for part in response: +if part is MockGDBServerResponder.RESPONSE_NONE: +continue if part is MockGDBServerResponder.RESPONSE_DISCONNECT: raise self.TerminateConnectionException() self._sendPacket(part) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 2aea7c6b781d7..f244f7abe45e3 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -354,8 +354,9 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet, disconnected = true; Disconnect(); } +} else { + timed_out = true; } -timed_out = true; break; case eConnectionStatusSuccess: // printf ("status = success but error = %s\n", diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index adbf06b9a19a0..d8130cae71ce6 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -406,7 +406,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_supports_qXfer_memory_map_read = eLazyBoolYes; else if (x == "qXfer:siginfo:read+") m_supports_qXfer_siginfo_read = eLazyBoolYes; - else if (x == "qEcho") + else if (x == "qEcho+") m_supports_qEcho = eLazyBoolYes; else if (x == "QPassSignals+") m_supports_QPassSignals = eLazyBoolYes; diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py index 08ac9290ee85a..49e589226b0ef 100644 --- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py @@ -356,6 +356,80 @@ def A(self, packet): ["vRun;%s;61726731;61726732;61726733" % (exe_hex,)] ) +def test_launch_lengthy_vRun(self): +class MyResponder(MockGDBServerResponder): +def __init__(self, *args, **kwargs): +self.started = False +return super().__init__(*args, **kwargs) + +def qC(self): +if self.started: +return "QCp10.10" +else: +return "E42" + +def qfThreadInfo(self): +if self.started: +return "mp10.10" +else: +return "E42" + +def qsThreadInfo(self): +return "l" + +def qEcho(self, num): +resp = "qEcho:" + str(num) +if num >= 2: +# We have launched our program +self.started
[Lldb-commits] [lldb] [lldb] Fix qEcho message handling (PR #145072)
https://github.com/eleviant updated https://github.com/llvm/llvm-project/pull/145072 >From 8436977c0331765ab17dbb47cd7113352642e575 Mon Sep 17 00:00:00 2001 From: Evgeny Leviant Date: Fri, 20 Jun 2025 18:46:24 +0200 Subject: [PATCH 1/2] [lldb] Fix qEcho message handling Patch fixes the sync-on-timeout logic in lldb and switches to qEcho based ping, instead of qC. This fixes vRun message case, when there is no process yet and qC returns an error. --- .../Python/lldbsuite/test/gdbclientutils.py | 10 +++ .../gdb-remote/GDBRemoteCommunication.cpp | 3 +- .../GDBRemoteCommunicationClient.cpp | 2 +- .../gdb_remote_client/TestGDBRemoteClient.py | 74 +++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py index 753de22b9cfee..b603c35c8df09 100644 --- a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py +++ b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py @@ -92,6 +92,9 @@ class MockGDBServerResponder: class RESPONSE_DISCONNECT: pass +class RESPONSE_NONE: +pass + def __init__(self): self.packetLog = [] @@ -181,6 +184,8 @@ def respond(self, packet): return self.qQueryGDBServer() if packet == "qHostInfo": return self.qHostInfo() +if packet.startswith("qEcho"): +return self.qEcho(int(packet.split(":")[1])) if packet == "qGetWorkingDir": return self.qGetWorkingDir() if packet == "qOffsets": @@ -237,6 +242,9 @@ def qProcessInfo(self): def qHostInfo(self): return "ptrsize:8;endian:little;" +def qEcho(self): +return "E04" + def qQueryGDBServer(self): return "E04" @@ -655,6 +663,8 @@ def _handlePacket(self, packet): if not isinstance(response, list): response = [response] for part in response: +if part is MockGDBServerResponder.RESPONSE_NONE: +continue if part is MockGDBServerResponder.RESPONSE_DISCONNECT: raise self.TerminateConnectionException() self._sendPacket(part) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 2aea7c6b781d7..f244f7abe45e3 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -354,8 +354,9 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet, disconnected = true; Disconnect(); } +} else { + timed_out = true; } -timed_out = true; break; case eConnectionStatusSuccess: // printf ("status = success but error = %s\n", diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index adbf06b9a19a0..d8130cae71ce6 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -406,7 +406,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_supports_qXfer_memory_map_read = eLazyBoolYes; else if (x == "qXfer:siginfo:read+") m_supports_qXfer_siginfo_read = eLazyBoolYes; - else if (x == "qEcho") + else if (x == "qEcho+") m_supports_qEcho = eLazyBoolYes; else if (x == "QPassSignals+") m_supports_QPassSignals = eLazyBoolYes; diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py index 08ac9290ee85a..49e589226b0ef 100644 --- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py @@ -356,6 +356,80 @@ def A(self, packet): ["vRun;%s;61726731;61726732;61726733" % (exe_hex,)] ) +def test_launch_lengthy_vRun(self): +class MyResponder(MockGDBServerResponder): +def __init__(self, *args, **kwargs): +self.started = False +return super().__init__(*args, **kwargs) + +def qC(self): +if self.started: +return "QCp10.10" +else: +return "E42" + +def qfThreadInfo(self): +if self.started: +return "mp10.10" +else: +return "E42" + +def qsThreadInfo(self): +return "l" + +def qEcho(self, num): +resp = "qEcho:" + str(num) +if num >= 2: +# We have launched our program +
[Lldb-commits] [clang] [lldb] [Clang][PowerPC] Add __dmr1024 type and DMF integer calculation builtins (PR #142480)
https://github.com/maryammo closed https://github.com/llvm/llvm-project/pull/142480 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/143126 >From fc849bd4e831f9dc6f53be3a8508e1eb33f4151c Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Fri, 6 Jun 2025 13:15:41 +0100 Subject: [PATCH 1/3] [lldb] add plugin names to process save-core error output. show the plugin names in when running `help plugin save-core` --- lldb/include/lldb/Core/PluginManager.h| 2 ++ lldb/source/Commands/CommandObjectProcess.cpp | 24 - lldb/source/Core/PluginManager.cpp| 27 +++ lldb/source/Symbol/SaveCoreOptions.cpp| 17 +--- .../process_save_core/TestProcessSaveCore.py | 7 + ...ommand-process-save-core-not-a-plugin.test | 2 +- 6 files changed, 69 insertions(+), 10 deletions(-) diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index e7b169103..0e917025ba41e 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -270,6 +270,8 @@ class PluginManager { static Status SaveCore(const lldb::ProcessSP &process_sp, lldb_private::SaveCoreOptions &core_options); + static std::vector GetSaveCorePluginNames(); + // ObjectContainer static bool RegisterPlugin( llvm::StringRef name, llvm::StringRef description, diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index b1f243c9e2777..0a1744277d7dc 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -1281,7 +1281,27 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed { ~CommandOptions() override = default; llvm::ArrayRef GetDefinitions() override { - return llvm::ArrayRef(g_process_save_core_options); + if (!m_opt_def.empty()) +return llvm::ArrayRef(m_opt_def); + + auto orig = llvm::ArrayRef(g_process_save_core_options); + m_opt_def.resize(orig.size()); + llvm::copy(g_process_save_core_options, m_opt_def.data()); + for (OptionDefinition &value : m_opt_def) { +llvm::StringRef opt_name = value.long_option; +if (opt_name != "plugin-name") + continue; + +std::vector plugin_names = +PluginManager::GetSaveCorePluginNames(); +m_plugin_enums.resize(plugin_names.size()); +for (auto [num, val] : llvm::zip(plugin_names, m_plugin_enums)) { + val.string_value = num.data(); +} +value.enum_values = llvm::ArrayRef(m_plugin_enums); +break; + } + return llvm::ArrayRef(m_opt_def); } Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, @@ -1312,6 +1332,8 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed { // Instance variables to hold the values for command options. SaveCoreOptions m_core_dump_options; +llvm::SmallVector m_plugin_enums; +std::vector m_opt_def; }; protected: diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index 5d44434033c55..94d66f0f929cd 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -843,11 +843,28 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, } // Check to see if any of the object file plugins tried and failed to save. - // If none ran, set the error message. - if (error.Success()) -error = Status::FromErrorString( -"no ObjectFile plugins were able to save a core for this process"); - return error; + // if any failure, return the error message. + if (error.Fail()) +return error; + + // Report only for the plugin that was specified. + if (!plugin_name.empty()) +return Status::FromErrorStringWithFormatv( +"The \"{}\" plugin is not able to save a core for this process.", +plugin_name); + + return Status::FromErrorString( + "no ObjectFile plugins were able to save a core for this process"); +} + +std::vector PluginManager::GetSaveCorePluginNames() { + std::vector plugin_names; + auto instances = GetObjectFileInstances().GetSnapshot(); + for (auto &instance : instances) { +if (instance.save_core) + plugin_names.emplace_back(instance.name); + } + return plugin_names; } #pragma mark ObjectContainer diff --git a/lldb/source/Symbol/SaveCoreOptions.cpp b/lldb/source/Symbol/SaveCoreOptions.cpp index d884b00a47b00..0f9dbb73c1721 100644 --- a/lldb/source/Symbol/SaveCoreOptions.cpp +++ b/lldb/source/Symbol/SaveCoreOptions.cpp @@ -21,9 +21,20 @@ Status SaveCoreOptions::SetPluginName(const char *name) { return error; } - if (!PluginManager::IsRegisteredObjectFilePluginName(name)) { -return Status::FromErrorStringWithFormat( -"plugin name '%s' is not a valid ObjectFile plugin name", name); + std::vector plugin_names = + PluginManager::GetSaveCorePluginNames(); + if (llvm::find(plugin_name
[Lldb-commits] [lldb] [lldb] Fix qEcho message handling (PR #145072)
https://github.com/eleviant created https://github.com/llvm/llvm-project/pull/145072 Patch fixes the sync-on-timeout logic in lldb and switches to qEcho based ping, instead of qC. This fixes vRun message case, when there is no process yet and qC returns an error. >From 8436977c0331765ab17dbb47cd7113352642e575 Mon Sep 17 00:00:00 2001 From: Evgeny Leviant Date: Fri, 20 Jun 2025 18:46:24 +0200 Subject: [PATCH] [lldb] Fix qEcho message handling Patch fixes the sync-on-timeout logic in lldb and switches to qEcho based ping, instead of qC. This fixes vRun message case, when there is no process yet and qC returns an error. --- .../Python/lldbsuite/test/gdbclientutils.py | 10 +++ .../gdb-remote/GDBRemoteCommunication.cpp | 3 +- .../GDBRemoteCommunicationClient.cpp | 2 +- .../gdb_remote_client/TestGDBRemoteClient.py | 74 +++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py index 753de22b9cfee..b603c35c8df09 100644 --- a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py +++ b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py @@ -92,6 +92,9 @@ class MockGDBServerResponder: class RESPONSE_DISCONNECT: pass +class RESPONSE_NONE: +pass + def __init__(self): self.packetLog = [] @@ -181,6 +184,8 @@ def respond(self, packet): return self.qQueryGDBServer() if packet == "qHostInfo": return self.qHostInfo() +if packet.startswith("qEcho"): +return self.qEcho(int(packet.split(":")[1])) if packet == "qGetWorkingDir": return self.qGetWorkingDir() if packet == "qOffsets": @@ -237,6 +242,9 @@ def qProcessInfo(self): def qHostInfo(self): return "ptrsize:8;endian:little;" +def qEcho(self): +return "E04" + def qQueryGDBServer(self): return "E04" @@ -655,6 +663,8 @@ def _handlePacket(self, packet): if not isinstance(response, list): response = [response] for part in response: +if part is MockGDBServerResponder.RESPONSE_NONE: +continue if part is MockGDBServerResponder.RESPONSE_DISCONNECT: raise self.TerminateConnectionException() self._sendPacket(part) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 2aea7c6b781d7..f244f7abe45e3 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -354,8 +354,9 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet, disconnected = true; Disconnect(); } +} else { + timed_out = true; } -timed_out = true; break; case eConnectionStatusSuccess: // printf ("status = success but error = %s\n", diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index adbf06b9a19a0..d8130cae71ce6 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -406,7 +406,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_supports_qXfer_memory_map_read = eLazyBoolYes; else if (x == "qXfer:siginfo:read+") m_supports_qXfer_siginfo_read = eLazyBoolYes; - else if (x == "qEcho") + else if (x == "qEcho+") m_supports_qEcho = eLazyBoolYes; else if (x == "QPassSignals+") m_supports_QPassSignals = eLazyBoolYes; diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py index 08ac9290ee85a..49e589226b0ef 100644 --- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py @@ -356,6 +356,80 @@ def A(self, packet): ["vRun;%s;61726731;61726732;61726733" % (exe_hex,)] ) +def test_launch_lengthy_vRun(self): +class MyResponder(MockGDBServerResponder): +def __init__(self, *args, **kwargs): +self.started = False +return super().__init__(*args, **kwargs) + +def qC(self): +if self.started: +return "QCp10.10" +else: +return "E42" + +def qfThreadInfo(self): +if self.started: +return "mp10.10" +else: +return "E42" + +def qsThreadInfo(self): +
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
https://github.com/dlav-sc updated https://github.com/llvm/llvm-project/pull/127505 >From 2520b8d7884d320ed7923685b1a3e8652a7e8f5f Mon Sep 17 00:00:00 2001 From: Daniil Avdeev Date: Fri, 23 May 2025 13:27:46 + Subject: [PATCH 1/4] [lldb][RISCV] handle lr/sc single step lldb-server had limited support for single-stepping through the lr/sc atomic sequence. This patch enhances that support for all possible atomic sequences. --- lldb/include/lldb/Core/EmulateInstruction.h | 45 +++ lldb/source/Core/EmulateInstruction.cpp | 93 + .../Instruction/ARM/EmulateInstructionARM.cpp | 11 ++ .../Instruction/ARM/EmulateInstructionARM.h | 18 +++ .../LoongArch/EmulateInstructionLoongArch.cpp | 122 +++--- .../LoongArch/EmulateInstructionLoongArch.h | 2 - .../RISCV/EmulateInstructionRISCV.cpp | 117 ++--- .../RISCV/EmulateInstructionRISCV.h | 37 +- .../Process/FreeBSD/NativeProcessFreeBSD.cpp | 14 +- .../NativeProcessSoftwareSingleStep.cpp | 108 +++- .../Utility/NativeProcessSoftwareSingleStep.h | 2 +- .../LoongArch/TestLoongArchEmulator.cpp | 36 +++--- 12 files changed, 422 insertions(+), 183 deletions(-) diff --git a/lldb/include/lldb/Core/EmulateInstruction.h b/lldb/include/lldb/Core/EmulateInstruction.h index b459476883fc5..0e3564206ccb8 100644 --- a/lldb/include/lldb/Core/EmulateInstruction.h +++ b/lldb/include/lldb/Core/EmulateInstruction.h @@ -32,6 +32,31 @@ class RegisterValue; class Stream; class Target; class UnwindPlan; +class EmulateInstruction; + +using BreakpointLocations = std::vector; + +class SingleStepBreakpointLocationsPredictor { +public: + SingleStepBreakpointLocationsPredictor( + std::unique_ptr emulator_up) + : m_emulator_up{std::move(emulator_up)} {} + + virtual BreakpointLocations GetBreakpointLocations(Status &status); + + virtual unsigned GetBreakpointSize(lldb::addr_t, Status &) { return 4; } + + virtual ~SingleStepBreakpointLocationsPredictor() = default; + +protected: + lldb::addr_t GetSequentiallyNextInstructionPC(Status &error); + + lldb::addr_t GetBreakpointLocationAddress(lldb::addr_t entry_pc, +Status &error); + + std::unique_ptr m_emulator_up; + bool m_emulation_result = false; +}; /// \class EmulateInstruction EmulateInstruction.h /// "lldb/Core/EmulateInstruction.h" @@ -497,7 +522,19 @@ class EmulateInstruction : public PluginInterface { static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx, const RegisterInfo ®_info); + static std::unique_ptr + CreateBreakpointLocationPredictor( + std::unique_ptr emulator_up); + + // Helper functions + std::optional ReadPC(); + bool WritePC(lldb::addr_t addr); + protected: + using BreakpointLocationsPredictorCreator = + std::function( + std::unique_ptr)>; + ArchSpec m_arch; void *m_baton = nullptr; ReadMemoryCallback m_read_mem_callback = &ReadMemoryDefault; @@ -508,6 +545,14 @@ class EmulateInstruction : public PluginInterface { Opcode m_opcode; private: + virtual BreakpointLocationsPredictorCreator + GetSingleStepBreakpointLocationsPredictorCreator() { +return [](std::unique_ptr emulator_up) { + return std::make_unique( + std::move(emulator_up)); +}; + } + // For EmulateInstruction only EmulateInstruction(const EmulateInstruction &) = delete; const EmulateInstruction &operator=(const EmulateInstruction &) = delete; diff --git a/lldb/source/Core/EmulateInstruction.cpp b/lldb/source/Core/EmulateInstruction.cpp index d240b4d3b3310..3bc7beff8ac7f 100644 --- a/lldb/source/Core/EmulateInstruction.cpp +++ b/lldb/source/Core/EmulateInstruction.cpp @@ -588,7 +588,100 @@ EmulateInstruction::GetInternalRegisterNumber(RegisterContext *reg_ctx, return LLDB_INVALID_REGNUM; } +std::unique_ptr +EmulateInstruction::CreateBreakpointLocationPredictor( +std::unique_ptr emulator_up) { + auto creator = + emulator_up->GetSingleStepBreakpointLocationsPredictorCreator(); + return creator(std::move(emulator_up)); +} + +std::optional EmulateInstruction::ReadPC() { + bool success = false; + auto addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, + LLDB_INVALID_ADDRESS, &success); + return success ? std::optional(addr) : std::nullopt; +} + +bool EmulateInstruction::WritePC(lldb::addr_t addr) { + EmulateInstruction::Context ctx; + ctx.type = eContextAdvancePC; + ctx.SetNoArgs(); + return WriteRegisterUnsigned(ctx, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC, addr); +} + bool EmulateInstruction::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { unwind_plan.Clear(); return false; } + +BreakpointLocations +SingleStepBreakpointLocationsPredictor::GetBreakpointLocations(Status &status) { + if (!m_emulator_up->ReadInstruction()
[Lldb-commits] [lldb] Revert "[lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes" (PR #145065)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes Reverts llvm/llvm-project#144880 Caused `TestObjCIvarsInBlocks.py` to fail on macOS CI. --- Full diff: https://github.com/llvm/llvm-project/pull/145065.diff 2 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+20-8) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (+3-4) ``diff diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 3bec89cdf7469..4f79c8aa3f811 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -445,6 +445,15 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) { name.SetCString(form_value.AsCString()); break; +case DW_AT_object_pointer: + // GetAttributes follows DW_AT_specification. + // DW_TAG_subprogram definitions and declarations may both + // have a DW_AT_object_pointer. Don't overwrite the one + // we parsed for the definition with the one from the declaration. + if (!object_pointer.IsValid()) +object_pointer = form_value.Reference(); + break; + case DW_AT_signature: signature = form_value; break; @@ -1107,7 +1116,7 @@ bool DWARFASTParserClang::ParseObjCMethod( std::pair DWARFASTParserClang::ParseCXXMethod( const DWARFDIE &die, CompilerType clang_type, const ParsedDWARFTypeAttributes &attrs, const DWARFDIE &decl_ctx_die, -const DWARFDIE &object_parameter, bool &ignore_containing_context) { +bool is_static, bool &ignore_containing_context) { Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); SymbolFileDWARF *dwarf = die.GetDWARF(); assert(dwarf); @@ -1191,9 +1200,6 @@ std::pair DWARFASTParserClang::ParseCXXMethod( TypeSystemClang::GetDeclContextForType(class_opaque_type), die, attrs.name.GetCString()); - // In DWARF, a C++ method is static if it has no object parameter child. - const bool is_static = !object_parameter.IsValid(); - // We have a C++ member function with no children (this pointer!) and clang // will get mad if we try and make a function that isn't well formed in the // DWARF, so we will just skip it... @@ -1219,7 +1225,9 @@ std::pair DWARFASTParserClang::ParseCXXMethod( ClangASTMetadata metadata; metadata.SetUserID(die.GetID()); -if (char const *object_pointer_name = object_parameter.GetName()) { +char const *object_pointer_name = +attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr; +if (object_pointer_name) { metadata.SetObjectPtrName(object_pointer_name); LLDB_LOGF(log, "Setting object pointer name: %s on method object %p.\n", object_pointer_name, static_cast(cxx_method_decl)); @@ -1315,9 +1323,11 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, type_handled = ParseObjCMethod(*objc_method, die, clang_type, attrs, is_variadic); } else if (is_cxx_method) { +// In DWARF, a C++ method is static if it has no object parameter child. +const bool is_static = !object_parameter.IsValid(); auto [handled, type_sp] = -ParseCXXMethod(die, clang_type, attrs, decl_ctx_die, - object_parameter, ignore_containing_context); +ParseCXXMethod(die, clang_type, attrs, decl_ctx_die, is_static, + ignore_containing_context); if (type_sp) return type_sp; @@ -1412,7 +1422,9 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, ClangASTMetadata metadata; metadata.SetUserID(die.GetID()); - if (char const *object_pointer_name = object_parameter.GetName()) { + char const *object_pointer_name = + attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr; + if (object_pointer_name) { metadata.SetObjectPtrName(object_pointer_name); LLDB_LOGF(log, "Setting object pointer name: %s on function " diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index a90f55bcff948..111604ce4068a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -470,8 +470,7 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser { /// \param[in] decl_ctx_die The DIE representing the DeclContext of the C++ /// method being parsed. /// - /// \param[in] object_parameter The DIE of this subprogram's object parameter. - /// May be an invalid DIE for C++ static methods. + /// \param[in] is_static Is true i
[Lldb-commits] [lldb] [LLDB] Update DIL to pass current 'frame var' tests. (PR #145055)
https://github.com/cmtice created https://github.com/llvm/llvm-project/pull/145055 As a preliminary to making DIL the default implementation for 'frame var', ran check-lldb forcing 'frame var' to always use DIL, and discovered a few failing tests. This fixes most of them. The only two remaining failing tests (once the smart pointer PR is committed) are TestVarPath.py, which fails a test case using a negative array subscript, as DIL does not yet parse negative numbers; and TestDAP_evaluate.py, which now passes a test case that the test says should fail (still investigating this). Changes in this PR: - Sets correct VariableSP, as well as returning ValueObjectSP (needed for several watchpoint tests). - Updates error messages, when looking up members, to match what the rest of LLDB expects. Also update appropriate DIL tests to expect the updated error messages. - Updates DIL parser tolook for and accept "(anonymous namespace)::" at the front of a variable name. >From e9079e6357b933e84603997edb8d0cd27a515989 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Fri, 20 Jun 2025 08:33:14 -0700 Subject: [PATCH] [LLDB] Update DIL to pass current 'frame var' tests. As a preliminary to making DIL the default implementation for 'frame var', ran check-lldb forcing 'frame var' to always use DIL, and discovered a few failing tests. This fixes most of them. The only two remaining failing tests (once the smart pointer PR is committed) are TestVarPath.py, which fails a test case using a negative array subscript, as DIL does not yet parse negative numbers; and TestDAP_evaluate.py, which now passes a test case that the test says should fail (still investigating this). Changes in this PR: - Sets correct VariableSP, as well as returning ValueObjectSP (needed for several watchpoint tests). - Update error messages, when looking up members, to match what the rest of LLDB expects. Also update appropriate DIL tests to expect the updated error messages. - Update DIL parser to look for and accept "(anonymous namespace)::" at the front of a variable name. --- lldb/source/Target/StackFrame.cpp | 1 + lldb/source/ValueObject/DILEval.cpp | 10 ++--- lldb/source/ValueObject/DILParser.cpp | 39 --- .../MemberOf/TestFrameVarDILMemberOf.py | 2 +- .../TestFrameVarDILMemberOfAnonymousMember.py | 10 ++--- 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index ab5cd0b27c789..f5a80efc821d5 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -562,6 +562,7 @@ ValueObjectSP StackFrame::DILGetValueForVariableExpressionPath( return ValueObjectConstResult::Create(nullptr, std::move(error)); } + var_sp = (*valobj_or_error)->GetVariable(); return *valobj_or_error; } diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp index c8cb54aa18a93..2c4d355a2c6b8 100644 --- a/lldb/source/ValueObject/DILEval.cpp +++ b/lldb/source/ValueObject/DILEval.cpp @@ -356,8 +356,8 @@ Interpreter::Visit(const MemberOfNode *node) { if (!m_use_synthetic || !field_obj) { std::string errMsg = llvm::formatv( - "no member named '{0}' in {1}", node->GetFieldName(), - base->GetCompilerType().GetFullyUnqualifiedType().TypeDescription()); + "\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(), + base->GetTypeName().AsCString(""), base->GetName()); return llvm::make_error( m_expr, errMsg, node->GetLocation(), node->GetFieldName().size()); } @@ -376,9 +376,9 @@ Interpreter::Visit(const MemberOfNode *node) { CompilerType base_type = base->GetCompilerType(); if (node->GetIsArrow() && base->IsPointerType()) base_type = base_type.GetPointeeType(); - std::string errMsg = - llvm::formatv("no member named '{0}' in {1}", node->GetFieldName(), -base_type.GetFullyUnqualifiedType().TypeDescription()); + std::string errMsg = llvm::formatv( + "\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(), + base->GetTypeName().AsCString(""), base->GetName()); return llvm::make_error( m_expr, errMsg, node->GetLocation(), node->GetFieldName().size()); } diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp index 9667885734f21..37d5bd30fa61f 100644 --- a/lldb/source/ValueObject/DILParser.cpp +++ b/lldb/source/ValueObject/DILParser.cpp @@ -178,11 +178,40 @@ ASTNodeUP DILParser::ParsePrimaryExpression() { } if (CurToken().Is(Token::l_paren)) { -m_dil_lexer.Advance(); -auto expr = ParseExpression(); -Expect(Token::r_paren); -m_dil_lexer.Advance(); -return expr; +// Check in case this is an anonynmous namespace +if (m_dil_lexer.LookAhead(1).Is(Token::identifier) && +(m_dil_lexer.LookAhead(1).GetSpelling() == "anon
[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)
@@ -16,4 +16,4 @@ run da-viper wrote: did not run it with a file since that is tested in the `TestProcessSaveCore.py` file. https://github.com/llvm/llvm-project/pull/143126 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)
github-actions[bot] wrote: :warning: Python code formatter, darker found issues in your code. :warning: You can test this locally with the following command: ``bash darker --check --diff -r HEAD~1...HEAD lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/TestDataFormatterStdString.py lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/TestDataFormatterStdU8String.py lldb/packages/Python/lldbsuite/test/dotest.py lldb/packages/Python/lldbsuite/test/test_categories.py `` View the diff from darker here. ``diff --- packages/Python/lldbsuite/test/dotest.py2025-06-20 14:32:46.00 + +++ packages/Python/lldbsuite/test/dotest.py2025-06-20 14:35:07.689297 + @@ -856,10 +856,11 @@ """ ) if not p.returncode: return True, "Compiling with MSVC STL" return (False, f"Not compiling with MSVC STL: {stderr}") + def checkMsvcStlSupport(): result, reason = canRunMsvcStlTests() if result: return # msvcstl supported `` https://github.com/llvm/llvm-project/pull/143177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [NFC][DebugInfo][DWARF] Create new low-level dwarf library (PR #145081)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp bolt/include/bolt/Core/DIEBuilder.h bolt/lib/Core/DIEBuilder.cpp bolt/lib/Core/DebugNames.cpp bolt/lib/Rewrite/DWARFRewriter.cpp lldb/source/Expression/DWARFExpression.cpp lldb/source/Symbol/UnwindPlan.cpp lldb/unittests/Symbol/PostfixExpressionTest.cpp lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp llvm/include/llvm/DWARFLinker/AddressesMap.h llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp llvm/lib/DebugInfo/DWARF/DWARFDie.cpp llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp llvm/lib/ProfileData/InstrProfCorrelator.cpp llvm/tools/dsymutil/DwarfLinkerForBinary.cpp llvm/tools/llvm-dwarfdump/Statistics.cpp llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp llvm/tools/llvm-objdump/SourcePrinter.cpp llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp `` View the diff from clang-format here. ``diff diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h index 73f44c500..e4a4fc6b2 100644 --- a/bolt/include/bolt/Core/DIEBuilder.h +++ b/bolt/include/bolt/Core/DIEBuilder.h @@ -20,8 +20,8 @@ #include "llvm/CodeGen/DIE.h" #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" -#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h" #include "llvm/Support/Allocator.h" #include diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp index e94fffbf4..b041dc5ea 100644 --- a/bolt/lib/Core/DIEBuilder.cpp +++ b/bolt/lib/Core/DIEBuilder.cpp @@ -14,11 +14,11 @@ #include "llvm/CodeGen/DIE.h" #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" -#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" +#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp index 9e3c0f9c7..a9d98a6ba 100644 --- a/bolt/lib/Core/DebugNames.cpp +++ b/bolt/lib/Core/DebugNames.cpp @@ -8,8 +8,8 @@ #include "bolt/Core/DebugNames.h" #include "bolt/Core/BinaryContext.h" -#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h" #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" +#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/LEB128.h" #include diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index a55a3f76b..0c1a1bac6 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -24,10 +24,10 @@ #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" -#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCObjectWriter.h" diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 57e368b72..2df27513a 100644 --- a/lld
[Lldb-commits] [lldb] [LLDB] Update DIL to pass current 'frame var' tests. (PR #145055)
https://github.com/cmtice updated https://github.com/llvm/llvm-project/pull/145055 >From e9079e6357b933e84603997edb8d0cd27a515989 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Fri, 20 Jun 2025 08:33:14 -0700 Subject: [PATCH 1/3] [LLDB] Update DIL to pass current 'frame var' tests. As a preliminary to making DIL the default implementation for 'frame var', ran check-lldb forcing 'frame var' to always use DIL, and discovered a few failing tests. This fixes most of them. The only two remaining failing tests (once the smart pointer PR is committed) are TestVarPath.py, which fails a test case using a negative array subscript, as DIL does not yet parse negative numbers; and TestDAP_evaluate.py, which now passes a test case that the test says should fail (still investigating this). Changes in this PR: - Sets correct VariableSP, as well as returning ValueObjectSP (needed for several watchpoint tests). - Update error messages, when looking up members, to match what the rest of LLDB expects. Also update appropriate DIL tests to expect the updated error messages. - Update DIL parser to look for and accept "(anonymous namespace)::" at the front of a variable name. --- lldb/source/Target/StackFrame.cpp | 1 + lldb/source/ValueObject/DILEval.cpp | 10 ++--- lldb/source/ValueObject/DILParser.cpp | 39 --- .../MemberOf/TestFrameVarDILMemberOf.py | 2 +- .../TestFrameVarDILMemberOfAnonymousMember.py | 10 ++--- 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index ab5cd0b27c789..f5a80efc821d5 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -562,6 +562,7 @@ ValueObjectSP StackFrame::DILGetValueForVariableExpressionPath( return ValueObjectConstResult::Create(nullptr, std::move(error)); } + var_sp = (*valobj_or_error)->GetVariable(); return *valobj_or_error; } diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp index c8cb54aa18a93..2c4d355a2c6b8 100644 --- a/lldb/source/ValueObject/DILEval.cpp +++ b/lldb/source/ValueObject/DILEval.cpp @@ -356,8 +356,8 @@ Interpreter::Visit(const MemberOfNode *node) { if (!m_use_synthetic || !field_obj) { std::string errMsg = llvm::formatv( - "no member named '{0}' in {1}", node->GetFieldName(), - base->GetCompilerType().GetFullyUnqualifiedType().TypeDescription()); + "\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(), + base->GetTypeName().AsCString(""), base->GetName()); return llvm::make_error( m_expr, errMsg, node->GetLocation(), node->GetFieldName().size()); } @@ -376,9 +376,9 @@ Interpreter::Visit(const MemberOfNode *node) { CompilerType base_type = base->GetCompilerType(); if (node->GetIsArrow() && base->IsPointerType()) base_type = base_type.GetPointeeType(); - std::string errMsg = - llvm::formatv("no member named '{0}' in {1}", node->GetFieldName(), -base_type.GetFullyUnqualifiedType().TypeDescription()); + std::string errMsg = llvm::formatv( + "\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(), + base->GetTypeName().AsCString(""), base->GetName()); return llvm::make_error( m_expr, errMsg, node->GetLocation(), node->GetFieldName().size()); } diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp index 9667885734f21..37d5bd30fa61f 100644 --- a/lldb/source/ValueObject/DILParser.cpp +++ b/lldb/source/ValueObject/DILParser.cpp @@ -178,11 +178,40 @@ ASTNodeUP DILParser::ParsePrimaryExpression() { } if (CurToken().Is(Token::l_paren)) { -m_dil_lexer.Advance(); -auto expr = ParseExpression(); -Expect(Token::r_paren); -m_dil_lexer.Advance(); -return expr; +// Check in case this is an anonynmous namespace +if (m_dil_lexer.LookAhead(1).Is(Token::identifier) && +(m_dil_lexer.LookAhead(1).GetSpelling() == "anonymous") && +m_dil_lexer.LookAhead(2).Is(Token::identifier) && +(m_dil_lexer.LookAhead(2).GetSpelling() == "namespace") && +m_dil_lexer.LookAhead(3).Is(Token::r_paren) && +m_dil_lexer.LookAhead(4).Is(Token::coloncolon)) { + m_dil_lexer.Advance(4); + + std::string identifier = "(anonymous namespace)"; + Expect(Token::coloncolon); + // Save the source location for the diagnostics message. + uint32_t loc = CurToken().GetLocation(); + m_dil_lexer.Advance(); + assert( + (CurToken().Is(Token::identifier) || CurToken().Is(Token::l_paren)) && + "Expected an identifier or anonymous namespeace, but not found."); + std::string identifier2 = ParseNestedNameSpecifier(); + if (identifier2.empty()) { +// There was only an identifer, no more levels of nesting. Or there +// was an invalid expression sta
[Lldb-commits] [lldb] [LLDB] Update DIL to pass current 'frame var' tests. (PR #145055)
https://github.com/cmtice updated https://github.com/llvm/llvm-project/pull/145055 >From e9079e6357b933e84603997edb8d0cd27a515989 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Fri, 20 Jun 2025 08:33:14 -0700 Subject: [PATCH 1/2] [LLDB] Update DIL to pass current 'frame var' tests. As a preliminary to making DIL the default implementation for 'frame var', ran check-lldb forcing 'frame var' to always use DIL, and discovered a few failing tests. This fixes most of them. The only two remaining failing tests (once the smart pointer PR is committed) are TestVarPath.py, which fails a test case using a negative array subscript, as DIL does not yet parse negative numbers; and TestDAP_evaluate.py, which now passes a test case that the test says should fail (still investigating this). Changes in this PR: - Sets correct VariableSP, as well as returning ValueObjectSP (needed for several watchpoint tests). - Update error messages, when looking up members, to match what the rest of LLDB expects. Also update appropriate DIL tests to expect the updated error messages. - Update DIL parser to look for and accept "(anonymous namespace)::" at the front of a variable name. --- lldb/source/Target/StackFrame.cpp | 1 + lldb/source/ValueObject/DILEval.cpp | 10 ++--- lldb/source/ValueObject/DILParser.cpp | 39 --- .../MemberOf/TestFrameVarDILMemberOf.py | 2 +- .../TestFrameVarDILMemberOfAnonymousMember.py | 10 ++--- 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index ab5cd0b27c789..f5a80efc821d5 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -562,6 +562,7 @@ ValueObjectSP StackFrame::DILGetValueForVariableExpressionPath( return ValueObjectConstResult::Create(nullptr, std::move(error)); } + var_sp = (*valobj_or_error)->GetVariable(); return *valobj_or_error; } diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp index c8cb54aa18a93..2c4d355a2c6b8 100644 --- a/lldb/source/ValueObject/DILEval.cpp +++ b/lldb/source/ValueObject/DILEval.cpp @@ -356,8 +356,8 @@ Interpreter::Visit(const MemberOfNode *node) { if (!m_use_synthetic || !field_obj) { std::string errMsg = llvm::formatv( - "no member named '{0}' in {1}", node->GetFieldName(), - base->GetCompilerType().GetFullyUnqualifiedType().TypeDescription()); + "\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(), + base->GetTypeName().AsCString(""), base->GetName()); return llvm::make_error( m_expr, errMsg, node->GetLocation(), node->GetFieldName().size()); } @@ -376,9 +376,9 @@ Interpreter::Visit(const MemberOfNode *node) { CompilerType base_type = base->GetCompilerType(); if (node->GetIsArrow() && base->IsPointerType()) base_type = base_type.GetPointeeType(); - std::string errMsg = - llvm::formatv("no member named '{0}' in {1}", node->GetFieldName(), -base_type.GetFullyUnqualifiedType().TypeDescription()); + std::string errMsg = llvm::formatv( + "\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(), + base->GetTypeName().AsCString(""), base->GetName()); return llvm::make_error( m_expr, errMsg, node->GetLocation(), node->GetFieldName().size()); } diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp index 9667885734f21..37d5bd30fa61f 100644 --- a/lldb/source/ValueObject/DILParser.cpp +++ b/lldb/source/ValueObject/DILParser.cpp @@ -178,11 +178,40 @@ ASTNodeUP DILParser::ParsePrimaryExpression() { } if (CurToken().Is(Token::l_paren)) { -m_dil_lexer.Advance(); -auto expr = ParseExpression(); -Expect(Token::r_paren); -m_dil_lexer.Advance(); -return expr; +// Check in case this is an anonynmous namespace +if (m_dil_lexer.LookAhead(1).Is(Token::identifier) && +(m_dil_lexer.LookAhead(1).GetSpelling() == "anonymous") && +m_dil_lexer.LookAhead(2).Is(Token::identifier) && +(m_dil_lexer.LookAhead(2).GetSpelling() == "namespace") && +m_dil_lexer.LookAhead(3).Is(Token::r_paren) && +m_dil_lexer.LookAhead(4).Is(Token::coloncolon)) { + m_dil_lexer.Advance(4); + + std::string identifier = "(anonymous namespace)"; + Expect(Token::coloncolon); + // Save the source location for the diagnostics message. + uint32_t loc = CurToken().GetLocation(); + m_dil_lexer.Advance(); + assert( + (CurToken().Is(Token::identifier) || CurToken().Is(Token::l_paren)) && + "Expected an identifier or anonymous namespeace, but not found."); + std::string identifier2 = ParseNestedNameSpecifier(); + if (identifier2.empty()) { +// There was only an identifer, no more levels of nesting. Or there +// was an invalid expression sta
[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)
@@ -74,24 +74,48 @@ struct DemangledNameInfo { return BasenameRange.second > BasenameRange.first; } + /// Returns \c true if `BasenameRange` is empty. + bool isBasenameEmpty() const { +return BasenameRange.first == BasenameRange.second; Michael137 wrote: Hmm I think I'd prefer having only a single API that tells us "do we have a valid entity or not". E.g., `hasValidQualifiers`/`hasValidBasename`/etc. Is there a reason we can't just modify the existing `hasXXX` helpers to be `Range.second >= Range.first`? If we are going to call `!hasXXX && !isEmpty` then might as well fold them into a single API. But if there's reasons we can't do that, this seems fine too https://github.com/llvm/llvm-project/pull/144731 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Socket::CreatePair (PR #145015)
https://github.com/JDevlieghere edited https://github.com/llvm/llvm-project/pull/145015 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Socket::CreatePair (PR #145015)
@@ -52,6 +52,34 @@ TCPSocket::TCPSocket(NativeSocket socket, bool should_close) TCPSocket::~TCPSocket() { CloseListenSockets(); } +llvm::Expected< +std::pair, std::unique_ptr>> +TCPSocket::CreatePair() { + auto listen_socket_up = std::make_unique(true); + if (Status error = listen_socket_up->Listen("localhost:0", 5); error.Fail()) +return error.takeError(); + + std::string connect_address = + llvm::StringRef(listen_socket_up->GetListeningConnectionURI()[0]) + .split("://") + .second.str(); + + auto connect_socket_up = std::make_unique(true); + if (Status error = connect_socket_up->Connect(connect_address); error.Fail()) +return error.takeError(); + + // Connection has already been made above, so a short timeout is sufficient. + Socket *accept_socket; + if (Status error = + listen_socket_up->Accept(std::chrono::seconds(1), accept_socket); JDevlieghere wrote: Can you think of a reason why we couldn't change the signature of `Socket::Accept` to return an `llvm::Expected>` instead of this Status + Socket* out parameter? Not trying to sign you up for it but it stands out. https://github.com/llvm/llvm-project/pull/145015 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Socket::CreatePair (PR #145015)
https://github.com/JDevlieghere approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/145015 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Socket::CreatePair (PR #145015)
@@ -106,6 +106,10 @@ class Socket : public IOObject { static std::unique_ptr Create(const SocketProtocol protocol, Status &error); + static llvm::Expected< + std::pair, std::unique_ptr>> JDevlieghere wrote: Nit: Maybe add a `Socket::Pair` or `Socket::SocketPair` typedef to make these declarations a little less verbose? ``` using Pair = std::pair, std::unique_ptr>; ``` https://github.com/llvm/llvm-project/pull/145015 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix SBMemoryRegionInfoListExtensions iter to yield unique refe… (PR #144815)
https://github.com/zyn-li updated https://github.com/llvm/llvm-project/pull/144815 >From 16792f7dffae9ef95a3a09c2dbaa6731b07e0ea7 Mon Sep 17 00:00:00 2001 From: Zhiyuan Li Date: Wed, 18 Jun 2025 16:49:12 -0700 Subject: [PATCH 1/2] [lldb] Fix SBMemoryRegionInfoListExtensions iter to yield unique references --- .../SBMemoryRegionInfoListExtensions.i| 2 +- .../find_in_memory/TestFindInMemory.py| 24 --- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lldb/bindings/interface/SBMemoryRegionInfoListExtensions.i b/lldb/bindings/interface/SBMemoryRegionInfoListExtensions.i index 29c0179c0ffe3..f565f45880119 100644 --- a/lldb/bindings/interface/SBMemoryRegionInfoListExtensions.i +++ b/lldb/bindings/interface/SBMemoryRegionInfoListExtensions.i @@ -9,8 +9,8 @@ '''Iterate over all the memory regions in a lldb.SBMemoryRegionInfoList object.''' import lldb size = self.GetSize() - region = lldb.SBMemoryRegionInfo() for i in range(size): +region = lldb.SBMemoryRegionInfo() self.GetMemoryRegionAtIndex(i, region) yield region %} diff --git a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py index 1ef37d2ec9898..4eabbb6e46774 100644 --- a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py +++ b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py @@ -154,14 +154,32 @@ def test_find_in_memory_unaligned(self): self.assertEqual(addr, lldb.LLDB_INVALID_ADDRESS) def test_memory_info_list_iterable(self): -"""Make sure the SBMemoryRegionInfoList is iterable""" +"""Make sure the SBMemoryRegionInfoList is iterable and each yielded object is unique""" self.assertTrue(self.process, PROCESS_IS_VALID) self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) info_list = self.process.GetMemoryRegions() self.assertTrue(info_list.GetSize() > 0) + +collected_info = [] try: -for info in info_list: -pass +for region in info_list: +collected_info.append(region) except Exception: self.fail("SBMemoryRegionInfoList is not iterable") + +self.assertTrue(len(collected_info) >= 2, "Need at least 2 items") +self.assertEqual(len(collected_info), info_list.GetSize(), "Should have collected all items") + +for i in range(len(collected_info)): +region = lldb.SBMemoryRegionInfo() +info_list.GetMemoryRegionAtIndex(i, region) + +self.assertEqual(collected_info[i].GetRegionBase(), region.GetRegionBase(), + f"items {i}: iterator data should match index access data") +self.assertEqual(collected_info[i].GetRegionEnd(), region.GetRegionEnd(), + f"items {i}: iterator data should match index access data") + +if len(collected_info) >= 2: +self.assertNotEqual(collected_info[0].GetRegionBase(), collected_info[1].GetRegionBase(), + "Different items should have different base addresses") >From b3015471bff73981807174d9913a144590126e17 Mon Sep 17 00:00:00 2001 From: zyn-li Date: Fri, 20 Jun 2025 11:47:18 -0700 Subject: [PATCH 2/2] use SBMemoryRegionInfo equality operator in test --- .../find_in_memory/TestFindInMemory.py| 27 ++- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py index 4eabbb6e46774..d61fdb16e2a02 100644 --- a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py +++ b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py @@ -163,23 +163,24 @@ def test_memory_info_list_iterable(self): collected_info = [] try: -for region in info_list: -collected_info.append(region) +for info in info_list: +collected_info.append(info) except Exception: self.fail("SBMemoryRegionInfoList is not iterable") - -self.assertTrue(len(collected_info) >= 2, "Need at least 2 items") -self.assertEqual(len(collected_info), info_list.GetSize(), "Should have collected all items") for i in range(len(collected_info)): region = lldb.SBMemoryRegionInfo() info_list.GetMemoryRegionAtIndex(i, region) - -self.assertEqual(collected_info[i].GetRegionBase(), region.GetRegionBase(), - f"items {i}: iterator data should match index access data") -self.assertEqual(collected_info[i].GetRegionEnd(), region.GetRegionEnd(), - f"items {i}: iterator data should match index access data") -
[Lldb-commits] [clang] [clang-tools-extra] [lldb] [clang] Remove intrusive reference count from `DiagnosticOptions` (PR #139584)
jyknight wrote: > Thanks for the concrete example! [..] I just wanted to thank you (a bit late) for the explanation above, it was really helpful! > FWIW I'd like to get rid of the reference count of DiagnosticsEngine too, and > make the lifetimes stricter and more explicit, but that's a lower priority > compared to the DiagnosticOptions refactor for me. I do hope that will happen someday, because that does seem to be a key part of the confusion here. But I totally understand about the priority. https://github.com/llvm/llvm-project/pull/139584 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Revert "[lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes" (PR #145065)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/145065 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/144998 >From 22e8f644c3cd8856e1663bdf71aab4fa621f75bf Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 29 Jan 2025 12:15:35 + Subject: [PATCH 1/2] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer Starting with https://github.com/llvm/llvm-project/pull/124790, Clang emits `DW_AT_object_pointer` encoded as integer constants rather than DIE references. This patch accounts for this. --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 47 +++-- .../x86/explicit-member-function-quals.cpp| 21 +- .../DWARF/DWARFASTParserClangTests.cpp| 196 ++ 3 files changed, 244 insertions(+), 20 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 4f79c8aa3f811..7d699434ca3c8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -174,23 +174,46 @@ DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram, if (!decl_ctx_die.IsStructUnionOrClass()) return {}; - if (DWARFDIE object_parameter = - subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer)) -return object_parameter; + // The DW_AT_object_pointer may be either encoded as a reference to a DIE, + // in which case that's the object parameter we want. Or it can be a constant + // index of the parameter. + std::optional object_pointer_index; + DWARFFormValue form_value; + if (subprogram.GetDIE()->GetAttributeValue( + subprogram.GetCU(), DW_AT_object_pointer, form_value, + /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) { +if (auto ref = form_value.Reference()) + return ref; + +object_pointer_index = form_value.Unsigned(); + } + + // Try to find the DW_TAG_formal_parameter via object_pointer_index. + DWARFDIE object_pointer; + size_t param_index = 0; + for (const auto &child : subprogram.children()) { +if (child.Tag() != DW_TAG_formal_parameter) + continue; - // If no DW_AT_object_pointer was specified, assume the implicit object - // parameter is the first parameter to the function, is called "this" and is - // artificial (which is what most compilers would generate). - auto children = subprogram.children(); - auto it = llvm::find_if(children, [](const DWARFDIE &child) { -return child.Tag() == DW_TAG_formal_parameter; - }); +if (param_index == object_pointer_index.value_or(0)) + object_pointer = child; + +++param_index; + } - if (it == children.end()) + // No formal parameter found for object pointer index. + // Nothing to be done. + if (!object_pointer) return {}; - DWARFDIE object_pointer = *it; + // We found the object pointer encoded via DW_AT_object_pointer. + // No need for the remaining heuristics. + if (object_pointer_index) +return object_pointer; + // If no DW_AT_object_pointer was specified, assume the implicit object + // parameter is the first parameter to the function, is called "this" and is + // artificial (which is what most compilers would generate). if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) return {}; diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp index 33001db69f83e..f89f0f4a4f0bf 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp @@ -1,4 +1,9 @@ // XFAIL: * +// +// FIXME: Explicit object parameter is not shown in +// type lookup output. This is because we don't attach +// valid source locations to decls in the DWARF AST, +// so the ParmVarDecl::isExplicitObjectParameter fails. // Tests that we correctly deduce the CV-quals and storage // class of explicit object member functions. @@ -8,15 +13,15 @@ // // CHECK: (lldb) type lookup Foo // CHECK-NEXT: struct Foo { -// CHECK-NEXT: void Method(Foo); -// CHECK-NEXT: void cMethod(const Foo &) const; -// CHECK-NEXT: void vMethod(volatile Foo &) volatile; -// CHECK-NEXT: void cvMethod(const volatile Foo &) const volatile; +// CHECK-NEXT: void Method(this Foo); +// CHECK-NEXT: void cMethod(this const Foo &) const; +// CHECK-NEXT: void vMethod(this volatile Foo &) volatile; +// CHECK-NEXT: void cvMethod(this const volatile Foo &) const volatile; // CHECK-NEXT: } struct Foo { - void Method(this Foo) {} - void cMethod(this Foo const &) {} - void vMethod(this Foo volatile &) {} - void cvMethod(this Foo const volatile &) {} + [[gnu::always_inline]] void Method(this Foo) {} + [[gnu::always_inline]] void cMethod(this Foo const &) {} + [[gnu::always_inline]] void vMethod(this Foo volat
[Lldb-commits] [lldb] [LLDB] Add SI_USER and SI_KERNEL to Linux signals (PR #144800)
DavidSpickett wrote: Depending on the user's knowledge of / interpretation of how signals work, I don't think "sent by kernel" is enough for them to find their specific problem. Asking my nearest totally accurate AI model: > Yes, when an application receives a SIGILL (illegal instruction) signal, it > is sent by the kernel. And you can argue this is just the implementation of signals, not the way applications are supposed to think about it, but I think it's one a lot of people would subscribe to. What you're saying here is that the cause of the generation of the signal (by whomever generates it), was located in a certain place. So the place that tried to execute the illegal instruction, not the place that wrapped up that exception data into a signal. It's crude but maybe just include SI_KERNEL in there? "sent by kernel (SI_KERNEL)". Then we don't have to explain the meaning of SI_KERNEL but I the user do have something I can look up and read about it. And if they do have a kernel side problem, doing some reading is what they'll need to do anyway. https://github.com/llvm/llvm-project/pull/144800 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb/cmake] Plugin layering enforcement mechanism (PR #144543)
medismailben wrote: Cool stuff! https://github.com/llvm/llvm-project/pull/144543 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 9524bfb - [lldb] Add Model Context Protocol (MCP) support to LLDB (#143628)
Author: Jonas Devlieghere Date: 2025-06-20T10:48:04-05:00 New Revision: 9524bfb27020d31b9474f595b7c0e5d2e1ac65f5 URL: https://github.com/llvm/llvm-project/commit/9524bfb27020d31b9474f595b7c0e5d2e1ac65f5 DIFF: https://github.com/llvm/llvm-project/commit/9524bfb27020d31b9474f595b7c0e5d2e1ac65f5.diff LOG: [lldb] Add Model Context Protocol (MCP) support to LLDB (#143628) This PR adds an MCP (Model Context Protocol ) server to LLDB. For motivation and background, please refer to the corresponding RFC: https://discourse.llvm.org/t/rfc-adding-mcp-support-to-lldb/86798 I implemented this as a new kind of plugin. The idea is that we could support multiple protocol servers (e.g. if we want to support DAP from within LLDB). This also introduces a corresponding top-level command (`protocol-server`) with two subcommands to `start` and `stop` the server. ``` (lldb) protocol-server start MCP tcp://localhost:1234 MCP server started with connection listeners: connection://[::1]:1234, connection://[127.0.0.1]:1234 ``` The MCP sever supports one tool (`lldb_command`) which executes a command, but can easily be extended with more commands. Added: lldb/include/lldb/Core/ProtocolServer.h lldb/source/Commands/CommandObjectProtocolServer.cpp lldb/source/Commands/CommandObjectProtocolServer.h lldb/source/Core/ProtocolServer.cpp lldb/source/Plugins/Protocol/CMakeLists.txt lldb/source/Plugins/Protocol/MCP/CMakeLists.txt lldb/source/Plugins/Protocol/MCP/MCPError.cpp lldb/source/Plugins/Protocol/MCP/MCPError.h lldb/source/Plugins/Protocol/MCP/Protocol.cpp lldb/source/Plugins/Protocol/MCP/Protocol.h lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.h lldb/source/Plugins/Protocol/MCP/Tool.cpp lldb/source/Plugins/Protocol/MCP/Tool.h lldb/unittests/Protocol/CMakeLists.txt lldb/unittests/Protocol/ProtocolMCPServerTest.cpp lldb/unittests/Protocol/ProtocolMCPTest.cpp Modified: lldb/cmake/modules/LLDBConfig.cmake lldb/include/lldb/Core/Debugger.h lldb/include/lldb/Core/PluginManager.h lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h lldb/include/lldb/lldb-enumerations.h lldb/include/lldb/lldb-forward.h lldb/include/lldb/lldb-private-interfaces.h lldb/source/Commands/CMakeLists.txt lldb/source/Core/CMakeLists.txt lldb/source/Core/Debugger.cpp lldb/source/Core/PluginManager.cpp lldb/source/Interpreter/CommandInterpreter.cpp lldb/source/Plugins/CMakeLists.txt lldb/unittests/CMakeLists.txt lldb/unittests/DAP/ProtocolTypesTest.cpp lldb/unittests/TestingSupport/TestUtilities.h Removed: diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 37b823feb584b..8c30b6e09d2c7 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -67,6 +67,7 @@ add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable libfbsdvmcore support in option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON) option(LLDB_BUILD_FRAMEWORK "Build LLDB.framework (Darwin only)" OFF) +option(LLDB_ENABLE_PROTOCOL_SERVERS "Enable protocol servers (e.g. MCP) in LLDB" ON) option(LLDB_NO_INSTALL_DEFAULT_RPATH "Disable default RPATH settings in binaries" OFF) option(LLDB_USE_SYSTEM_DEBUGSERVER "Use the system's debugserver for testing (Darwin only)." OFF) option(LLDB_SKIP_STRIP "Whether to skip stripping of binaries when installing lldb." OFF) diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 2087ef2a11562..9f82466a83417 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -602,6 +602,10 @@ class Debugger : public std::enable_shared_from_this, void FlushProcessOutput(Process &process, bool flush_stdout, bool flush_stderr); + void AddProtocolServer(lldb::ProtocolServerSP protocol_server_sp); + void RemoveProtocolServer(lldb::ProtocolServerSP protocol_server_sp); + lldb::ProtocolServerSP GetProtocolServer(llvm::StringRef protocol) const; + SourceManager::SourceFileCache &GetSourceFileCache() { return m_source_file_cache; } @@ -772,6 +776,8 @@ class Debugger : public std::enable_shared_from_this, mutable std::mutex m_progress_reports_mutex; /// @} + llvm::SmallVector m_protocol_servers; + std::mutex m_destroy_callback_mutex; lldb::callback_token_t m_destroy_callback_next_token = 0; struct DestroyCallbackInfo { diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index 1d7c976f3c382..d1af25988e50f 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -321,6 +321,17 @@ class PluginManager { static void AutoCompleteProcessName(llvm::StringRef partial_name,
[Lldb-commits] [lldb] [lldb][AArch64] Add HWCAP3 to register field detection (PR #145029)
https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/145029 >From ba8fcf4ef14e25b8a628b994988d6a67bdbea7df Mon Sep 17 00:00:00 2001 From: David Spickett Date: Thu, 19 Jun 2025 10:43:48 + Subject: [PATCH] [lldb][AArch64] Add HWCAP3 to register field detection This will be used to detect the presence of Arm's new Memory Tagging store only checking feature. This commit just adds the plubming to get that value into the detection function. FreeBSD has not allocated a number for HWCAP3 and already has AT_ARGV defined as 29. So instead of attempting to read from FreeBSD processes, I've explictly passed nullopt. We don't want to be reading some other entry accidentally. If/when FreeBSD adds HWCAP3 we can handle it like we do for AUXV_FREEBSD_AT_HWCAP. No extra tests here, those will be coming with the next change for MTE support. --- .../NativeRegisterContextFreeBSD_arm64.cpp| 3 +- .../NativeRegisterContextLinux_arm64.cpp | 5 ++- .../Plugins/Process/Utility/AuxVector.cpp | 1 + .../Plugins/Process/Utility/AuxVector.h | 1 + .../Utility/RegisterFlagsDetector_arm64.cpp | 36 +-- .../Utility/RegisterFlagsDetector_arm64.h | 25 - .../RegisterContextPOSIXCore_arm64.cpp| 13 --- 7 files changed, 59 insertions(+), 25 deletions(-) diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp index 7adc00622ec2d..d21dac221aa22 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp @@ -44,7 +44,8 @@ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( NativeProcessFreeBSD &process = native_thread.GetProcess(); g_register_flags_detector.DetectFields( process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0), -process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0)); +process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0), +/*hwcap3=*/0); } return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread); diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index 884c7d4b9e359..b1c7421bef8d5 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -162,10 +162,13 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS); +std::optional auxv_at_hwcap3 = +process.GetAuxValue(AuxVector::AUXV_AT_HWCAP3); std::lock_guard lock(g_register_flags_detector_mutex); if (!g_register_flags_detector.HasDetected()) g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0), - auxv_at_hwcap2.value_or(0)); + auxv_at_hwcap2.value_or(0), + auxv_at_hwcap3.value_or(0)); auto register_info_up = std::make_unique(target_arch, opt_regsets); diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/lldb/source/Plugins/Process/Utility/AuxVector.cpp index f495ffb1924e7..50500a8593e1d 100644 --- a/lldb/source/Plugins/Process/Utility/AuxVector.cpp +++ b/lldb/source/Plugins/Process/Utility/AuxVector.cpp @@ -84,6 +84,7 @@ const char *AuxVector::GetEntryName(EntryType type) const { case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break; case ENTRY_NAME(AUXV_AT_RANDOM); break; case ENTRY_NAME(AUXV_AT_HWCAP2); break; +case ENTRY_NAME(AUXV_AT_HWCAP3); break; case ENTRY_NAME(AUXV_AT_EXECFN); break; case ENTRY_NAME(AUXV_AT_SYSINFO);break; case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break; diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.h b/lldb/source/Plugins/Process/Utility/AuxVector.h index 2670b34f6b0af..7733e0ffc6832 100644 --- a/lldb/source/Plugins/Process/Utility/AuxVector.h +++ b/lldb/source/Plugins/Process/Utility/AuxVector.h @@ -57,6 +57,7 @@ class AuxVector { AUXV_AT_BASE_PLATFORM = 24, ///< String identifying real platforms. AUXV_AT_RANDOM = 25,///< Address of 16 random bytes. AUXV_AT_HWCAP2 = 26,///< Extension of AT_HWCAP. +AUXV_AT_HWCAP3 = 29,///< Extension of AT_HWCAP. AUXV_AT_EXECFN = 31,///< Filename of executable. AUXV_AT_SYSINFO = 32, ///< Pointer to the global system page used for system /// calls and other nice things. diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp index 042940b7dff6e..
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
https://github.com/JDevlieghere closed https://github.com/llvm/llvm-project/pull/143628 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -32,6 +34,37 @@ class RegisterValue; class Stream; class Target; class UnwindPlan; +class EmulateInstruction; + +using BreakpointLocations = std::vector; + +class SingleStepBreakpointLocationsPredictor { +public: + SingleStepBreakpointLocationsPredictor( + std::unique_ptr emulator_up) + : m_emulator_up{std::move(emulator_up)} {} + + virtual BreakpointLocations GetBreakpointLocations(Status &status); + + virtual llvm::Expected GetBreakpointSize(lldb::addr_t bp_addr) { +return 4; DavidSpickett wrote: `[[maybe_unused]] lldb::addr_t bp_addr` https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (PR #127505)
@@ -1792,4 +1778,127 @@ bool EmulateInstructionRISCV::SupportsThisArch(const ArchSpec &arch) { return arch.GetTriple().isRISCV(); } +BreakpointLocations +RISCVSingleStepBreakpointLocationsPredictor::GetBreakpointLocations( +Status &status) { + EmulateInstructionRISCV *riscv_emulator = + static_cast(m_emulator_up.get()); + + auto pc = riscv_emulator->ReadPC(); + if (!pc) { +status = Status("Can't read PC"); +return {}; + } + + auto inst = riscv_emulator->ReadInstructionAt(*pc); + if (!inst) { +// Can't read instruction. Try default handler. +return SingleStepBreakpointLocationsPredictor::GetBreakpointLocations( +status); + } + + if (FoundLoadReserve(inst->decoded)) +return HandleAtomicSequence(*pc, status); + + if (FoundStoreConditional(inst->decoded)) { +// Ill-formed atomic sequence (SC doesn't have corresponding LR +// instruction). Consider SC instruction like a non-atomic store and set a +// breakpoint at the next instruction. +Log *log = GetLog(LLDBLog::Unwind); +LLDB_LOGF(log, + "RISCVSingleStepBreakpointLocationsPredictor::%s: can't find " + "corresponding load reserve insturuction", + __FUNCTION__); +return {*pc + inst->is_rvc ? 2u : 4u}; + } + + return SingleStepBreakpointLocationsPredictor::GetBreakpointLocations(status); +} + +llvm::Expected +RISCVSingleStepBreakpointLocationsPredictor::GetBreakpointSize( +lldb::addr_t bp_addr) { + EmulateInstructionRISCV *riscv_emulator = + static_cast(m_emulator_up.get()); + + if (auto inst = riscv_emulator->ReadInstructionAt(bp_addr); inst) +return inst->is_rvc ? 2 : 4; + + // Try last instruction size. + if (auto last_instr_size = riscv_emulator->GetLastInstrSize(); + last_instr_size) +return *last_instr_size; + + // Just place non-compressed software trap. + return 4; +} + +BreakpointLocations +RISCVSingleStepBreakpointLocationsPredictor::HandleAtomicSequence( +lldb::addr_t pc, Status &error) { + EmulateInstructionRISCV *riscv_emulator = + static_cast(m_emulator_up.get()); + + // Handle instructions between LR and SC. According to unprivilleged + // RISC-V ISA there can be at most 16 instructions in the sequence. + + lldb::addr_t entry_pc = pc; // LR instruction address + pc += 4;// add LR_W, LR_D instruction size + + size_t atomic_length = 0; + std::optional inst; + std::vector bp_addrs; + do { +inst = riscv_emulator->ReadInstructionAt(pc); +if (!inst) { + error = Status("Can't read instruction"); + return {}; +} + +if (B *branch = std::get_if(&inst->decoded)) + bp_addrs.push_back(pc + SignExt(branch->imm)); + +unsigned addent = inst->is_rvc ? 2 : 4; +pc += addent; +atomic_length += addent; + } while ((atomic_length < s_max_atomic_sequence_length) && + !FoundStoreConditional(inst->decoded)); + + if (atomic_length >= s_max_atomic_sequence_length) { +// Ill-formed atomic sequence (LR doesn't have corresponding SC +// instruction). In this case consider LR like a non-atomic load instruction +// and set a breakpoint at the next after LR instruction. +Log *log = GetLog(LLDBLog::Unwind); +LLDB_LOGF(log, + "RISCVSingleStepBreakpointLocationsPredictor::%s: can't find " + "corresponding store conditional insturuction", + __FUNCTION__); +return {entry_pc + 4}; DavidSpickett wrote: Asking this again because I think GitHub hid the comment, is +4 safe here? Could it be +2 if the instruction is compressed, or do you already know that it won't be? https://github.com/llvm/llvm-project/pull/127505 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [NFC][DebugInfo][DWARF] Create new low-level dwarf library (PR #145081)
https://github.com/Sterling-Augustine created https://github.com/llvm/llvm-project/pull/145081 This is the culmination of a series of changes described in [1]. Although somewhat large by line count, it is almost entirely mechanical, creating a new library in DebugInfo/DWARF/LowLevel. This new library has very minimal dependencies, allowing it to be used from more places than the normal DebugInfo/DWARF library--in particular from MC. I am happy to put it in another location, or to structure it differently if that makes sense. Some have suggested in BinaryFormat, but it is not a great fit there. But if that makes more sense to the reviewers, I can do that. Another possibility would be to use pass-through headers to allow clients who don't care to depend only on DebugInfo/DWARF. This would be a much less invasive change, and perhaps easier for clients. But also a system that hides details. Either way, I'm open. 1. https://discourse.llvm.org/t/rfc-debuginfo-dwarf-refactor-into-to-lower-and-higher-level-libraries/86665/2 >From bb6aaad973284f0f378301b576f55717a052675d Mon Sep 17 00:00:00 2001 From: Sterling Augustine Date: Wed, 18 Jun 2025 10:35:05 -0700 Subject: [PATCH 1/4] Split Dwarf Expression printing into separate files --- lldb/source/Expression/DWARFExpression.cpp| 3 +- lldb/source/Symbol/UnwindPlan.cpp | 4 +- .../Symbol/PostfixExpressionTest.cpp | 3 +- .../PdbFPOProgramToDWARFExpressionTests.cpp | 3 +- .../llvm/DebugInfo/DWARF/DWARFExpression.h| 58 .../DebugInfo/DWARF/DWARFExpressionPrinter.h | 66 llvm/lib/DebugInfo/DWARF/CMakeLists.txt | 1 + llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp | 4 +- llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp | 3 +- llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp| 3 +- llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 3 +- llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp | 284 .../DWARF/DWARFExpressionPrinter.cpp | 310 ++ .../LogicalView/Readers/LVDWARFReader.cpp | 3 +- llvm/tools/llvm-objdump/SourcePrinter.cpp | 3 +- .../DWARFExpressionCompactPrinterTest.cpp | 3 +- 16 files changed, 399 insertions(+), 355 deletions(-) create mode 100644 llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h create mode 100644 llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 661324338e801..58f1b95b57041 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -37,6 +37,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "llvm/DebugInfo/DWARF/DWARFExpression.h" +#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h" using namespace lldb; using namespace lldb_private; @@ -81,7 +82,7 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level, llvm::DIDumpOptions DumpOpts; DumpOpts.GetNameForDWARFReg = GetRegName; llvm::DWARFExpression E(m_data.GetAsLLVM(), m_data.GetAddressByteSize()); - llvm::DWARFExpressionPrinter::print(&E, s->AsRawOstream(), DumpOpts, nullptr); + llvm::printDwarfExpression(&E, s->AsRawOstream(), DumpOpts, nullptr); } RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; } diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp index e9ac6b6cde295..eda57bd29b859 100644 --- a/lldb/source/Symbol/UnwindPlan.cpp +++ b/lldb/source/Symbol/UnwindPlan.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFExpression.h" +#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h" #include using namespace lldb; @@ -89,8 +90,7 @@ static void DumpDWARFExpr(Stream &s, llvm::ArrayRef expr, Thread *threa order_and_width->second); llvm::DWARFExpression E(data, order_and_width->second, llvm::dwarf::DWARF32); -llvm::DWARFExpressionPrinter::print(&E, s.AsRawOstream(), -llvm::DIDumpOptions(), nullptr); +printDwarfExpression(&E, s.AsRawOstream(), llvm::DIDumpOptions(), nullptr); } else s.PutCString("dwarf-expr"); } diff --git a/lldb/unittests/Symbol/PostfixExpressionTest.cpp b/lldb/unittests/Symbol/PostfixExpressionTest.cpp index 1e437da5133d9..23c24e67fb9c9 100644 --- a/lldb/unittests/Symbol/PostfixExpressionTest.cpp +++ b/lldb/unittests/Symbol/PostfixExpressionTest.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFExpression.h" +#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" #include "gmock/gmock.h" @@ -160,7 +161,7 @@ static std::string ParseAndGenerateDWARF(llvm::StringR
[Lldb-commits] [lldb] 749e4a5 - [lldb] Fix ASCII art in CommandObjectProtocolServer (NFC)
Author: Jonas Devlieghere Date: 2025-06-20T10:54:00-05:00 New Revision: 749e4a53d252e23e870d4a1638ff9d846af58e7f URL: https://github.com/llvm/llvm-project/commit/749e4a53d252e23e870d4a1638ff9d846af58e7f DIFF: https://github.com/llvm/llvm-project/commit/749e4a53d252e23e870d4a1638ff9d846af58e7f.diff LOG: [lldb] Fix ASCII art in CommandObjectProtocolServer (NFC) Added: Modified: lldb/source/Commands/CommandObjectProtocolServer.cpp lldb/source/Commands/CommandObjectProtocolServer.h Removed: diff --git a/lldb/source/Commands/CommandObjectProtocolServer.cpp b/lldb/source/Commands/CommandObjectProtocolServer.cpp index 420fc5fdddadb..115754769f3e3 100644 --- a/lldb/source/Commands/CommandObjectProtocolServer.cpp +++ b/lldb/source/Commands/CommandObjectProtocolServer.cpp @@ -1,5 +1,4 @@ -//===-- CommandObjectProtocolServer.cpp -//--===// +//===-- CommandObjectProtocolServer.cpp ---===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Commands/CommandObjectProtocolServer.h b/lldb/source/Commands/CommandObjectProtocolServer.h index 3591216b014cb..791b3a78aaf02 100644 --- a/lldb/source/Commands/CommandObjectProtocolServer.h +++ b/lldb/source/Commands/CommandObjectProtocolServer.h @@ -1,5 +1,4 @@ -//===-- CommandObjectProtocolServer.h -//===// +//===-- CommandObjectProtocolServer.h -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AArch64] Add HWCAP3 to register field detection (PR #145029)
DavidSpickett wrote: HWCAP3 has been present for a while - https://elixir.bootlin.com/linux/v6.16-rc2/source/include/uapi/linux/auxvec.h#L35 The MTE patches are still in review (https://lore.kernel.org/linux-arm-kernel/20250611150417.44850-5-yeoreum@arm.com/) but are unlikely to change drastically. So my plan is to get support code reviewed while we wait, and I'll land it once the kernel side is approved. https://github.com/llvm/llvm-project/pull/145029 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AArch64] Add HWCAP3 to register field detection (PR #145029)
https://github.com/DavidSpickett edited https://github.com/llvm/llvm-project/pull/145029 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][darwin] force BuiltinHeadersInSystemModules to be always false (PR #144913)
charles-zablit wrote: I only get one test failures when running the `check-lldb-api` target: `commands/platform/sdk/TestPlatformSDK.py` but it also happens on the main branch, so there's probably something wrong with the SDK configuration on my system. https://github.com/llvm/llvm-project/pull/144913 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][target] Add progress report for wait-attaching to process (PR #144768)
labath wrote: Well.. IIUC, this test tries to attach to a process called "a.out" -- and hopes that the process doesn't appear. If you run the test suite in parallel, you'll have any number of processes like that going around all the time. Not only will this test fail, but it will mess up the state of a random other test. I guess you could just wait for a sufficiently unique process name... https://github.com/llvm/llvm-project/pull/144768 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 20d57e7 - [lldb][AIX] Added base file for AIX Register Context (#144645)
Author: Hemang Gadhavi Date: 2025-06-20T20:18:39+05:30 New Revision: 20d57e77f6709ef32791391bc064d3ed5663272a URL: https://github.com/llvm/llvm-project/commit/20d57e77f6709ef32791391bc064d3ed5663272a DIFF: https://github.com/llvm/llvm-project/commit/20d57e77f6709ef32791391bc064d3ed5663272a.diff LOG: [lldb][AIX] Added base file for AIX Register Context (#144645) This PR is in reference to porting LLDB on AIX. Link to discussions on llvm discourse and github: 1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640 2. https://github.com/llvm/llvm-project/issues/101657 The complete changes for porting are present in this draft PR: https://github.com/llvm/llvm-project/pull/102601 - Added skeleton for Registercontext file for AIX. (Later we will add implementation respectively) Added: lldb/source/Plugins/Process/AIX/NativeRegisterContextAIX.cpp lldb/source/Plugins/Process/AIX/NativeRegisterContextAIX.h Modified: lldb/source/Plugins/Process/AIX/CMakeLists.txt Removed: diff --git a/lldb/source/Plugins/Process/AIX/CMakeLists.txt b/lldb/source/Plugins/Process/AIX/CMakeLists.txt index 6b3151edbd1ef..3a6d9ec118e60 100644 --- a/lldb/source/Plugins/Process/AIX/CMakeLists.txt +++ b/lldb/source/Plugins/Process/AIX/CMakeLists.txt @@ -1,6 +1,7 @@ add_lldb_library(lldbPluginProcessAIX NativeProcessAIX.cpp NativeThreadAIX.cpp + NativeRegisterContextAIX.cpp LINK_COMPONENTS Support diff --git a/lldb/source/Plugins/Process/AIX/NativeRegisterContextAIX.cpp b/lldb/source/Plugins/Process/AIX/NativeRegisterContextAIX.cpp new file mode 100644 index 0..e44cd7b5a30f5 --- /dev/null +++ b/lldb/source/Plugins/Process/AIX/NativeRegisterContextAIX.cpp @@ -0,0 +1,54 @@ +//=== NativeRegisterContextAIX.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 "NativeRegisterContextAIX.h" +#include "Plugins/Process/AIX/NativeProcessAIX.h" + +using namespace lldb_private; +using namespace lldb_private::process_aix; + +lldb::ByteOrder NativeRegisterContextAIX::GetByteOrder() const { + return lldb::eByteOrderInvalid; +} + +Status NativeRegisterContextAIX::ReadRegisterRaw(uint32_t reg_index, + RegisterValue ®_value) { + return Status("unimplemented"); +} + +Status +NativeRegisterContextAIX::WriteRegisterRaw(uint32_t reg_index, + const RegisterValue ®_value) { + return Status("unimplemented"); +} + +Status NativeRegisterContextAIX::ReadGPR() { return Status("unimplemented"); } + +Status NativeRegisterContextAIX::WriteGPR() { return Status("unimplemented"); } + +Status NativeRegisterContextAIX::ReadFPR() { return Status("unimplemented"); } + +Status NativeRegisterContextAIX::WriteFPR() { return Status("unimplemented"); } + +Status NativeRegisterContextAIX::ReadVMX() { return Status("unimplemented"); } + +Status NativeRegisterContextAIX::WriteVMX() { return Status("unimplemented"); } + +Status NativeRegisterContextAIX::ReadVSX() { return Status("unimplemented"); } + +Status NativeRegisterContextAIX::WriteVSX() { return Status("unimplemented"); } + +Status NativeRegisterContextAIX::ReadRegisterSet(void *buf, size_t buf_size, + unsigned int regset) { + return Status("unimplemented"); +} + +Status NativeRegisterContextAIX::WriteRegisterSet(void *buf, size_t buf_size, + unsigned int regset) { + return Status("unimplemented"); +} diff --git a/lldb/source/Plugins/Process/AIX/NativeRegisterContextAIX.h b/lldb/source/Plugins/Process/AIX/NativeRegisterContextAIX.h new file mode 100644 index 0..e78483a7670f6 --- /dev/null +++ b/lldb/source/Plugins/Process/AIX/NativeRegisterContextAIX.h @@ -0,0 +1,62 @@ +//=== NativeRegisterContextAIX.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_SOURCE_PLUGINS_PROCESS_AIX_NATIVEREGISTERCONTEXTAIX_H +#define LLDB_SOURCE_PLUGINS_PROCESS_AIX_NATIVEREGISTERCONTEXTAIX_H + +#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h" + +namespace lldb_private::process_aix { + +class NativeRegisterContextAIX +: public virtual NativeRegisterContextRegisterInfo { +protected: + NativeRegisterContextAIX(NativeThreadProtocol &thread) + : NativeRegisterContextRegis
[Lldb-commits] [lldb] 65cb3bc - [Clang][PowerPC] Add __dmr1024 type and DMF integer calculation builtins (#142480)
Author: Maryam Moghadas Date: 2025-06-20T13:03:14-04:00 New Revision: 65cb3bcf327da8f9740e56897bc9954364e59eb6 URL: https://github.com/llvm/llvm-project/commit/65cb3bcf327da8f9740e56897bc9954364e59eb6 DIFF: https://github.com/llvm/llvm-project/commit/65cb3bcf327da8f9740e56897bc9954364e59eb6.diff LOG: [Clang][PowerPC] Add __dmr1024 type and DMF integer calculation builtins (#142480) Define the __dmr1024 type used to manipulate the new DMR registers introduced by the Dense Math Facility (DMF) on PowerPC, and add six Clang builtins that correspond to the integer outer-product accumulate to ACC PowerPC instructions: * __builtin_mma_dmxvi8gerx4 * __builtin_mma_pmdmxvi8gerx4 * __builtin_mma_dmxvi8gerx4pp * __builtin_mma_pmdmxvi8gerx4pp * __builtin_mma_dmxvi8gerx4spp * __builtin_mma_pmdmxvi8gerx4spp. Added: clang/test/CodeGen/PowerPC/builtins-ppc-dmf.c clang/test/CodeGen/PowerPC/ppc-dmf-paired-vec-memops-builtin-err.c clang/test/CodeGen/PowerPC/ppc-dmf-types.c clang/test/CodeGen/PowerPC/ppc-future-mma-builtin-err.c clang/test/Sema/ppc-dmf-types.c Modified: clang/include/clang/Basic/BuiltinsPPC.def clang/include/clang/Basic/PPCTypes.def clang/lib/AST/ASTContext.cpp clang/test/AST/ast-dump-ppc-types.c clang/test/CodeGenCXX/ppc-mangle-mma-types.cpp lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp Removed: diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index bb7d54bbb793e..099500754a0e0 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -1134,6 +1134,18 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2np, "vW512*VVi15i15i3", true, "mma,paired-vector-memops") UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true, "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_dmxvi8gerx4, "vW1024*W256V", false, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_pmdmxvi8gerx4, "vW1024*W256Vi255i15i15", false, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_dmxvi8gerx4pp, "vW1024*W256V", true, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_pmdmxvi8gerx4pp, "vW1024*W256Vi255i15i15", true, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_dmxvi8gerx4spp, "vW1024*W256V", true, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_pmdmxvi8gerx4spp, "vW1024*W256Vi255i15i15", true, + "mma,paired-vector-memops") // FIXME: Obviously incomplete. diff --git a/clang/include/clang/Basic/PPCTypes.def b/clang/include/clang/Basic/PPCTypes.def index 9e2cb2aedc9fc..fc4155ca98b2d 100644 --- a/clang/include/clang/Basic/PPCTypes.def +++ b/clang/include/clang/Basic/PPCTypes.def @@ -30,6 +30,7 @@ #endif +PPC_VECTOR_MMA_TYPE(__dmr1024, DMR1024, 1024) PPC_VECTOR_MMA_TYPE(__vector_quad, VectorQuad, 512) PPC_VECTOR_VSX_TYPE(__vector_pair, VectorPair, 256) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 74be2871f270c..02d6570d0ea0f 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3522,6 +3522,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, case BuiltinType::BFloat16: case BuiltinType::VectorQuad: case BuiltinType::VectorPair: +case BuiltinType::DMR1024: OS << "?"; return; diff --git a/clang/test/AST/ast-dump-ppc-types.c b/clang/test/AST/ast-dump-ppc-types.c index 26ae5441f20d7..1c860c268e0ec 100644 --- a/clang/test/AST/ast-dump-ppc-types.c +++ b/clang/test/AST/ast-dump-ppc-types.c @@ -1,9 +1,11 @@ +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu future \ +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr10 \ -// RUN: -ast-dump -ast-dump-filter __vector %s | FileCheck %s +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr9 \ -// RUN: -ast-dump -ast-dump-filter __vector %s | FileCheck %s +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr8 \ -// RUN: -ast-dump -ast-dump-filter __vector %s | FileCheck %s +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck %s \ // RUN: --check-prefix=CHECK-X86_64 // RUN: %clang_cc1 -triple arm-unknown-unknown -ast-dump %s | FileCheck %s \ @@ -15,16 +17,21 @@ // are correctly defined. We also added checks on a couple of other targets to // ensure the types are target-dependent. +// CHECK: TypedefDecl {{.*}} implicit __dmr1024 '__dmr1024' +// CHECK: `-BuiltinType {{.*}} '__dmr1024' // CHECK:
[Lldb-commits] [lldb] [lldb] Fix SBMemoryRegionInfoListExtensions iter to yield unique refe… (PR #144815)
https://github.com/zyn-li updated https://github.com/llvm/llvm-project/pull/144815 >From 2054114501b9de9ab54d22044800607fd12d Mon Sep 17 00:00:00 2001 From: Zhiyuan Li Date: Wed, 18 Jun 2025 16:49:12 -0700 Subject: [PATCH] [lldb] Fix SBMemoryRegionInfoListExtensions iter to yield unique references --- .../SBMemoryRegionInfoListExtensions.i| 2 +- .../find_in_memory/TestFindInMemory.py| 23 +-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lldb/bindings/interface/SBMemoryRegionInfoListExtensions.i b/lldb/bindings/interface/SBMemoryRegionInfoListExtensions.i index 29c0179c0ffe3..f565f45880119 100644 --- a/lldb/bindings/interface/SBMemoryRegionInfoListExtensions.i +++ b/lldb/bindings/interface/SBMemoryRegionInfoListExtensions.i @@ -9,8 +9,8 @@ '''Iterate over all the memory regions in a lldb.SBMemoryRegionInfoList object.''' import lldb size = self.GetSize() - region = lldb.SBMemoryRegionInfo() for i in range(size): +region = lldb.SBMemoryRegionInfo() self.GetMemoryRegionAtIndex(i, region) yield region %} diff --git a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py index 1ef37d2ec9898..d61fdb16e2a02 100644 --- a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py +++ b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py @@ -154,14 +154,33 @@ def test_find_in_memory_unaligned(self): self.assertEqual(addr, lldb.LLDB_INVALID_ADDRESS) def test_memory_info_list_iterable(self): -"""Make sure the SBMemoryRegionInfoList is iterable""" +"""Make sure the SBMemoryRegionInfoList is iterable and each yielded object is unique""" self.assertTrue(self.process, PROCESS_IS_VALID) self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) info_list = self.process.GetMemoryRegions() self.assertTrue(info_list.GetSize() > 0) + +collected_info = [] try: for info in info_list: -pass +collected_info.append(info) except Exception: self.fail("SBMemoryRegionInfoList is not iterable") + +for i in range(len(collected_info)): +region = lldb.SBMemoryRegionInfo() +info_list.GetMemoryRegionAtIndex(i, region) + +self.assertEqual( +collected_info[i], +region, +f"items {i}: iterator data should match index access data", +) + +if len(collected_info) >= 2: +self.assertNotEqual( +collected_info[0].GetRegionBase(), +collected_info[1].GetRegionBase(), +"Different items should have different base addresses", +) ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Explicitly use python for version fixup (PR #144217)
https://github.com/chelcassanova approved this pull request. LGTM! (For future reference, we should also do this when we run the framework fixup Python script) https://github.com/llvm/llvm-project/pull/144217 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits