[Lldb-commits] [lldb] [lldb] Move the generic MCP server code into Protocol/MCP (NFC) (PR #152396)
https://github.com/JDevlieghere closed https://github.com/llvm/llvm-project/pull/152396 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ARM] Port Arm Linux to use NativeRegisterContextDBReg (PR #152284)
@@ -0,0 +1,116 @@
+//===-- NativeRegisterContextDBReg_arm.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 "NativeRegisterContextDBReg_arm.h"
+
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+
+using namespace lldb_private;
+
+uint32_t NativeRegisterContextDBReg_arm::GetWatchpointSize(uint32_t wp_index) {
+ Log *log = GetLog(LLDBLog::Watchpoints);
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f) {
+ case 0x01:
+return 1;
+ case 0x03:
+return 2;
+ case 0x07:
+return 3;
+ case 0x0f:
+return 4;
+ default:
+return 0;
+ }
+}
+
+std::optional
+NativeRegisterContextDBReg_arm::AdjustBreakpoint(
+const BreakpointDetails &details) {
+ BreakpointDetails bd = details;
+ // Use size to get a hint of arm vs thumb modes.
+ switch (bd.size) {
+ case 2:
+bd.addr &= ~1;
+break;
+ case 4:
+bd.addr &= ~3;
+break;
+ default:
+return {};
+ }
+
+ return bd;
+}
+
+std::optional
+NativeRegisterContextDBReg_arm::AdjustWatchpoint(
+const WatchpointDetails &details) {
+ auto [size, addr] = details;
+
+ if (size == 0 || size > 4)
+return {};
+
+ // Check 4-byte alignment for hardware watchpoint target address. Below is a
+ // hack to recalculate address and size in order to make sure we can watch
+ // non 4-byte aligned addresses as well.
+ if (addr & 0x03) {
+uint8_t watch_mask = (addr & 0x03) + size;
+if (watch_mask > 0x04)
+ return {};
+else if (watch_mask <= 0x02)
+ size = 2;
+else
+ size = 4;
+
+addr = addr & (~0x03);
+ }
+
+ return WatchpointDetails{size, addr};
+}
+
+uint32_t NativeRegisterContextDBReg_arm::MakeBreakControlValue(size_t size) {
+ switch (size) {
+ case 2:
+return (0x3 << 5) | 7;
+ case 4:
+return (0xfu << 5) | 7;
+ default:
+// We assume that AdjustBreakpoint would have caught this earlier.
+llvm_unreachable("Invalid breakpoint size.");
+ }
+}
+
+uint32_t NativeRegisterContextDBReg_arm::MakeWatchControlValue(
+lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ uint32_t addr_word_offset = 0, byte_mask = 0;
+
+ // We can only watch up to four bytes that follow a 4 byte aligned address
+ // per watchpoint register pair, so make sure we can properly encode this.
+ addr_word_offset = addr % 4;
b10902118 wrote:
This is actually unneeded. `addr_word_offset` will always be 0 because there is
`addr = addr & (~0x03);` in `NativeRegisterContextDBReg_arm::AdjustWatchpoint`.
Previous `NativeRegisterContextLinux_arm::SetHardwareWatchpoint` made this
redundancy, which is clearer there.
https://github.com/llvm/llvm-project/pull/152284
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] Add network symbol optimization configuration options (PR #150777)
walter-erquinigo wrote: Yes, could you split this path into smaller ones? That's more standard for LLDB https://github.com/llvm/llvm-project/pull/150777 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 44aedac - [lldb] Move the generic MCP server code into Protocol/MCP (NFC) (#152396)
Author: Jonas Devlieghere
Date: 2025-08-07T09:01:28-07:00
New Revision: 44aedacb1b64b415fddfada39eb876602980ea72
URL:
https://github.com/llvm/llvm-project/commit/44aedacb1b64b415fddfada39eb876602980ea72
DIFF:
https://github.com/llvm/llvm-project/commit/44aedacb1b64b415fddfada39eb876602980ea72.diff
LOG: [lldb] Move the generic MCP server code into Protocol/MCP (NFC) (#152396)
This is a continuation of #152188, which started splitting up the MCP
implementation into a generic implementation in Protocol/MCP that will
be shared between LLDB and lldb-mcp.
For now I kept all the networking code in the MCP server plugin. Once
the changes to JSONTransport land, we might be able to move more of it
into the Protocol library.
Added:
lldb/include/lldb/Protocol/MCP/Server.h
lldb/source/Protocol/MCP/Server.cpp
Modified:
lldb/include/lldb/Protocol/MCP/Protocol.h
lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.h
lldb/source/Protocol/MCP/CMakeLists.txt
Removed:
diff --git a/lldb/include/lldb/Protocol/MCP/Protocol.h
b/lldb/include/lldb/Protocol/MCP/Protocol.h
index c43b06809bd3f..6448416eee08f 100644
--- a/lldb/include/lldb/Protocol/MCP/Protocol.h
+++ b/lldb/include/lldb/Protocol/MCP/Protocol.h
@@ -21,7 +21,7 @@
namespace lldb_protocol::mcp {
-static llvm::StringLiteral kVersion = "2024-11-05";
+static llvm::StringLiteral kProtocolVersion = "2024-11-05";
/// A request that expects a response.
struct Request {
diff --git a/lldb/include/lldb/Protocol/MCP/Server.h
b/lldb/include/lldb/Protocol/MCP/Server.h
new file mode 100644
index 0..2ac05880de86b
--- /dev/null
+++ b/lldb/include/lldb/Protocol/MCP/Server.h
@@ -0,0 +1,70 @@
+//===--===//
+//
+// 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_PROTOCOL_MCP_SERVER_H
+#define LLDB_PROTOCOL_MCP_SERVER_H
+
+#include "lldb/Protocol/MCP/Protocol.h"
+#include "lldb/Protocol/MCP/Resource.h"
+#include "lldb/Protocol/MCP/Tool.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Error.h"
+#include
+
+namespace lldb_protocol::mcp {
+
+class Server {
+public:
+ Server(std::string name, std::string version);
+ virtual ~Server() = default;
+
+ void AddTool(std::unique_ptr tool);
+ void AddResourceProvider(std::unique_ptr
resource_provider);
+
+protected:
+ virtual Capabilities GetCapabilities() = 0;
+
+ using RequestHandler =
+ std::function(const Request &)>;
+ using NotificationHandler = std::function;
+
+ void AddRequestHandlers();
+
+ void AddRequestHandler(llvm::StringRef method, RequestHandler handler);
+ void AddNotificationHandler(llvm::StringRef method,
+ NotificationHandler handler);
+
+ llvm::Expected> HandleData(llvm::StringRef data);
+
+ llvm::Expected Handle(Request request);
+ void Handle(Notification notification);
+
+ llvm::Expected InitializeHandler(const Request &);
+
+ llvm::Expected ToolsListHandler(const Request &);
+ llvm::Expected ToolsCallHandler(const Request &);
+
+ llvm::Expected ResourcesListHandler(const Request &);
+ llvm::Expected ResourcesReadHandler(const Request &);
+
+ std::mutex m_mutex;
+
+private:
+ const std::string m_name;
+ const std::string m_version;
+
+ llvm::StringMap> m_tools;
+ std::vector> m_resource_providers;
+
+ llvm::StringMap m_request_handlers;
+ llvm::StringMap m_notification_handlers;
+};
+
+} // namespace lldb_protocol::mcp
+
+#endif
diff --git a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
index c9fe474d45c49..c359663239dcc 100644
--- a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
+++ b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
@@ -27,25 +27,12 @@ using namespace llvm;
LLDB_PLUGIN_DEFINE(ProtocolServerMCP)
static constexpr size_t kChunkSize = 1024;
+static constexpr llvm::StringLiteral kName = "lldb-mcp";
+static constexpr llvm::StringLiteral kVersion = "0.1.0";
-ProtocolServerMCP::ProtocolServerMCP() : ProtocolServer() {
- AddRequestHandler("initialize",
-std::bind(&ProtocolServerMCP::InitializeHandler, this,
- std::placeholders::_1));
-
- AddRequestHandler("tools/list",
-std::bind(&ProtocolServerMCP::ToolsListHandler, this,
- std::placeholders::_1));
- AddRequestHandler("tools/call",
-std::bind(&ProtocolServerMCP::ToolsCallHandler, this,
- std::placeholders::_1));
-
- AddRequestHandler("resources/lis
[Lldb-commits] [lldb] [lldb] Fix race condition in Process::WaitForProcessToStop() (PR #144919)
athierry-oct wrote:
Thanks for your help!
I did a bit more digging : in `TestCallThatRestarts.py`, it seems the stop
event is sent by `EvaluateExpression()` to the primary listener because the
process is stopped by a signal (SIGCHLD). So, the execution of the thread plan
that runs during expression evaluation is interrupted, and we end up in the
following code:
Process.cpp
```c++
// If the process exited during the run of the thread plan, notify everyone.
if (event_to_broadcast_sp) {
if (log)
log->PutCString("Process::RunThreadPlan(): rebroadcasting event.");
BroadcastEvent(event_to_broadcast_sp);
}
```
Here's the relevant log:
```
python3 Process::RunThreadPlan(): execution interrupted:
0x7f3748007600 Event: broadcaster = 0x133665e8 (lldb.process), type =
0x0001 (state-changed), data = { process = 0x133665b0 (pid = 1200636),
state = stopped} <1 threads> <0x1251fc [ip 0x7f42dffa653b] signal SIGCHLD>
python3 Process::RunThreadPlan: ExecutionInterrupted - for plan:
0x1307b8d0 not discarding.
python3 0x1335E690
Broadcaster("lldb.process")::RestoreBroadcaster (about to pop
listener("lldb.process.listener.run-thread-plan")=0x1305F8D0)
python3 Process::RunThreadPlan(): rebroadcasting event.
python3 0x1335e690 Broadcaster("lldb.process")::BroadcastEvent
(event_sp = 0x7f3748007600 Event: broadcaster = 0x133665e8 (lldb.process), type
= 0x0001 (state-changed), data = { process = 0x133665b0 (pid = 1200636),
state = stopped}, unique=false) hijack = 0x
python3 0x1242a210 Listener('lldb.Debugger')::AddEvent (event_sp =
{0x7f3748007600})
python3 -- [UserExpression::Execute] Execution of expression completed
--
python3 == [UserExpression::Evaluate] Execution completed abnormally ==
```
IIUC LLDB broadcasts this stop event to the primary listener to let the user
(eg. the IDE) know that the process stopped during expression evaluation.
In light of this, do you still think `EvaluateExpression()` should consume the
stop event instead of rebroadcasting it to the primary listener? Or should the
test itself handle the event to clear the queue after `EvaluateExpression()`
but before calling `ResumeSynchronous()` ?
https://github.com/llvm/llvm-project/pull/144919
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Update JSONTransport to use MainLoop for reading. (PR #152367)
https://github.com/ashgti updated
https://github.com/llvm/llvm-project/pull/152367
>From 02417f51a23fbfd4d941b6f9b18e82fe8eb87566 Mon Sep 17 00:00:00 2001
From: John Harrison
Date: Tue, 5 Aug 2025 11:23:31 -0700
Subject: [PATCH] [lldb] Update JSONTransport to use MainLoop for reading.
Reapply "[lldb] Update JSONTransport to use MainLoop for reading." (#152155)
This reverts commit cd40281685f642ad879e33f3fda8d1faa136ebf4.
This also includes some updates to try to address the platforms with failing
tests.
I updated the JSONTransport and tests to use std::function instead of
llvm:unique_function. I think the tests were failing due to the unique_function
not being moved correctly in the loop on some platforms.
---
lldb/include/lldb/Host/JSONTransport.h| 113 +--
lldb/source/Host/common/JSONTransport.cpp | 167 --
lldb/test/API/tools/lldb-dap/io/TestDAP_io.py | 27 +-
lldb/tools/lldb-dap/DAP.cpp | 128
lldb/tools/lldb-dap/DAP.h | 7 +
lldb/tools/lldb-dap/Transport.h | 2 +-
lldb/unittests/DAP/DAPTest.cpp| 11 +-
lldb/unittests/DAP/TestBase.cpp | 26 +-
lldb/unittests/DAP/TestBase.h | 20 ++
lldb/unittests/Host/JSONTransportTest.cpp | 299 +-
.../ProtocolServer/ProtocolMCPServerTest.cpp | 131
11 files changed, 573 insertions(+), 358 deletions(-)
diff --git a/lldb/include/lldb/Host/JSONTransport.h
b/lldb/include/lldb/Host/JSONTransport.h
index 4087cdf2b42f7..98bce6e265356 100644
--- a/lldb/include/lldb/Host/JSONTransport.h
+++ b/lldb/include/lldb/Host/JSONTransport.h
@@ -13,13 +13,15 @@
#ifndef LLDB_HOST_JSONTRANSPORT_H
#define LLDB_HOST_JSONTRANSPORT_H
+#include "lldb/Host/MainLoopBase.h"
#include "lldb/lldb-forward.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/JSON.h"
-#include
+#include
#include
+#include
namespace lldb_private {
@@ -28,27 +30,33 @@ class TransportEOFError : public
llvm::ErrorInfo {
static char ID;
TransportEOFError() = default;
-
- void log(llvm::raw_ostream &OS) const override {
-OS << "transport end of file reached";
- }
+ void log(llvm::raw_ostream &OS) const override { OS << "transport EOF"; }
std::error_code convertToErrorCode() const override {
-return llvm::inconvertibleErrorCode();
+return std::make_error_code(std::errc::io_error);
}
};
-class TransportTimeoutError : public llvm::ErrorInfo {
+class TransportUnhandledContentsError
+: public llvm::ErrorInfo {
public:
static char ID;
- TransportTimeoutError() = default;
+ explicit TransportUnhandledContentsError(std::string unhandled_contents)
+ : m_unhandled_contents(unhandled_contents) {}
void log(llvm::raw_ostream &OS) const override {
-OS << "transport operation timed out";
+OS << "transport EOF with unhandled contents " << m_unhandled_contents;
}
std::error_code convertToErrorCode() const override {
-return std::make_error_code(std::errc::timed_out);
+return std::make_error_code(std::errc::bad_message);
}
+
+ const std::string &getUnhandledContents() const {
+return m_unhandled_contents;
+ }
+
+private:
+ std::string m_unhandled_contents;
};
class TransportInvalidError : public llvm::ErrorInfo {
@@ -68,6 +76,10 @@ class TransportInvalidError : public
llvm::ErrorInfo {
/// A transport class that uses JSON for communication.
class JSONTransport {
public:
+ using ReadHandleUP = MainLoopBase::ReadHandleUP;
+ template
+ using Callback = std::function)>;
+
JSONTransport(lldb::IOObjectSP input, lldb::IOObjectSP output);
virtual ~JSONTransport() = default;
@@ -83,24 +95,69 @@ class JSONTransport {
return WriteImpl(message);
}
- /// Reads the next message from the input stream.
+ /// Registers the transport with the MainLoop.
template
- llvm::Expected Read(const std::chrono::microseconds &timeout) {
-llvm::Expected message = ReadImpl(timeout);
-if (!message)
- return message.takeError();
-return llvm::json::parse(/*JSON=*/*message);
+ llvm::Expected RegisterReadObject(MainLoopBase &loop,
+ Callback callback) {
+Status error;
+ReadHandleUP handle = loop.RegisterReadObject(
+m_input,
+[&](MainLoopBase &loop) {
+ char buffer[kReadBufferSize];
+ size_t len = sizeof(buffer);
+ if (llvm::Error error = m_input->Read(buffer, len).takeError()) {
+callback(loop, std::move(error));
+return;
+ }
+
+ if (len)
+m_buffer.append(std::string(buffer, len));
+
+ // If the buffer has contents, try parsing any pending messages.
+ if (!m_buffer.empty()) {
+llvm::Expected> messages = Parse();
+if (llvm::Error error = messages.takeError()) {
+
[Lldb-commits] [lldb] [lldb] Update JSONTransport to use MainLoop for reading. (PR #152367)
https://github.com/ashgti ready_for_review https://github.com/llvm/llvm-project/pull/152367 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Update JSONTransport to use MainLoop for reading. (PR #152367)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: John Harrison (ashgti)
Changes
Reapply "[lldb] Update JSONTransport to use MainLoop for reading." (#152155)
This reverts commit cd40281685f642ad879e33f3fda8d1faa136ebf4.
This also includes some updates to try to address the platforms with failing
tests.
I updated the JSONTransport and tests to use std::function instead of
llvm:unique_function. I think the tests were failing due to the unique_function
not being moved correctly in the loop on some platforms.
---
Patch is 54.04 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/152367.diff
11 Files Affected:
- (modified) lldb/include/lldb/Host/JSONTransport.h (+84-29)
- (modified) lldb/source/Host/common/JSONTransport.cpp (+53-114)
- (modified) lldb/test/API/tools/lldb-dap/io/TestDAP_io.py (+17-10)
- (modified) lldb/tools/lldb-dap/DAP.cpp (+65-63)
- (modified) lldb/tools/lldb-dap/DAP.h (+7)
- (modified) lldb/tools/lldb-dap/Transport.h (+1-1)
- (modified) lldb/unittests/DAP/DAPTest.cpp (+5-6)
- (modified) lldb/unittests/DAP/TestBase.cpp (+17-9)
- (modified) lldb/unittests/DAP/TestBase.h (+20)
- (modified) lldb/unittests/Host/JSONTransportTest.cpp (+228-71)
- (modified) lldb/unittests/ProtocolServer/ProtocolMCPServerTest.cpp (+76-55)
``diff
diff --git a/lldb/include/lldb/Host/JSONTransport.h
b/lldb/include/lldb/Host/JSONTransport.h
index 4087cdf2b42f7..98bce6e265356 100644
--- a/lldb/include/lldb/Host/JSONTransport.h
+++ b/lldb/include/lldb/Host/JSONTransport.h
@@ -13,13 +13,15 @@
#ifndef LLDB_HOST_JSONTRANSPORT_H
#define LLDB_HOST_JSONTRANSPORT_H
+#include "lldb/Host/MainLoopBase.h"
#include "lldb/lldb-forward.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/JSON.h"
-#include
+#include
#include
+#include
namespace lldb_private {
@@ -28,27 +30,33 @@ class TransportEOFError : public
llvm::ErrorInfo {
static char ID;
TransportEOFError() = default;
-
- void log(llvm::raw_ostream &OS) const override {
-OS << "transport end of file reached";
- }
+ void log(llvm::raw_ostream &OS) const override { OS << "transport EOF"; }
std::error_code convertToErrorCode() const override {
-return llvm::inconvertibleErrorCode();
+return std::make_error_code(std::errc::io_error);
}
};
-class TransportTimeoutError : public llvm::ErrorInfo {
+class TransportUnhandledContentsError
+: public llvm::ErrorInfo {
public:
static char ID;
- TransportTimeoutError() = default;
+ explicit TransportUnhandledContentsError(std::string unhandled_contents)
+ : m_unhandled_contents(unhandled_contents) {}
void log(llvm::raw_ostream &OS) const override {
-OS << "transport operation timed out";
+OS << "transport EOF with unhandled contents " << m_unhandled_contents;
}
std::error_code convertToErrorCode() const override {
-return std::make_error_code(std::errc::timed_out);
+return std::make_error_code(std::errc::bad_message);
}
+
+ const std::string &getUnhandledContents() const {
+return m_unhandled_contents;
+ }
+
+private:
+ std::string m_unhandled_contents;
};
class TransportInvalidError : public llvm::ErrorInfo {
@@ -68,6 +76,10 @@ class TransportInvalidError : public
llvm::ErrorInfo {
/// A transport class that uses JSON for communication.
class JSONTransport {
public:
+ using ReadHandleUP = MainLoopBase::ReadHandleUP;
+ template
+ using Callback = std::function)>;
+
JSONTransport(lldb::IOObjectSP input, lldb::IOObjectSP output);
virtual ~JSONTransport() = default;
@@ -83,24 +95,69 @@ class JSONTransport {
return WriteImpl(message);
}
- /// Reads the next message from the input stream.
+ /// Registers the transport with the MainLoop.
template
- llvm::Expected Read(const std::chrono::microseconds &timeout) {
-llvm::Expected message = ReadImpl(timeout);
-if (!message)
- return message.takeError();
-return llvm::json::parse(/*JSON=*/*message);
+ llvm::Expected RegisterReadObject(MainLoopBase &loop,
+ Callback callback) {
+Status error;
+ReadHandleUP handle = loop.RegisterReadObject(
+m_input,
+[&](MainLoopBase &loop) {
+ char buffer[kReadBufferSize];
+ size_t len = sizeof(buffer);
+ if (llvm::Error error = m_input->Read(buffer, len).takeError()) {
+callback(loop, std::move(error));
+return;
+ }
+
+ if (len)
+m_buffer.append(std::string(buffer, len));
+
+ // If the buffer has contents, try parsing any pending messages.
+ if (!m_buffer.empty()) {
+llvm::Expected> messages = Parse();
+if (llvm::Error error = messages.takeError()) {
+ callback(loop, std::move(error));
+ return;
+}
+
+for (const aut
[Lldb-commits] [lldb] [lldb][ARM] Port Arm Linux to use NativeRegisterContextDBReg (PR #152284)
@@ -76,17 +77,26 @@ class NativeRegisterContextDBReg
// On AArch64 and Loongarch the hardware breakpoint length size is 4, and the
// target address must 4-byte alignment.
- bool ValidateBreakpoint(size_t size, lldb::addr_t addr) {
+ virtual bool ValidateBreakpoint(size_t size, lldb::addr_t addr) {
return (size == 4) && !(addr & 0x3);
}
+
struct WatchpointDetails {
size_t size;
lldb::addr_t addr;
};
virtual std::optional
AdjustWatchpoint(const WatchpointDetails &details) = 0;
+
+ using BreakpointDetails = WatchpointDetails;
+ virtual std::optional
+ AdjustBreakpoint(const BreakpointDetails &details) {
b10902118 wrote:
Is this used?
https://github.com/llvm/llvm-project/pull/152284
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ARM] Port Arm Linux to use NativeRegisterContextDBReg (PR #152284)
https://github.com/b10902118 edited https://github.com/llvm/llvm-project/pull/152284 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [libcxxabi] [lldb] [llvm] [lldb][Expression] Add structor variant to LLDB's function call labels (PR #149827)
@@ -2482,6 +2485,134 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE
&orig_die,
return false;
}
+static int ClangToItaniumCtorKind(clang::CXXCtorType kind) {
+ switch (kind) {
+ case clang::CXXCtorType::Ctor_Complete:
+return 1;
+ case clang::CXXCtorType::Ctor_Base:
+return 2;
+ case clang::CXXCtorType::Ctor_CopyingClosure:
+ case clang::CXXCtorType::Ctor_DefaultClosure:
+ case clang::CXXCtorType::Ctor_Comdat:
+llvm_unreachable("Unexpected constructor kind.");
+ }
+}
+
+static int ClangToItaniumDtorKind(clang::CXXDtorType kind) {
+ switch (kind) {
+ case clang::CXXDtorType::Dtor_Deleting:
+return 0;
+ case clang::CXXDtorType::Dtor_Complete:
+return 1;
+ case clang::CXXDtorType::Dtor_Base:
+return 2;
+ case clang::CXXDtorType::Dtor_Comdat:
+llvm_unreachable("Unexpected destructor kind.");
+ }
+}
+
+static std::optional
+GetItaniumCtorDtorVariant(llvm::StringRef discriminator) {
+ const bool is_ctor = discriminator.consume_front("C");
+ if (!is_ctor && !discriminator.consume_front("D"))
+return std::nullopt;
+
+ uint64_t structor_kind;
+ if (!llvm::to_integer(discriminator, structor_kind))
+return std::nullopt;
+
+ if (is_ctor) {
+if (structor_kind > clang::CXXCtorType::Ctor_DefaultClosure)
+ return std::nullopt;
+
+return ClangToItaniumCtorKind(
+static_cast(structor_kind));
+ }
+
+ if (structor_kind > clang::CXXDtorType::Dtor_Comdat)
+return std::nullopt;
+
+ return
ClangToItaniumDtorKind(static_cast(structor_kind));
+}
+
+DWARFDIE SymbolFileDWARF::FindFunctionDefinition(const FunctionCallLabel
&label,
+ const DWARFDIE &declaration) {
+ DWARFDIE definition;
+ llvm::DenseMap structor_variant_to_die;
+
+ // eFunctionNameTypeFull for mangled name lookup.
+ // eFunctionNameTypeMethod is required for structor lookups (since we look
+ // those up by DW_AT_name).
+ Module::LookupInfo info(ConstString(label.lookup_name),
+ lldb::eFunctionNameTypeFull |
+ lldb::eFunctionNameTypeMethod,
+ lldb::eLanguageTypeUnknown);
+
+ m_index->GetFunctions(info, *this, {}, [&](DWARFDIE entry) {
+if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0))
+ return IterationAction::Continue;
+
+auto spec = entry.GetAttributeValueAsReferenceDIE(DW_AT_specification);
+if (!spec)
+ return IterationAction::Continue;
+
+if (spec != declaration)
Michael137 wrote:
For the structural match, were you suggesting we re-use the innards of
`CopyUniqueClassMethodTypes` to do so, or that there is something on the
`DWARFASTParserClang` that should've been cached about the fact that the two
DIEs are structurally the same?
https://github.com/llvm/llvm-project/pull/149827
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Propagate ExpressionErrors from ValueObjectPrinter::GetDescriptionForDisplay (PR #152417)
@@ -150,6 +151,11 @@ llvm::Expected
ValueObjectPrinter::GetDescriptionForDisplay() {
if (maybe_str)
return maybe_str;
+ if (maybe_str.errorIsA())
+// Propagate expression errors to expose diagnostics to the user.
+// Without this early exit, the summary/value may be shown without errors.
+return maybe_str;
+
adrian-prantl wrote:
Would this be testable by running an expression that fails reliably? For
example by implementing a [-description] method that crashes?
https://github.com/llvm/llvm-project/pull/152417
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix auto advance PC in `EmulateInstructionARM64` if PC >= 4G (PR #151460)
JDevlieghere wrote: Seems like this is [tripping up](https://ci.swift.org/view/all/job/llvm.org/view/LLDB/job/lldb-cmake-sanitized/2038/testReport/lldb-unit/Instruction___EmulatorTests_1/16/) UBSan: ``` [--] 1 test from TestAArch64Emulator [ RUN ] TestAArch64Emulator.TestAutoAdvancePC /Users/ec2-user/jenkins/workspace/llvm.org/lldb-cmake-sanitized/llvm-project/lldb/unittests/Instruction/ARM64/TestAArch64Emulator.cpp:115:34: runtime error: index 1311768467463790080 out of bounds for type 'uint8_t[64]' (aka 'unsigned char[64]') SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /Users/ec2-user/jenkins/workspace/llvm.org/lldb-cmake-sanitized/llvm-project/lldb/unittests/Instruction/ARM64/TestAArch64Emulator.cpp:115:34 in ``` https://github.com/llvm/llvm-project/pull/151460 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ARM] Port Arm Linux to use NativeRegisterContextDBReg (PR #152284)
b10902118 wrote:
Other parts looks the same as my previous try.
I haven't test this one, but older version seems to already have problem with
thumb breakpoint. In my manual test, soft bp caused segmentation fault on 6.15
arm64 linux kernel (just remember qemu complained [GUP] and gpt says it is
stack allocation issue), but ok on my old arm64 android somehow. Hard bp (on
old android) works only in the first trigger and then stuck there. I'll trace
this and may take a while.
I just started with the infinite loop program below and manually attached to
it, kind of clumsy. Any suggestions are welcomed.
```c
int main() {
volatile int a = 42;
while (true) {
a += 1;
}
return 0;
}
```
https://github.com/llvm/llvm-project/pull/152284
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Update JSONTransport to use MainLoop for reading. (PR #152367)
https://github.com/JDevlieghere approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/152367 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Run API tests with PDB too (PR #149305)
@@ -804,6 +804,13 @@ def setUpCommands(cls): ) return commands +def getDebugInfoSetupCommands(self): +if self.getDebugInfo() == "native-pdb": Michael137 wrote: Why not fold this into `setUpCommands`? Then we don't need to loop over these here separately https://github.com/llvm/llvm-project/pull/149305 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Run API tests with PDB too (PR #149305)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/149305 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Don't crash if no default unwind plan (PR #152481)
https://github.com/nikic created
https://github.com/llvm/llvm-project/pull/152481
The code was assuming that if abi_sp is not null, then it will also return a
non-null default unwind plan. However, this is not the case at least on s390x,
so check for that. In that case, we'll treat it as an invalid frame.
>From d638c5ac3db3adb773d006ead6749c0fae5ec3e0 Mon Sep 17 00:00:00 2001
From: Nikita Popov
Date: Thu, 7 Aug 2025 13:05:23 +0200
Subject: [PATCH] [lldb] Don't crash if no default unwind plan
The code was assuming that if abi_sp is not null, then it will
also return a non-null default unwind plan. However, this is not
the case at least on s390x, so check for that. In that case,
we'll treat it as an invalid frame.
---
lldb/source/Target/RegisterContextUnwind.cpp | 7 +--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp
b/lldb/source/Target/RegisterContextUnwind.cpp
index 9e9e2d86958f3..bdd8578b14dba 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -426,9 +426,12 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
}
}
-if (abi_sp) {
- m_fast_unwind_plan_sp.reset();
+m_fast_unwind_plan_sp.reset();
+m_full_unwind_plan_sp.reset();
+if (abi_sp)
m_full_unwind_plan_sp = abi_sp->CreateDefaultUnwindPlan();
+
+if (m_full_unwind_plan_sp) {
if (m_frame_type != eSkipFrame) // don't override eSkipFrame
{
m_frame_type = eNormalFrame;
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Don't crash if no default unwind plan (PR #152481)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: Nikita Popov (nikic)
Changes
The code was assuming that if abi_sp is not null, then it will also return a
non-null default unwind plan. However, this is not the case at least on s390x,
so check for that. In that case, we'll treat it as an invalid frame.
---
Full diff: https://github.com/llvm/llvm-project/pull/152481.diff
1 Files Affected:
- (modified) lldb/source/Target/RegisterContextUnwind.cpp (+5-2)
``diff
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp
b/lldb/source/Target/RegisterContextUnwind.cpp
index 9e9e2d86958f3..bdd8578b14dba 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -426,9 +426,12 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
}
}
-if (abi_sp) {
- m_fast_unwind_plan_sp.reset();
+m_fast_unwind_plan_sp.reset();
+m_full_unwind_plan_sp.reset();
+if (abi_sp)
m_full_unwind_plan_sp = abi_sp->CreateDefaultUnwindPlan();
+
+if (m_full_unwind_plan_sp) {
if (m_frame_type != eSkipFrame) // don't override eSkipFrame
{
m_frame_type = eNormalFrame;
``
https://github.com/llvm/llvm-project/pull/152481
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] fac7453 - [lldb][Mangled] Move SuffixRange computation into TrackingOutputBuffer (#152483)
Author: Michael Buch
Date: 2025-08-07T14:39:52+01:00
New Revision: fac7453d2ca7ebe33dec3d60211c0374a2bb69cd
URL:
https://github.com/llvm/llvm-project/commit/fac7453d2ca7ebe33dec3d60211c0374a2bb69cd
DIFF:
https://github.com/llvm/llvm-project/commit/fac7453d2ca7ebe33dec3d60211c0374a2bb69cd.diff
LOG: [lldb][Mangled] Move SuffixRange computation into TrackingOutputBuffer
(#152483)
This way all the tracking is self-contained in `TrackingOutputBuffer`
and we can test the `SuffixRange` properly.
Added:
Modified:
lldb/source/Core/DemangledNameInfo.cpp
lldb/source/Core/Mangled.cpp
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
lldb/unittests/Core/MangledTest.cpp
Removed:
diff --git a/lldb/source/Core/DemangledNameInfo.cpp
b/lldb/source/Core/DemangledNameInfo.cpp
index 00227f02bbff8..76f8987c5149c 100644
--- a/lldb/source/Core/DemangledNameInfo.cpp
+++ b/lldb/source/Core/DemangledNameInfo.cpp
@@ -111,6 +111,11 @@ void TrackingOutputBuffer::finalizeEnd() {
if (NameInfo.ScopeRange.first > NameInfo.ScopeRange.second)
NameInfo.ScopeRange.second = NameInfo.ScopeRange.first;
NameInfo.BasenameRange.first = NameInfo.ScopeRange.second;
+
+ // We call anything past the FunctionEncoding the "suffix".
+ // In practice this would be nodes like `DotSuffix` that wrap
+ // a FunctionEncoding.
+ NameInfo.SuffixRange.first = getCurrentPosition();
}
ScopedOverride TrackingOutputBuffer::enterFunctionTypePrinting() {
@@ -138,6 +143,9 @@ void TrackingOutputBuffer::printLeft(const Node &N) {
default:
OutputBuffer::printLeft(N);
}
+
+ // Keep updating suffix until we reach the end.
+ NameInfo.SuffixRange.second = getCurrentPosition();
}
void TrackingOutputBuffer::printRight(const Node &N) {
@@ -151,6 +159,9 @@ void TrackingOutputBuffer::printRight(const Node &N) {
default:
OutputBuffer::printRight(N);
}
+
+ // Keep updating suffix until we reach the end.
+ NameInfo.SuffixRange.second = getCurrentPosition();
}
void TrackingOutputBuffer::printLeftImpl(const FunctionType &N) {
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 3663f430111c2..ce4db4e0daa8b 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -172,9 +172,6 @@ GetItaniumDemangledStr(const char *M) {
TrackingOutputBuffer OB(demangled_cstr, demangled_size);
demangled_cstr = ipd.finishDemangle(&OB);
-// TODO: we should set the SuffixRange inside the TrackingOutputBuffer.
-OB.NameInfo.SuffixRange.first = OB.NameInfo.QualifiersRange.second;
-OB.NameInfo.SuffixRange.second = std::string_view(OB).size();
info = std::move(OB.NameInfo);
assert(demangled_cstr &&
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 3bc870810dc81..3118ff151d1cf 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -392,13 +392,16 @@ GetDemangledScope(const SymbolContext &sc) {
return CPlusPlusLanguage::GetDemangledScope(demangled_name, info);
}
-/// Handles anything printed after the FunctionEncoding ItaniumDemangle
-/// node. Most notably the DotSuffix node.
-///
-/// FIXME: the suffix should also have an associated
-/// CPlusPlusLanguage::GetDemangledFunctionSuffix
-/// once we start setting the `DemangledNameInfo::SuffixRange`
-/// from inside the `TrackingOutputBuffer`.
+llvm::Expected
+CPlusPlusLanguage::GetDemangledFunctionSuffix(llvm::StringRef demangled,
+ const DemangledNameInfo &info) {
+ if (!info.hasSuffix())
+return llvm::createStringError("Suffix range for '%s' is invalid.",
+ demangled.data());
+
+ return demangled.slice(info.SuffixRange.first, info.SuffixRange.second);
+}
+
static llvm::Expected
GetDemangledFunctionSuffix(const SymbolContext &sc) {
auto info_or_err = GetAndValidateInfo(sc);
@@ -407,11 +410,7 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- if (!info.hasSuffix())
-return llvm::createStringError("Suffix range for '%s' is invalid.",
- demangled_name.data());
-
- return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
+ return CPlusPlusLanguage::GetDemangledFunctionSuffix(demangled_name, info);
}
llvm::Expected
@@ -2424,7 +2423,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
return true;
}
case FormatEntity::Entry::Type::FunctionSuffix: {
-auto suffix_or_err = GetDemangledFunctionSuffix(sc);
+auto suffix_or_err = ::GetDemangledFunctionSuffix(sc);
if (!suffix_or_err) {
LLDB_LOG_ERROR(
GetLog
[Lldb-commits] [lldb] [lldb][Mangled] Move SuffixRange computation into TrackingOutputBuffer (PR #152483)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/152483 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Annotate disassembly with register‐resident variable locations (PR #147460)
adrian-prantl wrote: > > adding an option to the dissemble CommandObject is the right solution. > > Personally I think I would prefer an option to the CommandObject. Do you > > think this is feasible, or are there more many points through which the > > disassembly is reachable, making an option infeasible? > > After looking more closely into one of the failing test cases, > TestFrameDisassemble.py, I noticed that its entry point for disassembly is > through `SBFrame::Disassemble()`, which bypasses the CLI entirely and doesn’t > go through `CommandObjectDisassemble`. There are multiple options: 1. keep the original behavior and call the internal API from SBFrame::Disassemble with the flag to turn off the annotations 2. (optional) add an SBFrame::Disassemble(class DisassembleOptions) overload > Since this means command-line options like `--rich` wouldn’t apply in this > context, would it be okay if I start by introducing a new setting (e.g., > `target.enable-rich-disassembly`) to gate the annotation output globally? I think I would prefer implementing option (1) and worry about exposing the new behavior through the API later. I would like to avoid global or target-specific settings if possible, because they can introduce unwanted side effects. (Imagine an IDE that depends on the traditional disassemble format, and a user that turns on the setting in their lldbinit file). > Once that’s in place and CI is passing, I can follow up with a separate > change to add the `--rich` option to `CommandObjectDisassemble`, which would > override the setting for CLI use cases and give users more fine-grained > control. > > Does that sound reasonable? https://github.com/llvm/llvm-project/pull/147460 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [RISCV-LLDB] RISCV feature attribute support and allows overriding additional(default) feature (PR #147990)
santhoshe447 wrote: Kindly share any inputs or suggestion, if any. https://github.com/llvm/llvm-project/pull/147990 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Move the generic MCP server code into Protocol/MCP (NFC) (PR #152396)
https://github.com/ashgti approved this pull request. https://github.com/llvm/llvm-project/pull/152396 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [vscode-lldb] Add VS Code commands for high level debug workflow (PR #151827)
ashgti wrote: I don't know if there is any other documentation on that. Its in the code and supported and used by a few different extensions. For example, the npm extension uses this strategy for debugging with the vscode-js-debug extension. https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts#L127-L168 is the code for this, but its not really documentation as much as just referencing the actual implementation. https://github.com/llvm/llvm-project/pull/151827 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [LLVM] [LLDB] Emit and handle `lf_alias` nodes (PR #152484)
dwblaikie wrote: (I'm not particularly up on the details of PDB - but this patch should land, if/when it lands, in a few parts (& maybe should be separate pull requests) - the LLVM side of things, for instance, could be separated from the LLDB parts at least, I think) https://github.com/llvm/llvm-project/pull/152484 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix incorrect print of UUID and load address (PR #152560)
https://github.com/ddcc created https://github.com/llvm/llvm-project/pull/152560
The current display is missing a space, for example:
```
no target │ Locating binary: 24906A83-0182-361B-8B4A-90A249B04FD7at
0x000c0d108000
```
>From 4c9d337dcd01c6713fc6a250ac30bdb22ae1abfb Mon Sep 17 00:00:00 2001
From: Dominic Chen
Date: Thu, 7 Aug 2025 10:40:15 -0700
Subject: [PATCH] Fix incorrect print of UUID and load address
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The current display is missing a space, for example:
```
no target │ Locating binary: 24906A83-0182-361B-8B4A-90A249B04FD7at
0x000c0d108000
```
---
lldb/source/Core/DynamicLoader.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/source/Core/DynamicLoader.cpp
b/lldb/source/Core/DynamicLoader.cpp
index 4be9f3eb9abc5..7580b15c02ce1 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -211,7 +211,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
if (uuid.IsValid())
prog_str << uuid.GetAsString();
if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
-prog_str << "at 0x";
+prog_str << " at 0x";
prog_str.PutHex64(value);
}
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix incorrect print of UUID and load address (PR #152560)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: Dominic Chen (ddcc)
Changes
The current display is missing a space, for example:
```
no target │ Locating binary: 24906A83-0182-361B-8B4A-90A249B04FD7at
0x000c0d108000
```
---
Full diff: https://github.com/llvm/llvm-project/pull/152560.diff
1 Files Affected:
- (modified) lldb/source/Core/DynamicLoader.cpp (+1-1)
``diff
diff --git a/lldb/source/Core/DynamicLoader.cpp
b/lldb/source/Core/DynamicLoader.cpp
index 4be9f3eb9abc5..7580b15c02ce1 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -211,7 +211,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
if (uuid.IsValid())
prog_str << uuid.GetAsString();
if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
-prog_str << "at 0x";
+prog_str << " at 0x";
prog_str.PutHex64(value);
}
``
https://github.com/llvm/llvm-project/pull/152560
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix incorrect print of UUID and load address (PR #152560)
https://github.com/bulbazord approved this pull request. https://github.com/llvm/llvm-project/pull/152560 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix incorrect print of UUID and load address (PR #152560)
https://github.com/JDevlieghere approved this pull request. https://github.com/llvm/llvm-project/pull/152560 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix race condition in Process::WaitForProcessToStop() (PR #144919)
jimingham wrote: If the user has set "UnwindOnException" to false in their ExpressionOptions, we need to propagate that stop event and the driver would need to consume it to show the user that they are stopped at the crash site. So we definitely have to rebroadcast the event and the driver needs to be waiting to consume it. So having the test check for the event (just like the lldb driver would do) is the correct way to use lldb. https://github.com/llvm/llvm-project/pull/144919 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [NFC][lldb] Speed up lookup of shared modules (PR #152054)
https://github.com/augusto2112 closed https://github.com/llvm/llvm-project/pull/152054 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][NativePDB] Find functions by basename (PR #152295)
@@ -282,6 +284,13 @@ class SymbolFileNativePDB : public SymbolFileCommon {
m_parent_types;
lldb_private::UniqueCStringMap m_type_base_names;
+
+ /// Global ID -> mangled name/full function name
Nerixyz wrote:
Right, sorry for the confusion.
https://github.com/llvm/llvm-project/pull/152295
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][NativePDB] Find functions by basename (PR #152295)
https://github.com/Nerixyz updated
https://github.com/llvm/llvm-project/pull/152295
>From b6886d625c55e7f2cfbbbc699ffaf0791ea192ff Mon Sep 17 00:00:00 2001
From: Nerixyz
Date: Wed, 6 Aug 2025 13:30:38 +0200
Subject: [PATCH 1/4] [LLDB][NativePDB] Find functions by basename
---
.../NativePDB/SymbolFileNativePDB.cpp | 149 +++---
.../NativePDB/SymbolFileNativePDB.h | 9 ++
.../SymbolFile/NativePDB/find-functions.cpp | 34
3 files changed, 173 insertions(+), 19 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index dcea33dd9f854..04a3b9b7b87a2 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -39,6 +39,7 @@
#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDB.h"
@@ -1641,6 +1642,94 @@ void SymbolFileNativePDB::DumpClangAST(Stream &s,
llvm::StringRef filter) {
clang->GetNativePDBParser()->Dump(s, filter);
}
+void SymbolFileNativePDB::CacheFunctionNames() {
+ if (!m_func_full_names.IsEmpty())
+return;
+
+ // (segment, code offset) -> gid
+ std::map, uint32_t> addr_ids;
+
+ // First, find all function references in the globals table.
+ for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
+CVSymbol ref_sym = m_index->symrecords().readRecord(gid);
+auto kind = ref_sym.kind();
+if (kind != S_PROCREF && kind != S_LPROCREF)
+ continue;
+
+ProcRefSym ref =
+llvm::cantFail(SymbolDeserializer::deserializeAs(ref_sym));
+if (ref.Name.empty())
+ continue;
+
+// Find the function this is referencing
+CompilandIndexItem &cci =
+m_index->compilands().GetOrCreateCompiland(ref.modi());
+auto iter = cci.m_debug_stream.getSymbolArray().at(ref.SymOffset);
+if (iter == cci.m_debug_stream.getSymbolArray().end())
+ continue;
+kind = iter->kind();
+if (kind != S_GPROC32 && kind != S_LPROC32)
+ continue;
+
+ProcSym proc =
+llvm::cantFail(SymbolDeserializer::deserializeAs(*iter));
+if ((proc.Flags & ProcSymFlags::IsUnreachable) != ProcSymFlags::None)
+ continue;
+if (proc.Name.empty())
+ continue;
+
+// The function/procedure symbol only contains the demangled name.
+// The mangled names are in the publics table. Save the address of this
+// function to lookup the mangled name later.
+addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid);
+
+llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(proc.Name);
+if (basename.empty())
+ basename = proc.Name;
+
+m_func_base_names.Append(ConstString(basename), gid);
+m_func_full_names.Append(ConstString(proc.Name), gid);
+
+// To see if this is a member function, check the type
+auto type = m_index->tpi().getType(proc.FunctionType);
+if (type.kind() == LF_MFUNCTION) {
+ MemberFunctionRecord mfr;
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs(type, mfr));
+ if (!mfr.getThisType().isNoneType())
+m_func_method_names.Append(ConstString(basename), gid);
+}
+ }
+
+ // The publics stream contains all mangled function names and their address.
+ for (auto pid : m_index->publics().getPublicsTable()) {
+PdbGlobalSymId global{pid, true};
+CVSymbol sym = m_index->ReadSymbolRecord(global);
+auto kind = sym.kind();
+if (kind != S_PUB32)
+ continue;
+PublicSym32 pub =
+llvm::cantFail(SymbolDeserializer::deserializeAs(sym));
+// We only care about mangled names - if the name isn't mangled, it's
+// already in the full name map
+if (!Mangled::IsMangledName(pub.Name))
+ continue;
+
+// Check if this symbol is for one of our functions
+auto it = addr_ids.find({pub.Segment, pub.Offset});
+if (it != addr_ids.end())
+ m_func_full_names.Append(ConstString(pub.Name), it->second);
+ }
+
+ // Sort them before value searching is working properly
+ m_func_full_names.Sort();
+ m_func_full_names.SizeToFit();
+ m_func_method_names.Sort();
+ m_func_method_names.SizeToFit();
+ m_func_base_names.Sort();
+ m_func_base_names.SizeToFit();
+}
+
void SymbolFileNativePDB::FindGlobalVariables(
ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
@@ -1677,34 +1766,56 @@ void SymbolFileNativePDB::FindFunctions(
if (name_type_mask & eFunctionNameTypeFull)
name = lookup_info.GetName();
- // For now we only support lookup by method name or full name.
if (!(name_type_mask & eFunctionNameTy
[Lldb-commits] [lldb] [LLDB][NativePDB] Find functions by basename (PR #152295)
@@ -1677,34 +1766,56 @@ void SymbolFileNativePDB::FindFunctions(
if (name_type_mask & eFunctionNameTypeFull)
name = lookup_info.GetName();
- // For now we only support lookup by method name or full name.
if (!(name_type_mask & eFunctionNameTypeFull ||
+name_type_mask & eFunctionNameTypeBase ||
name_type_mask & eFunctionNameTypeMethod))
return;
+ CacheFunctionNames();
- using SymbolAndOffset = std::pair;
+ std::set resolved_ids; // avoid duplicate lookups
+ auto resolve_from = [&](UniqueCStringMap &Names) {
+std::vector ids;
+if (!Names.GetValues(name, ids))
+ return;
- std::vector matches = m_index->globals().findRecordsByName(
- name.GetStringRef(), m_index->symrecords());
- for (const SymbolAndOffset &match : matches) {
-if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF)
- continue;
-ProcRefSym proc(match.second.kind());
-cantFail(SymbolDeserializer::deserializeAs(match.second,
proc));
+for (uint32_t id : ids) {
+ if (resolved_ids.find(id) != resolved_ids.end())
+continue;
-if (!IsValidRecord(proc))
- continue;
+ PdbGlobalSymId global{id, false};
+ if (parent_decl_ctx.IsValid() &&
+ GetDeclContextContainingUID(toOpaqueUid(global)) != parent_decl_ctx)
+continue;
-CompilandIndexItem &cci =
-m_index->compilands().GetOrCreateCompiland(proc.modi());
-SymbolContext sc;
+ CVSymbol sym = m_index->ReadSymbolRecord(global);
+ auto kind = sym.kind();
+ lldbassert(kind == S_PROCREF || kind == S_LPROCREF);
-sc.comp_unit = GetOrCreateCompileUnit(cci).get();
-PdbCompilandSymId func_id(proc.modi(), proc.SymOffset);
-sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get();
+ ProcRefSym proc =
+ cantFail(SymbolDeserializer::deserializeAs(sym));
-sc_list.Append(sc);
- }
+ if (!IsValidRecord(proc))
+continue;
+
+ CompilandIndexItem &cci =
+ m_index->compilands().GetOrCreateCompiland(proc.modi());
+ SymbolContext sc;
+
+ sc.comp_unit = GetOrCreateCompileUnit(cci).get();
Michael137 wrote:
missing `sc.comp_unit` nullptr check
https://github.com/llvm/llvm-project/pull/152295
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][NativePDB] Find functions by basename (PR #152295)
@@ -282,6 +284,13 @@ class SymbolFileNativePDB : public SymbolFileCommon {
m_parent_types;
lldb_private::UniqueCStringMap m_type_base_names;
+
+ /// Global ID -> mangled name/full function name
Michael137 wrote:
Did you mean for these mapping comments to be reversed. E.g.,:
```
/// mangled name/full function name -> Global ID
```
?
https://github.com/llvm/llvm-project/pull/152295
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [libcxx] [lldb] [libcxx] adds size-based `__split_buffer` representation to unstable ABI (PR #139632)
@@ -45,11 +47,232 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
+template
+class __split_buffer_pointer_layout {
+public: // TODO: make private after vector becomes size-based
+ using reference = typename _SplitBuffer::reference;
+ using const_reference = typename _SplitBuffer::const_reference;
+ using pointer = typename _SplitBuffer::pointer;
+ using const_pointer = typename _SplitBuffer::const_pointer;
+ using size_type = typename _SplitBuffer::size_type;
+ using allocator_type = typename _SplitBuffer::allocator_type;
+
+ pointer __first_ = nullptr;
+ pointer __begin_ = nullptr;
+ pointer __end_ = nullptr;
+ _LIBCPP_COMPRESSED_PAIR(pointer, __cap_ = nullptr, allocator_type, __alloc_);
+
+public:
+ static const bool __is_size_based = false;
philnik777 wrote:
This is a bit smelly. Why do we need to inform `__split_buffer` which memory
layout it is using?
https://github.com/llvm/llvm-project/pull/139632
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [libcxx] [lldb] [libcxx] adds size-based `__split_buffer` representation to unstable ABI (PR #139632)
@@ -78,23 +80,232 @@ public:
__split_buffer,
void>;
- pointer __first_;
- pointer __begin_;
- pointer __end_;
- _LIBCPP_COMPRESSED_PAIR(pointer, __cap_, allocator_type, __alloc_);
+ struct __data {
+pointer __first_ = nullptr;
+pointer __begin_ = nullptr;
+#ifdef _LIBCPP_ABI_SIZE_BASED_CONTAINERS
+size_type __size_ = 0;
+size_type __cap_ = 0;
+allocator_type __alloc_;
+#else
+pointer __end_ = nullptr;
+_LIBCPP_COMPRESSED_PAIR(pointer, __cap_ = nullptr, allocator_type,
__alloc_);
+#endif
+
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __data() = default;
+
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __data(const
allocator_type& __alloc)
+: __alloc_(__alloc)
+{}
+
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer begin()
_NOEXCEPT {
+ return __begin_;
+}
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer begin()
const _NOEXCEPT {
+ return __begin_;
+}
+
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end()
_NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_CONTAINERS
+ return __begin_ + __size_;
+#else
+ return __end_;
+#endif
+}
+
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end() const
_NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_CONTAINERS
+ return __begin_ + __size_;
+#else
+ return __end_;
+#endif
+}
philnik777 wrote:
Could you provide an example where that makes a difference?
https://github.com/llvm/llvm-project/pull/139632
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [libcxx] [lldb] [libcxx] adds size-based `__split_buffer` representation to unstable ABI (PR #139632)
@@ -78,23 +301,22 @@ public:
__split_buffer,
void>;
- pointer __first_;
- pointer __begin_;
- pointer __end_;
- _LIBCPP_COMPRESSED_PAIR(pointer, __cap_, allocator_type, __alloc_);
+ _Layout<__split_buffer> __data_;
__split_buffer(const __split_buffer&)= delete;
__split_buffer& operator=(const __split_buffer&) = delete;
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer()
_NOEXCEPT_(is_nothrow_default_constructible::value)
- : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __cap_(nullptr)
{}
+ : __data_() {}
philnik777 wrote:
```suggestion
= default;
```
That should do it, right?
https://github.com/llvm/llvm-project/pull/139632
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [libcxx] [lldb] [libcxx] adds size-based `__split_buffer` representation to unstable ABI (PR #139632)
@@ -428,50 +630,87 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp,
_Allocator>::shrink_to_fi
}
}
-template
+// Need to use this because C++03 doesn't permit constexpr if :(
+template
+struct __maybe_update_sentinel;
+
+template <>
+struct __maybe_update_sentinel {
+ template
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI static void
+ __update_size(_SplitBuffer& __data, _DifferenceType __d) {
+__data.__update_sentinel(__data.size() + __d);
+ }
+
+ template
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI static void
__update_end(_SplitBuffer& __data) {
+__data.update_sentinel(__data.end() + 1);
+ }
+};
+
+template <>
+struct __maybe_update_sentinel {
+ template
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI static void
__update_size(_SplitBuffer&, _DifferenceType) {}
+
+ template
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI static void
__update_end(_SplitBuffer&) {}
+};
philnik777 wrote:
This looks like it should be part of the layout class. The whole point of that
is that we have a uniform interface, which we apparently don't quite have.
https://github.com/llvm/llvm-project/pull/139632
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [libcxx] [lldb] [libcxx] adds size-based `__split_buffer` representation to unstable ABI (PR #139632)
@@ -45,11 +47,232 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
+template
+class __split_buffer_pointer_layout {
+public: // TODO: make private after vector becomes size-based
+ using reference = typename _SplitBuffer::reference;
+ using const_reference = typename _SplitBuffer::const_reference;
+ using pointer = typename _SplitBuffer::pointer;
+ using const_pointer = typename _SplitBuffer::const_pointer;
+ using size_type = typename _SplitBuffer::size_type;
+ using allocator_type = typename _SplitBuffer::allocator_type;
+
+ pointer __first_ = nullptr;
+ pointer __begin_ = nullptr;
+ pointer __end_ = nullptr;
+ _LIBCPP_COMPRESSED_PAIR(pointer, __cap_ = nullptr, allocator_type, __alloc_);
+
+public:
+ static const bool __is_size_based = false;
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
__split_buffer_pointer_layout() = default;
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20
+ _LIBCPP_HIDE_FROM_ABI explicit __split_buffer_pointer_layout(const
allocator_type& __alloc)
+ : __alloc_(__alloc) {}
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer first()
_NOEXCEPT { return __first_; }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer first()
const _NOEXCEPT { return __first_; }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer begin()
_NOEXCEPT { return __begin_; }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer begin()
const _NOEXCEPT { return __begin_; }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end() _NOEXCEPT
{ return __end_; }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end() const
_NOEXCEPT { return __end_; }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const
_NOEXCEPT {
+return static_cast(__end_ - __begin_);
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const
_NOEXCEPT { return __begin_ == __end_; }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity()
const _NOEXCEPT {
+return static_cast(__cap_ - __first_);
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__update_first(pointer __new_first) _NOEXCEPT {
philnik777 wrote:
```suggestion
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_first(pointer
__new_first) _NOEXCEPT {
```
Seems like a more canonical name. Same below.
https://github.com/llvm/llvm-project/pull/139632
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [libcxx] [lldb] [libcxx] adds size-based `__split_buffer` representation to unstable ABI (PR #139632)
@@ -78,23 +301,22 @@ public: __split_buffer, void>; - pointer __first_; - pointer __begin_; - pointer __end_; - _LIBCPP_COMPRESSED_PAIR(pointer, __cap_, allocator_type, __alloc_); + _Layout<__split_buffer> __data_; philnik777 wrote: Could we make this a base instead? I think that would remove the need for a bunch of trivial wrappers throughout the class. https://github.com/llvm/llvm-project/pull/139632 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Run API tests with PDB too (PR #149305)
Nerixyz wrote: Updated the PR to use the new setting and to run tests with both native and DIA (if available). https://github.com/llvm/llvm-project/pull/149305 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add "settings modified" command (PR #152338)
DavidSpickett wrote: Would some `(default: )` be useful? So I can see at a glance that `crash-horribly: true (default: false)` is what I should be investigating. A boolean is a bad example because ofc the default is the 1 other value but you see the idea. https://github.com/llvm/llvm-project/pull/152338 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Run API tests with PDB too (PR #149305)
https://github.com/Michael137 commented: SGTM I'll let @labath / @JDevlieghere give the final say https://github.com/llvm/llvm-project/pull/149305 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Make MSVC STL formatters work with (Native/DIA) PDB (PR #150513)
@@ -0,0 +1,188 @@ +# REQUIRES: target-windows Michael137 wrote: Instead of having these shell tests can we just mark the relevant formatters with the `pdb` categories introduced in https://github.com/llvm/llvm-project/pull/149305? Maybe that was already your plan :) https://github.com/llvm/llvm-project/pull/150513 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Run API tests with PDB too (PR #149305)
@@ -804,6 +804,13 @@ def setUpCommands(cls): ) return commands +def getDebugInfoSetupCommands(self): +if self.getDebugInfo() == "native-pdb": Nerixyz wrote: `setUpCommands` is a `@classmethod`, so it gets the calling class type as it's argument, not the instance. I don't know if/why `@classmethod` is needed there. https://github.com/llvm/llvm-project/pull/149305 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Make MSVC STL formatters work with (Native/DIA) PDB (PR #150513)
@@ -0,0 +1,188 @@ +# REQUIRES: target-windows Nerixyz wrote: Yea, that was my plan. Once that's merged, I'll update the tests. https://github.com/llvm/llvm-project/pull/150513 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][Mangled] Move SuffixRange computation into TrackingOutputBuffer (PR #152483)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: Michael Buch (Michael137)
Changes
This way all the tracking is self-contained in `TrackingOutputBuffer` and we
can test the `SuffixRange` properly.
---
Full diff: https://github.com/llvm/llvm-project/pull/152483.diff
5 Files Affected:
- (modified) lldb/source/Core/DemangledNameInfo.cpp (+11)
- (modified) lldb/source/Core/Mangled.cpp (-3)
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
(+12-13)
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h (+4)
- (modified) lldb/unittests/Core/MangledTest.cpp (+4-4)
``diff
diff --git a/lldb/source/Core/DemangledNameInfo.cpp
b/lldb/source/Core/DemangledNameInfo.cpp
index 00227f02bbff8..4001e699f75c2 100644
--- a/lldb/source/Core/DemangledNameInfo.cpp
+++ b/lldb/source/Core/DemangledNameInfo.cpp
@@ -111,6 +111,11 @@ void TrackingOutputBuffer::finalizeEnd() {
if (NameInfo.ScopeRange.first > NameInfo.ScopeRange.second)
NameInfo.ScopeRange.second = NameInfo.ScopeRange.first;
NameInfo.BasenameRange.first = NameInfo.ScopeRange.second;
+
+ // We call anything past the FunctionEncoding is the suffix.
+ // In practice this would be nodes like `DotSuffix` that wrap
+ // a FunctionEncoding.
+ NameInfo.SuffixRange.first = getCurrentPosition();
}
ScopedOverride TrackingOutputBuffer::enterFunctionTypePrinting() {
@@ -138,6 +143,9 @@ void TrackingOutputBuffer::printLeft(const Node &N) {
default:
OutputBuffer::printLeft(N);
}
+
+ // Keeps updating suffix until we reach the end.
+ NameInfo.SuffixRange.second = getCurrentPosition();
}
void TrackingOutputBuffer::printRight(const Node &N) {
@@ -151,6 +159,9 @@ void TrackingOutputBuffer::printRight(const Node &N) {
default:
OutputBuffer::printRight(N);
}
+
+ // Keeps updating suffix until we reach the end.
+ NameInfo.SuffixRange.second = getCurrentPosition();
}
void TrackingOutputBuffer::printLeftImpl(const FunctionType &N) {
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 3663f430111c2..ce4db4e0daa8b 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -172,9 +172,6 @@ GetItaniumDemangledStr(const char *M) {
TrackingOutputBuffer OB(demangled_cstr, demangled_size);
demangled_cstr = ipd.finishDemangle(&OB);
-// TODO: we should set the SuffixRange inside the TrackingOutputBuffer.
-OB.NameInfo.SuffixRange.first = OB.NameInfo.QualifiersRange.second;
-OB.NameInfo.SuffixRange.second = std::string_view(OB).size();
info = std::move(OB.NameInfo);
assert(demangled_cstr &&
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 3bc870810dc81..3118ff151d1cf 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -392,13 +392,16 @@ GetDemangledScope(const SymbolContext &sc) {
return CPlusPlusLanguage::GetDemangledScope(demangled_name, info);
}
-/// Handles anything printed after the FunctionEncoding ItaniumDemangle
-/// node. Most notably the DotSuffix node.
-///
-/// FIXME: the suffix should also have an associated
-/// CPlusPlusLanguage::GetDemangledFunctionSuffix
-/// once we start setting the `DemangledNameInfo::SuffixRange`
-/// from inside the `TrackingOutputBuffer`.
+llvm::Expected
+CPlusPlusLanguage::GetDemangledFunctionSuffix(llvm::StringRef demangled,
+ const DemangledNameInfo &info) {
+ if (!info.hasSuffix())
+return llvm::createStringError("Suffix range for '%s' is invalid.",
+ demangled.data());
+
+ return demangled.slice(info.SuffixRange.first, info.SuffixRange.second);
+}
+
static llvm::Expected
GetDemangledFunctionSuffix(const SymbolContext &sc) {
auto info_or_err = GetAndValidateInfo(sc);
@@ -407,11 +410,7 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- if (!info.hasSuffix())
-return llvm::createStringError("Suffix range for '%s' is invalid.",
- demangled_name.data());
-
- return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
+ return CPlusPlusLanguage::GetDemangledFunctionSuffix(demangled_name, info);
}
llvm::Expected
@@ -2424,7 +2423,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
return true;
}
case FormatEntity::Entry::Type::FunctionSuffix: {
-auto suffix_or_err = GetDemangledFunctionSuffix(sc);
+auto suffix_or_err = ::GetDemangledFunctionSuffix(sc);
if (!suffix_or_err) {
LLDB_LOG_ERROR(
GetLog(LLDBLog::Language), suffix_or_err.takeError(),
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 4f449f11257a6..4a30299dd2658 100644
--- a/
[Lldb-commits] [lldb] [lldb][Mangled] Move SuffixRange computation into TrackingOutputBuffer (PR #152483)
https://github.com/Michael137 created
https://github.com/llvm/llvm-project/pull/152483
This way all the tracking is self-contained in `TrackingOutputBuffer` and we
can test the `SuffixRange` properly.
>From cdcb92a3012107dce4418de1c74c6142dc356a14 Mon Sep 17 00:00:00 2001
From: Michael Buch
Date: Thu, 7 Aug 2025 13:11:59 +0100
Subject: [PATCH] [lldb][Mangled] Move SuffixRange computation into
TrackingOutputBuffer
This way all the tracking is self-contained in `TrackingOutputBuffer`
and we can test the `SuffixRange` properly.
---
lldb/source/Core/DemangledNameInfo.cpp| 11
lldb/source/Core/Mangled.cpp | 3 ---
.../Language/CPlusPlus/CPlusPlusLanguage.cpp | 25 +--
.../Language/CPlusPlus/CPlusPlusLanguage.h| 4 +++
lldb/unittests/Core/MangledTest.cpp | 8 +++---
5 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/lldb/source/Core/DemangledNameInfo.cpp
b/lldb/source/Core/DemangledNameInfo.cpp
index 00227f02bbff8..4001e699f75c2 100644
--- a/lldb/source/Core/DemangledNameInfo.cpp
+++ b/lldb/source/Core/DemangledNameInfo.cpp
@@ -111,6 +111,11 @@ void TrackingOutputBuffer::finalizeEnd() {
if (NameInfo.ScopeRange.first > NameInfo.ScopeRange.second)
NameInfo.ScopeRange.second = NameInfo.ScopeRange.first;
NameInfo.BasenameRange.first = NameInfo.ScopeRange.second;
+
+ // We call anything past the FunctionEncoding is the suffix.
+ // In practice this would be nodes like `DotSuffix` that wrap
+ // a FunctionEncoding.
+ NameInfo.SuffixRange.first = getCurrentPosition();
}
ScopedOverride TrackingOutputBuffer::enterFunctionTypePrinting() {
@@ -138,6 +143,9 @@ void TrackingOutputBuffer::printLeft(const Node &N) {
default:
OutputBuffer::printLeft(N);
}
+
+ // Keeps updating suffix until we reach the end.
+ NameInfo.SuffixRange.second = getCurrentPosition();
}
void TrackingOutputBuffer::printRight(const Node &N) {
@@ -151,6 +159,9 @@ void TrackingOutputBuffer::printRight(const Node &N) {
default:
OutputBuffer::printRight(N);
}
+
+ // Keeps updating suffix until we reach the end.
+ NameInfo.SuffixRange.second = getCurrentPosition();
}
void TrackingOutputBuffer::printLeftImpl(const FunctionType &N) {
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 3663f430111c2..ce4db4e0daa8b 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -172,9 +172,6 @@ GetItaniumDemangledStr(const char *M) {
TrackingOutputBuffer OB(demangled_cstr, demangled_size);
demangled_cstr = ipd.finishDemangle(&OB);
-// TODO: we should set the SuffixRange inside the TrackingOutputBuffer.
-OB.NameInfo.SuffixRange.first = OB.NameInfo.QualifiersRange.second;
-OB.NameInfo.SuffixRange.second = std::string_view(OB).size();
info = std::move(OB.NameInfo);
assert(demangled_cstr &&
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 3bc870810dc81..3118ff151d1cf 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -392,13 +392,16 @@ GetDemangledScope(const SymbolContext &sc) {
return CPlusPlusLanguage::GetDemangledScope(demangled_name, info);
}
-/// Handles anything printed after the FunctionEncoding ItaniumDemangle
-/// node. Most notably the DotSuffix node.
-///
-/// FIXME: the suffix should also have an associated
-/// CPlusPlusLanguage::GetDemangledFunctionSuffix
-/// once we start setting the `DemangledNameInfo::SuffixRange`
-/// from inside the `TrackingOutputBuffer`.
+llvm::Expected
+CPlusPlusLanguage::GetDemangledFunctionSuffix(llvm::StringRef demangled,
+ const DemangledNameInfo &info) {
+ if (!info.hasSuffix())
+return llvm::createStringError("Suffix range for '%s' is invalid.",
+ demangled.data());
+
+ return demangled.slice(info.SuffixRange.first, info.SuffixRange.second);
+}
+
static llvm::Expected
GetDemangledFunctionSuffix(const SymbolContext &sc) {
auto info_or_err = GetAndValidateInfo(sc);
@@ -407,11 +410,7 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- if (!info.hasSuffix())
-return llvm::createStringError("Suffix range for '%s' is invalid.",
- demangled_name.data());
-
- return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
+ return CPlusPlusLanguage::GetDemangledFunctionSuffix(demangled_name, info);
}
llvm::Expected
@@ -2424,7 +2423,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
return true;
}
case FormatEntity::Entry::Type::FunctionSuffix: {
-auto suffix_or_err = GetDemangledFunctionSuffix(sc);
+auto suffix_or_err = ::GetDemangledFunctionSuffix(sc);
if (!suffix_or_err) {
LLDB_
[Lldb-commits] [lldb] [lldb][Mangled] Move SuffixRange computation into TrackingOutputBuffer (PR #152483)
https://github.com/charles-zablit approved this pull request. https://github.com/llvm/llvm-project/pull/152483 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [LLVM] [LLDB] Emit and handle `lf_alias` nodes (PR #152484)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Walnut (Walnut356) Changes This patch causes LLVM to emit `lf_alias` nodes for typedefs, allowing typedefs to be represented in the type data stream. Typedef `S_UDT` nodes are still created for the symbol stream. This strictly generates additional information and points to that additional information when possible. This is important because local variable symbols store *type* indexes. Without this change, it is impossible for a local variable to convey its typedefed type to the debugger.Before (LLVM 20.1.8):Sample program
```cpp #include#include struct Point { float x = 0.0; float y = 0.0; }; typedef Point Coord; int main() { unsigned char uc = 0; uint8_t u8 = 1; Point p = Point{5, 10}; Coord c = Coord{15, 20}; std::cout << "Hello World!\n"; } ``` After:
Please use extra scrutiny when looking over the LLDB-related changes. I have a bit of experience working with `SymbolFileNativePDB` and `PdbAstBuilder`, but I'm not super familiar with clang's `QualType` and such. In particular, I'm using a default `CompilerDeclContext` for the typedef type because I wasn't sure what else to use. --- Full diff: https://github.com/llvm/llvm-project/pull/152484.diff 13 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp (+14) - (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp (+15) - (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h (+3) - (modified) llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def (+1-1) - (modified) llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h (+13) - (modified) llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h (+2) - (modified) llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (+4-9) - (modified) llvm/lib/DebugInfo/CodeView/RecordName.cpp (+5) - (modified) llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp (+6) - (modified) llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp (+7) - (modified) llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp (+12) - (modified) llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp (+5) - (modified) llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp (+7) ``diff diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index f01fba3c48ce9..db29c96b6194a 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -805,6 +805,20 @@ clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) { return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv); } + if (cvt.kind() == LF_ALIAS) { +AliasRecord ar; +llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ar)); + +auto underlying_type = ToCompilerType(GetOrCreateType(ar.UnderlyingType)); + +std::string name = std::string(DropNameScope(ar.Name)); + +CompilerType ct = underlying_type.CreateTypedef( +name.c_str(), CompilerDeclContext(), 0); + +return m_clang.GetQualType(ct.GetOpaqueQualType()); + } + return {}; } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index dcea33dd9f854..57a4c29a037e6 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -709,6 +709,15 @@ TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id, ct, lldb_private::Type::ResolveState::Full); } +TypeSP SymbolFileNativePDB::CreateAliasType(PdbTypeSymId type_id, +const AliasRecord &ar, +CompilerType ct) { + + return MakeType(toOpaqueUid(type_id), ct.GetTypeName(), llvm::expectedToOptional(ct.GetByteSize(nullptr)), nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, Declaration(), ct, + lldb_private::Type::ResolveState::Full); +} + TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) { if (type_id.index.isSimple()) return CreateSimpleType(type_id.index, ct); @@ -765,6 +774,12 @@ TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) { return CreateFunctionType(type_id, mfr, ct); } + if (cvt.kind() == LF_ALIAS) { +AliasRecord ar; +llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ar)); +return CreateAliasType(type_id, ar, ct); + } + return nullptr;
[Lldb-commits] [lldb] [llvm] [LLVM] [LLDB] Emit and handle `lf_alias` nodes (PR #152484)
llvmbot wrote: @llvm/pr-subscribers-platform-windows @llvm/pr-subscribers-debuginfo Author: Walnut (Walnut356) Changes This patch causes LLVM to emit `lf_alias` nodes for typedefs, allowing typedefs to be represented in the type data stream. Typedef `S_UDT` nodes are still created for the symbol stream. This strictly generates additional information and points to that additional information when possible. This is important because local variable symbols store *type* indexes. Without this change, it is impossible for a local variable to convey its typedefed type to the debugger.Before (LLVM 20.1.8):Sample program
```cpp #include#include struct Point { float x = 0.0; float y = 0.0; }; typedef Point Coord; int main() { unsigned char uc = 0; uint8_t u8 = 1; Point p = Point{5, 10}; Coord c = Coord{15, 20}; std::cout << "Hello World!\n"; } ``` After:
Please use extra scrutiny when looking over the LLDB-related changes. I have a bit of experience working with `SymbolFileNativePDB` and `PdbAstBuilder`, but I'm not super familiar with clang's `QualType` and such. In particular, I'm using a default `CompilerDeclContext` for the typedef type because I wasn't sure what else to use. --- Full diff: https://github.com/llvm/llvm-project/pull/152484.diff 13 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp (+14) - (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp (+15) - (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h (+3) - (modified) llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def (+1-1) - (modified) llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h (+13) - (modified) llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h (+2) - (modified) llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (+4-9) - (modified) llvm/lib/DebugInfo/CodeView/RecordName.cpp (+5) - (modified) llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp (+6) - (modified) llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp (+7) - (modified) llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp (+12) - (modified) llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp (+5) - (modified) llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp (+7) ``diff diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index f01fba3c48ce9..db29c96b6194a 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -805,6 +805,20 @@ clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) { return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv); } + if (cvt.kind() == LF_ALIAS) { +AliasRecord ar; +llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ar)); + +auto underlying_type = ToCompilerType(GetOrCreateType(ar.UnderlyingType)); + +std::string name = std::string(DropNameScope(ar.Name)); + +CompilerType ct = underlying_type.CreateTypedef( +name.c_str(), CompilerDeclContext(), 0); + +return m_clang.GetQualType(ct.GetOpaqueQualType()); + } + return {}; } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index dcea33dd9f854..57a4c29a037e6 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -709,6 +709,15 @@ TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id, ct, lldb_private::Type::ResolveState::Full); } +TypeSP SymbolFileNativePDB::CreateAliasType(PdbTypeSymId type_id, +const AliasRecord &ar, +CompilerType ct) { + + return MakeType(toOpaqueUid(type_id), ct.GetTypeName(), llvm::expectedToOptional(ct.GetByteSize(nullptr)), nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, Declaration(), ct, + lldb_private::Type::ResolveState::Full); +} + TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) { if (type_id.index.isSimple()) return CreateSimpleType(type_id.index, ct); @@ -765,6 +774,12 @@ TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) { return CreateFunctionType(type_id, mfr, ct); } + if (cvt.kind() == LF_ALIAS) { +AliasRecord ar; +llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ar)); +return CreateAliasType(t
[Lldb-commits] [lldb] [llvm] [LLVM] [LLDB] Emit and handle `lf_alias` nodes (PR #152484)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/152484 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [LLVM] [LLDB] Emit and handle `lf_alias` nodes (PR #152484)
https://github.com/Walnut356 edited https://github.com/llvm/llvm-project/pull/152484 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [LLVM] [LLDB] Emit and handle `lf_alias` nodes (PR #152484)
https://github.com/Walnut356 created
https://github.com/llvm/llvm-project/pull/152484
This patch causes LLVM to emit `lf_alias` nodes for typedefs, allowing typedefs
to be represented in the type data stream. Typedef `S_UDT` nodes are still
created for the symbol stream. This strictly generates additional information
and points to that additional information when possible.
This is important because local variable symbols store *type* indexes. Without
this change, it is impossible for a local variable to convey its typedefed type
to the debugger.
Sample program
```cpp
#include
#include
struct Point {
float x = 0.0;
float y = 0.0;
};
typedef Point Coord;
int main() {
unsigned char uc = 0;
uint8_t u8 = 1;
Point p = Point{5, 10};
Coord c = Coord{15, 20};
std::cout << "Hello World!\n";
}
```
Before (LLVM 20.1.8):
https://github.com/user-attachments/assets/cb9e9e7e-3ad0-4e3a-81c7-5edb4248d2db";
/>
After:
https://github.com/user-attachments/assets/d6035b33-ce5c-4b22-a6c0-aa38b2495fb3";
/>
Please use extra scrutiny when looking over the LLDB-related changes. I have a
bit of experience working with `SymbolFileNativePDB` and `PdbAstBuilder`, but
I'm not super familiar with clang's `QualType` and such. In particular, I'm
using a default `CompilerDeclContext` for the typedef type because I wasn't
sure what else to use.
>From a5e517684e1f9e588226a17cb53551f54472860e Mon Sep 17 00:00:00 2001
From: Walnut <[email protected]>
Date: Thu, 7 Aug 2025 05:25:14 -0500
Subject: [PATCH 1/2] add AliasRecord and emit it for type aliases
---
.../llvm/DebugInfo/CodeView/CodeViewTypes.def | 2 +-
llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h | 13 +
.../LogicalView/Readers/LVCodeViewVisitor.h | 2 ++
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 13 -
llvm/lib/DebugInfo/CodeView/RecordName.cpp | 5 +
llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp | 6 ++
llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp | 7 +++
.../LogicalView/Readers/LVCodeViewVisitor.cpp | 12
llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp | 5 +
llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp | 7 +++
10 files changed, 62 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
b/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
index a3eb80a4e..aa3beea75c75b 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
+++ b/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
@@ -53,6 +53,7 @@ TYPE_RECORD(LF_ENUM, 0x1507, Enum)
TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2)
TYPE_RECORD(LF_VFTABLE, 0x151d, VFTable)
TYPE_RECORD(LF_VTSHAPE, 0x000a, VFTableShape)
+TYPE_RECORD(LF_ALIAS, 0x150a, Alias)
TYPE_RECORD(LF_BITFIELD, 0x1205, BitField)
@@ -181,7 +182,6 @@ CV_TYPE(LF_MANAGED_ST, 0x140f)
CV_TYPE(LF_ST_MAX, 0x1500)
CV_TYPE(LF_TYPESERVER, 0x1501)
CV_TYPE(LF_DIMARRAY, 0x1508)
-CV_TYPE(LF_ALIAS, 0x150a)
CV_TYPE(LF_DEFARG, 0x150b)
CV_TYPE(LF_FRIENDFCN, 0x150c)
CV_TYPE(LF_NESTTYPEEX, 0x1512)
diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 5a84fac5f5903..0e739650bd089 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -952,6 +952,19 @@ class EndPrecompRecord : public TypeRecord {
uint32_t Signature = 0;
};
+// LF_ALIAS
+class AliasRecord : public TypeRecord {
+public:
+ AliasRecord() = default;
+ explicit AliasRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+ AliasRecord(TypeIndex UnderlyingType, StringRef Name)
+ : TypeRecord(TypeRecordKind::Alias), UnderlyingType(UnderlyingType),
Name(Name) {}
+
+ TypeIndex UnderlyingType;
+ StringRef Name;
+
+};
+
} // end namespace codeview
} // end namespace llvm
diff --git
a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
index eb6371e911be4..164ea990336e0 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
@@ -418,6 +418,8 @@ class LVLogicalVisitor final {
LVElement *Element);
Error visitKnownRecord(CVType &Record, EndPrecompRecord &EndPrecomp,
TypeIndex TI, LVElement *Element);
+ Error visitKnownRecord(CVType &Record, AliasRecord &Alias,
+ TypeIndex TI, LVElement *Element);
Error visitUnknownMember(CVMemberRecord &Record, TypeIndex TI);
Error visitKnownMember(CVMemberRecord &Record, BaseClassRecord &Base,
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index c5d6e40eb7c1e..29978c9e5270f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/li
[Lldb-commits] [lldb] [lldb][rpc] Fix build failures when building lldb-rpc-gen (PR #151603)
mstorsjo wrote: > > Right - I see. But why does this build configuration have to affect whether > > it should build lldb-rpc-gen or not? Is it because the clang in this build > > can't manage to process the lldb headers (which are built for the current > > host)? > > Right, "the clang in this build can't manage to process the lldb headers" > because they include the target c++ headers, which are not available yet on a > moment of executing the lldb-rpc-gen tool during the cross-toolchain build. Hmm, that's very odd. At the point when `lldb-rpc-gen` runs, it's supposed to try to parse the headers in the same way as the host compiler does, using the same C++ standard library as the host compiler does. Unless Clang is built with something like `CLANG_DEFAULT_CXX_STDLIB=libc++` though, or a default config file used for all targets, - which then also would apply when using the same Clang (libraries) for the host. > * the lldb-rpc-gen tool depends on the clang libs to scan the lldb headers, > but in our configuration Clang will use just-built libc++ and its header > files. We need to prepare the libc++ headers inside of the build tree before > using clang++/lldb-rpc-gen. Actually IMO the issue is the other way around; if the host build doesn't use libc++ headers, then the lldb-rpc-gen is supposed to parse headers in exactly the same way as the host build as well, not waiting for some target runtimes to be built. > in addition: > > * as far as I know, there is no way to properly configure the build > dependencies and run the lldb-rpc-gen tool after the `builtins` and > `runtimes` builds get ready. > * I know only one way to detect the cross toolchain build -- to compare > LLVM_HOST_TRIPLE and LLVM_DEFAULT_TARGET_TRIPLE, -- but it is not working for > some cases. That's maybe one indication, yes... But as far as I can see, this really boils down to something else; it's not so much about cross vs not cross, it's about "can the currently built clang libraries be used for host compilation/parsing" - and target specific defaults like `CLANG_DEFAULT_CXX_STDLIB=libc++` can be one of the factors that break that. Possibly many more as well. (The fact that your Clang build only supports targeting aarch64 might also factor in, but most of the Clang frontend doesn't require the LLVM backend, at least for parsing headers.) Specifically the case about cross compiling LLVM itself, is another factor though, because if we'd enable building `lldb-rpc-gen` like we do for all other build-time code generation tools, like `llvm-tblgen`, then we end up duplicating 75% of the whole clang build - which we probably don't want to do. > PS. Probably it is optimal to stop trying to detect all these known and > unknown situations and manage building over `option` with OFF by default (may > be except Darwin), but with consideration of the cross builds. Yes, I agree about that. https://github.com/llvm/llvm-project/pull/151603 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][Mangled] Move SuffixRange computation into TrackingOutputBuffer (PR #152483)
https://github.com/Michael137 updated
https://github.com/llvm/llvm-project/pull/152483
>From cdcb92a3012107dce4418de1c74c6142dc356a14 Mon Sep 17 00:00:00 2001
From: Michael Buch
Date: Thu, 7 Aug 2025 13:11:59 +0100
Subject: [PATCH 1/2] [lldb][Mangled] Move SuffixRange computation into
TrackingOutputBuffer
This way all the tracking is self-contained in `TrackingOutputBuffer`
and we can test the `SuffixRange` properly.
---
lldb/source/Core/DemangledNameInfo.cpp| 11
lldb/source/Core/Mangled.cpp | 3 ---
.../Language/CPlusPlus/CPlusPlusLanguage.cpp | 25 +--
.../Language/CPlusPlus/CPlusPlusLanguage.h| 4 +++
lldb/unittests/Core/MangledTest.cpp | 8 +++---
5 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/lldb/source/Core/DemangledNameInfo.cpp
b/lldb/source/Core/DemangledNameInfo.cpp
index 00227f02bbff8..4001e699f75c2 100644
--- a/lldb/source/Core/DemangledNameInfo.cpp
+++ b/lldb/source/Core/DemangledNameInfo.cpp
@@ -111,6 +111,11 @@ void TrackingOutputBuffer::finalizeEnd() {
if (NameInfo.ScopeRange.first > NameInfo.ScopeRange.second)
NameInfo.ScopeRange.second = NameInfo.ScopeRange.first;
NameInfo.BasenameRange.first = NameInfo.ScopeRange.second;
+
+ // We call anything past the FunctionEncoding is the suffix.
+ // In practice this would be nodes like `DotSuffix` that wrap
+ // a FunctionEncoding.
+ NameInfo.SuffixRange.first = getCurrentPosition();
}
ScopedOverride TrackingOutputBuffer::enterFunctionTypePrinting() {
@@ -138,6 +143,9 @@ void TrackingOutputBuffer::printLeft(const Node &N) {
default:
OutputBuffer::printLeft(N);
}
+
+ // Keeps updating suffix until we reach the end.
+ NameInfo.SuffixRange.second = getCurrentPosition();
}
void TrackingOutputBuffer::printRight(const Node &N) {
@@ -151,6 +159,9 @@ void TrackingOutputBuffer::printRight(const Node &N) {
default:
OutputBuffer::printRight(N);
}
+
+ // Keeps updating suffix until we reach the end.
+ NameInfo.SuffixRange.second = getCurrentPosition();
}
void TrackingOutputBuffer::printLeftImpl(const FunctionType &N) {
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 3663f430111c2..ce4db4e0daa8b 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -172,9 +172,6 @@ GetItaniumDemangledStr(const char *M) {
TrackingOutputBuffer OB(demangled_cstr, demangled_size);
demangled_cstr = ipd.finishDemangle(&OB);
-// TODO: we should set the SuffixRange inside the TrackingOutputBuffer.
-OB.NameInfo.SuffixRange.first = OB.NameInfo.QualifiersRange.second;
-OB.NameInfo.SuffixRange.second = std::string_view(OB).size();
info = std::move(OB.NameInfo);
assert(demangled_cstr &&
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 3bc870810dc81..3118ff151d1cf 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -392,13 +392,16 @@ GetDemangledScope(const SymbolContext &sc) {
return CPlusPlusLanguage::GetDemangledScope(demangled_name, info);
}
-/// Handles anything printed after the FunctionEncoding ItaniumDemangle
-/// node. Most notably the DotSuffix node.
-///
-/// FIXME: the suffix should also have an associated
-/// CPlusPlusLanguage::GetDemangledFunctionSuffix
-/// once we start setting the `DemangledNameInfo::SuffixRange`
-/// from inside the `TrackingOutputBuffer`.
+llvm::Expected
+CPlusPlusLanguage::GetDemangledFunctionSuffix(llvm::StringRef demangled,
+ const DemangledNameInfo &info) {
+ if (!info.hasSuffix())
+return llvm::createStringError("Suffix range for '%s' is invalid.",
+ demangled.data());
+
+ return demangled.slice(info.SuffixRange.first, info.SuffixRange.second);
+}
+
static llvm::Expected
GetDemangledFunctionSuffix(const SymbolContext &sc) {
auto info_or_err = GetAndValidateInfo(sc);
@@ -407,11 +410,7 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- if (!info.hasSuffix())
-return llvm::createStringError("Suffix range for '%s' is invalid.",
- demangled_name.data());
-
- return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
+ return CPlusPlusLanguage::GetDemangledFunctionSuffix(demangled_name, info);
}
llvm::Expected
@@ -2424,7 +2423,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
return true;
}
case FormatEntity::Entry::Type::FunctionSuffix: {
-auto suffix_or_err = GetDemangledFunctionSuffix(sc);
+auto suffix_or_err = ::GetDemangledFunctionSuffix(sc);
if (!suffix_or_err) {
LLDB_LOG_ERROR(
GetLog(LLDBLog::Language), suffix_or_err.takeError(),
diff --git a/lldb/source/Plugins/Lan
[Lldb-commits] [lldb] [LLDB][NativePDB] Find functions by basename (PR #152295)
@@ -1677,34 +1766,56 @@ void SymbolFileNativePDB::FindFunctions(
if (name_type_mask & eFunctionNameTypeFull)
name = lookup_info.GetName();
- // For now we only support lookup by method name or full name.
if (!(name_type_mask & eFunctionNameTypeFull ||
+name_type_mask & eFunctionNameTypeBase ||
name_type_mask & eFunctionNameTypeMethod))
return;
+ CacheFunctionNames();
- using SymbolAndOffset = std::pair;
+ std::set resolved_ids; // avoid duplicate lookups
+ auto resolve_from = [&](UniqueCStringMap &Names) {
+std::vector ids;
+if (!Names.GetValues(name, ids))
+ return;
- std::vector matches = m_index->globals().findRecordsByName(
- name.GetStringRef(), m_index->symrecords());
- for (const SymbolAndOffset &match : matches) {
-if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF)
- continue;
-ProcRefSym proc(match.second.kind());
-cantFail(SymbolDeserializer::deserializeAs(match.second,
proc));
+for (uint32_t id : ids) {
+ if (resolved_ids.find(id) != resolved_ids.end())
+continue;
Michael137 wrote:
could do
```suggestion
if (!resolved_ids.insert(id))
continue;
```
Then don't need the insert at the end of the loop. Of course that means we
won't retry resolving an ID if it failed the first time. But don't think
anything would change in between invocations of this lambda for the ID to
suddently become resolved if it failed the first time?
https://github.com/llvm/llvm-project/pull/152295
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 229d860 - [NFC][lldb] Speed up lookup of shared modules (#152054)
Author: Augusto Noronha
Date: 2025-08-07T11:12:38-07:00
New Revision: 229d86026fa0e5d9412a0d5004532f0d9733aac6
URL:
https://github.com/llvm/llvm-project/commit/229d86026fa0e5d9412a0d5004532f0d9733aac6
DIFF:
https://github.com/llvm/llvm-project/commit/229d86026fa0e5d9412a0d5004532f0d9733aac6.diff
LOG: [NFC][lldb] Speed up lookup of shared modules (#152054)
By profiling LLDB debugging a Swift application without a dSYM and a
large amount of .o files, I identified that querying shared modules was
the biggest bottleneck when running "frame variable", and Clang types
need to be searched.
One of the reasons for that slowness is that the shared module list can
grow very large, and the search through it is O(n).
To solve this issue, this patch adds a new hashmap to the shared module
list whose key is the name of the module, and the value is all the
modules that share that name. This should speed up any search where the
query contains the module name.
rdar://156753350
Added:
Modified:
lldb/source/Core/ModuleList.cpp
Removed:
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index d5ddc2b249e56..34caa474c1e32 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -755,11 +755,240 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
+/// A wrapper around ModuleList for shared modules. Provides fast lookups for
+/// file-based ModuleSpec queries.
+class SharedModuleList {
+public:
+ /// Finds all the modules matching the module_spec, and adds them to \p
+ /// matching_module_list.
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+std::lock_guard guard(GetMutex());
+// Try map first for performance - if found, skip expensive full list
+// search
+if (FindModulesInMap(module_spec, matching_module_list))
+ return;
+m_list.FindModules(module_spec, matching_module_list);
+// Assert that modules were found in the list but not the map, it's
+// because the module_spec has no filename or the found module has a
+//
diff erent filename. For example, when searching by UUID and finding a
+// module with an alias.
+assert((matching_module_list.IsEmpty() ||
+module_spec.GetFileSpec().GetFilename().IsEmpty() ||
+module_spec.GetFileSpec().GetFilename() !=
+matching_module_list.GetModuleAtIndex(0)
+->GetFileSpec()
+.GetFilename()) &&
+ "Search by name not found in SharedModuleList's map");
+ }
+
+ ModuleSP FindModule(const Module *module_ptr) {
+if (!module_ptr)
+ return ModuleSP();
+
+std::lock_guard guard(GetMutex());
+if (ModuleSP result = FindModuleInMap(module_ptr))
+ return result;
+return m_list.FindModule(module_ptr);
+ }
+
+ // UUID searches bypass map since UUIDs aren't indexed by filename.
+ ModuleSP FindModule(const UUID &uuid) const {
+return m_list.FindModule(uuid);
+ }
+
+ void Append(const ModuleSP &module_sp, bool use_notifier) {
+if (!module_sp)
+ return;
+std::lock_guard guard(GetMutex());
+m_list.Append(module_sp, use_notifier);
+AddToMap(module_sp);
+ }
+
+ size_t RemoveOrphans(bool mandatory) {
+std::unique_lock lock(GetMutex(), std::defer_lock);
+if (mandatory) {
+ lock.lock();
+} else {
+ if (!lock.try_lock())
+return 0;
+}
+size_t total_count = 0;
+size_t run_count;
+do {
+ // Remove indexed orphans first, then remove non-indexed orphans. This
+ // order is important because the shared count will be
diff erent if a
+ // module is indexed or not.
+ run_count = RemoveOrphansFromMapAndList();
+ run_count += m_list.RemoveOrphans(mandatory);
+ total_count += run_count;
+ // Because removing orphans might make new orphans, remove from both
+ // containers until a fixed-point is reached.
+} while (run_count != 0);
+
+return total_count;
+ }
+
+ bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
+if (!module_sp)
+ return false;
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_sp.get());
+return m_list.Remove(module_sp, use_notifier);
+ }
+
+ void ReplaceEquivalent(const ModuleSP &module_sp,
+ llvm::SmallVectorImpl *old_modules) {
+std::lock_guard guard(GetMutex());
+m_list.ReplaceEquivalent(module_sp, old_modules);
+ReplaceEquivalentInMap(module_sp);
+ }
+
+ bool RemoveIfOrphaned(const Module *module_ptr) {
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_ptr, /*if_orphaned =*/true);
+return m_list.RemoveIfOrphaned(module_ptr);
+ }
+
+ std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); }
+
+private:
+ ModuleSP FindModuleInMap(const Modul
[Lldb-commits] [lldb] [lldb] Propagate ExpressionErrors from ValueObjectPrinter::GetDescriptionForDisplay (PR #152417)
jimingham wrote: Our experience is that people think `po` is the way to show them values, and so they will ALWAYS want to see the value regardless of where it comes from. https://github.com/llvm/llvm-project/pull/152417 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] refactor PlatformAndroid and make threadsafe (PR #145382)
https://github.com/cs01 edited https://github.com/llvm/llvm-project/pull/145382 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] refactor PlatformAndroid (PR #145382)
cs01 wrote: Friendly ping @labath https://github.com/llvm/llvm-project/pull/145382 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [NFC][lldb] Speed up lookup of shared modules (PR #152054)
@@ -755,11 +755,240 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
+/// A wrapper around ModuleList for shared modules. Provides fast lookups for
+/// file-based ModuleSpec queries.
+class SharedModuleList {
+public:
+ /// Finds all the modules matching the module_spec, and adds them to \p
+ /// matching_module_list.
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+std::lock_guard guard(GetMutex());
+// Try map first for performance - if found, skip expensive full list
+// search
+if (FindModulesInMap(module_spec, matching_module_list))
+ return;
+m_list.FindModules(module_spec, matching_module_list);
+// Assert that modules were found in the list but not the map, it's
+// because the module_spec has no filename or the found module has a
+// different filename. For example, when searching by UUID and finding a
+// module with an alias.
+assert((matching_module_list.IsEmpty() ||
+module_spec.GetFileSpec().GetFilename().IsEmpty() ||
+module_spec.GetFileSpec().GetFilename() !=
+matching_module_list.GetModuleAtIndex(0)
+->GetFileSpec()
+.GetFilename()) &&
+ "Search by name not found in SharedModuleList's map");
+ }
+
+ ModuleSP FindModule(const Module *module_ptr) {
+if (!module_ptr)
+ return ModuleSP();
+
+std::lock_guard guard(GetMutex());
+if (ModuleSP result = FindModuleInMap(module_ptr))
+ return result;
+return m_list.FindModule(module_ptr);
+ }
+
+ // UUID searches bypass map since UUIDs aren't indexed by filename.
+ ModuleSP FindModule(const UUID &uuid) const {
+return m_list.FindModule(uuid);
+ }
+
+ void Append(const ModuleSP &module_sp, bool use_notifier) {
+if (!module_sp)
+ return;
+std::lock_guard guard(GetMutex());
+m_list.Append(module_sp, use_notifier);
+AddToMap(module_sp);
+ }
+
+ size_t RemoveOrphans(bool mandatory) {
+std::unique_lock lock(GetMutex(), std::defer_lock);
+if (mandatory) {
+ lock.lock();
+} else {
+ if (!lock.try_lock())
+return 0;
+}
+size_t total_count = 0;
+size_t run_count;
+do {
+ // Remove indexed orphans first, then remove non-indexed orphans. This
+ // order is important because the shared count will be different if a
+ // module is indexed or not.
+ run_count = RemoveOrphansFromMapAndList();
+ run_count += m_list.RemoveOrphans(mandatory);
+ total_count += run_count;
+ // Because removing orphans might make new orphans, remove from both
+ // containers until a fixed-point is reached.
+} while (run_count != 0);
+
+return total_count;
+ }
+
+ bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
+if (!module_sp)
+ return false;
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_sp.get());
+return m_list.Remove(module_sp, use_notifier);
+ }
+
+ void ReplaceEquivalent(const ModuleSP &module_sp,
+ llvm::SmallVectorImpl *old_modules) {
+std::lock_guard guard(GetMutex());
+m_list.ReplaceEquivalent(module_sp, old_modules);
+ReplaceEquivalentInMap(module_sp);
+ }
+
+ bool RemoveIfOrphaned(const Module *module_ptr) {
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_ptr, /*if_orphaned =*/true);
JDevlieghere wrote:
```suggestion
RemoveFromMap(module_ptr, /*if_orphaned=*/true);
```
https://github.com/llvm/llvm-project/pull/152054
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [NFC][lldb] Speed up lookup of shared modules (PR #152054)
@@ -755,11 +755,240 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
+/// A wrapper around ModuleList for shared modules. Provides fast lookups for
+/// file-based ModuleSpec queries.
+class SharedModuleList {
+public:
+ /// Finds all the modules matching the module_spec, and adds them to \p
+ /// matching_module_list.
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+std::lock_guard guard(GetMutex());
+// Try map first for performance - if found, skip expensive full list
+// search
+if (FindModulesInMap(module_spec, matching_module_list))
+ return;
+m_list.FindModules(module_spec, matching_module_list);
+// Assert that modules were found in the list but not the map, it's
+// because the module_spec has no filename or the found module has a
+// different filename. For example, when searching by UUID and finding a
+// module with an alias.
+assert((matching_module_list.IsEmpty() ||
+module_spec.GetFileSpec().GetFilename().IsEmpty() ||
+module_spec.GetFileSpec().GetFilename() !=
+matching_module_list.GetModuleAtIndex(0)
+->GetFileSpec()
+.GetFilename()) &&
+ "Search by name not found in SharedModuleList's map");
+ }
+
+ ModuleSP FindModule(const Module *module_ptr) {
+if (!module_ptr)
+ return ModuleSP();
+
+std::lock_guard guard(GetMutex());
+if (ModuleSP result = FindModuleInMap(module_ptr))
+ return result;
+return m_list.FindModule(module_ptr);
+ }
+
+ // UUID searches bypass map since UUIDs aren't indexed by filename.
+ ModuleSP FindModule(const UUID &uuid) const {
+return m_list.FindModule(uuid);
+ }
+
+ void Append(const ModuleSP &module_sp, bool use_notifier) {
+if (!module_sp)
+ return;
+std::lock_guard guard(GetMutex());
+m_list.Append(module_sp, use_notifier);
+AddToMap(module_sp);
+ }
+
+ size_t RemoveOrphans(bool mandatory) {
+std::unique_lock lock(GetMutex(), std::defer_lock);
+if (mandatory) {
+ lock.lock();
+} else {
+ if (!lock.try_lock())
+return 0;
+}
+size_t total_count = 0;
+size_t run_count;
+do {
+ // Remove indexed orphans first, then remove non-indexed orphans. This
+ // order is important because the shared count will be different if a
+ // module is indexed or not.
+ run_count = RemoveOrphansFromMapAndList();
+ run_count += m_list.RemoveOrphans(mandatory);
+ total_count += run_count;
+ // Because removing orphans might make new orphans, remove from both
+ // containers until a fixed-point is reached.
+} while (run_count != 0);
+
+return total_count;
+ }
+
+ bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
+if (!module_sp)
+ return false;
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_sp.get());
+return m_list.Remove(module_sp, use_notifier);
+ }
+
+ void ReplaceEquivalent(const ModuleSP &module_sp,
+ llvm::SmallVectorImpl *old_modules) {
+std::lock_guard guard(GetMutex());
+m_list.ReplaceEquivalent(module_sp, old_modules);
+ReplaceEquivalentInMap(module_sp);
+ }
+
+ bool RemoveIfOrphaned(const Module *module_ptr) {
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_ptr, /*if_orphaned =*/true);
+return m_list.RemoveIfOrphaned(module_ptr);
+ }
+
+ std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); }
+
+private:
+ ModuleSP FindModuleInMap(const Module *module_ptr) {
+if (!module_ptr->GetFileSpec().GetFilename())
+ return ModuleSP();
+ConstString name = module_ptr->GetFileSpec().GetFilename();
+auto it = m_name_to_modules.find(name);
+if (it == m_name_to_modules.end())
+ return ModuleSP();
+const llvm::SmallVectorImpl &vector = it->second;
+for (auto &module_sp : vector) {
+ if (module_sp.get() == module_ptr)
+return module_sp;
+}
+return ModuleSP();
+ }
+
+ bool FindModulesInMap(const ModuleSpec &module_spec,
+ModuleList &matching_module_list) const {
+auto it = m_name_to_modules.find(module_spec.GetFileSpec().GetFilename());
+if (it == m_name_to_modules.end())
+ return false;
+const llvm::SmallVectorImpl &vector = it->second;
+bool found = false;
+for (auto &module_sp : vector) {
+ if (module_sp->MatchesModuleSpec(module_spec)) {
+matching_module_list.Append(module_sp);
+found = true;
+ }
+}
+return found;
+ }
+
+ void AddToMap(const ModuleSP &module_sp) {
+ConstString name = module_sp->GetFileSpec().GetFilename();
+if (name.IsEmpty())
+ return;
+llvm::SmallVectorImpl &vec = m_name_to_modules[name];
+vec.push_back(module_sp);
JDevlieghere wrote:
```suggestion
m_name_to_
[Lldb-commits] [lldb] [LLDB] Run a few more PDB tests with native PDB as well (PR #152580)
https://github.com/JDevlieghere closed https://github.com/llvm/llvm-project/pull/152580 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Propagate ExpressionErrors from ValueObjectPrinter::GetDescriptionForDisplay (PR #152417)
kastiglione wrote: > That's changing this UI to NOT print the value if the `po` expression fails > for some reason. > > Is that your intent? it's my intent when the failure is a _compiler reason_ – which is to make a distinction that this is a more narrow change than "some reason". https://github.com/llvm/llvm-project/pull/152417 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] persistent assembly breakpoints (PR #148061)
eronnen wrote: @JDevlieghere Pinging in case you still would like to review :grimacing: https://github.com/llvm/llvm-project/pull/148061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Propagate ExpressionErrors from ValueObjectPrinter::GetDescriptionForDisplay (PR #152417)
@@ -150,6 +151,11 @@ llvm::Expected
ValueObjectPrinter::GetDescriptionForDisplay() {
if (maybe_str)
return maybe_str;
+ if (maybe_str.errorIsA())
+// Propagate expression errors to expose diagnostics to the user.
+// Without this early exit, the summary/value may be shown without errors.
+return maybe_str;
+
kastiglione wrote:
Unfortunately no
https://github.com/llvm/llvm-project/pull/152417
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Revert "[NFC][lldb] Speed up lookup of shared modules (#152054)" (PR #152582)
llvm-ci wrote:
LLVM Buildbot has detected a new failure on builder `lldb-aarch64-ubuntu`
running on `linaro-lldb-aarch64-ubuntu` while building `lldb` at step 6 "test".
Full details are available at:
https://lab.llvm.org/buildbot/#/builders/59/builds/22275
Here is the relevant piece of the build log for the reference
```
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: commands/log/invalid-args/TestInvalidArgsLog.py (189 of 2304)
PASS: lldb-api :: commands/platform/basic/TestPlatformCommand.py (190 of 2304)
PASS: lldb-api :: commands/memory/write/TestMemoryWrite.py (191 of 2304)
PASS: lldb-api :: commands/platform/basic/TestPlatformPython.py (192 of 2304)
PASS: lldb-api :: commands/platform/file/close/TestPlatformFileClose.py (193 of
2304)
PASS: lldb-api :: commands/platform/file/read/TestPlatformFileRead.py (194 of
2304)
PASS: lldb-api :: commands/memory/read/TestMemoryRead.py (195 of 2304)
UNSUPPORTED: lldb-api :: commands/platform/sdk/TestPlatformSDK.py (196 of 2304)
PASS: lldb-api :: commands/platform/connect/TestPlatformConnect.py (197 of 2304)
UNRESOLVED: lldb-api :: commands/gui/spawn-threads/TestGuiSpawnThreads.py (198
of 2304)
TEST 'lldb-api ::
commands/gui/spawn-threads/TestGuiSpawnThreads.py' FAILED
Script:
--
/usr/bin/python3.10
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/dotest.py
-u CXXFLAGS -u CFLAGS --env
LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --env
LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/include
--env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin
--arch aarch64 --build-dir
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex
--lldb-module-cache-dir
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api
--clang-module-cache-dir
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api
--executable /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/lldb
--compiler /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/clang
--dsymutil /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/dsymutil
--make /usr/bin/gmake --llvm-tools-dir
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --lldb-obj-root
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb --lldb-libs-dir
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --cmake-build-type
Release
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/commands/gui/spawn-threads
-p TestGuiSpawnThreads.py
--
Exit Code: 1
Command Output (stdout):
--
lldb version 22.0.0git (https://github.com/llvm/llvm-project.git revision
75cc77e55e12d39aed94702b0b1365e39713081e)
clang revision 75cc77e55e12d39aed94702b0b1365e39713081e
llvm revision 75cc77e55e12d39aed94702b0b1365e39713081e
Skipping the following test categories: ['libc++', 'msvcstl', 'dsym',
'gmodules', 'debugserver', 'objc']
--
Command Output (stderr):
--
FAIL: LLDB
(/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) ::
test_gui (TestGuiSpawnThreads.TestGuiSpawnThreadsTest)
==
ERROR: test_gui (TestGuiSpawnThreads.TestGuiSpawnThreadsTest)
--
Traceback (most recent call last):
File
"/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/decorators.py",
line 151, in wrapper
return func(*args, **kwargs)
File
"/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/commands/gui/spawn-threads/TestGuiSpawnThreads.py",
line 44, in test_gui
self.child.expect_exact(f"thread #{i + 2}: tid =")
File "/usr/local/lib/python3.10/dist-packages/pexpect/spawnbase.py", line
432, in expect_exact
return exp.expect_loop(timeout)
File "/usr/local/lib/python3.10/dist-packages/pexpect/expect.py", line 179,
in expect_loop
return self.eof(e)
File "/usr/local/lib/python3.10/dist-packages/pexpect/expect.py", line 122,
in eof
raise exc
pexpect.exceptions.EOF: End Of File (EOF). Exception style platform.
command: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/lldb
args: ['/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/lldb',
'--no-lldbinit', '--no-use-colors', '-O', 'settings clear --all', '-O',
'settings set symbols.enable-external-lookup false', '-O', 'settings set
target.inherit-tcc true', '-O', 'settings set target.disable-aslr false', '-O',
'settings set target.detach-on-error false', '-O', 'settings set
target.auto-apply-fixits false', '-O', 'settings set
plugin.process.gdb-remote.packet-timeout 60', '-O', 'settings set
symbols.clang-modules-cache-path
"/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-
[Lldb-commits] [lldb] [lldb] Only use PyConfig when LLDB_EMBED_PYTHON_HOME is enabled (PR #152588)
@@ -134,9 +115,30 @@ struct InitializePythonRAII {
PyImport_AppendInittab("_lldb", LLDBSwigPyInit);
}
+#if LLDB_EMBED_PYTHON_HOME
JDevlieghere wrote:
Part of it, yes, but you could avoid changing the order by splitting the
ifdef-ed code in two, which is slightly messier. I enabled
`LLDB_EMBED_PYTHON_HOME` on Darwin and there it doesn't matter. That would look
like this:
```
#if LLDB_EMBED_PYTHON_HOME
PyConfig config;
[...]
PyConfig_SetBytesString(&config, &config.home, g_python_home.c_str());
#endif
if (!Py_IsInitialized()) {
[...]
PyImport_AppendInittab("_lldb", LLDBSwigPyInit);
}
#if LLDB_EMBED_PYTHON_HOME
config.install_signal_handlers = 0;
Py_InitializeFromConfig(&config);
PyConfig_Clear(&config);
#else
Py_InitializeEx(/*install_sigs=*/0);
#endif
```
https://github.com/llvm/llvm-project/pull/152588
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 41b5880 - [LLDB] Run a few more PDB tests with native PDB as well (#152580)
Author: nerix
Date: 2025-08-07T13:44:32-07:00
New Revision: 41b5880c957320b1be68cdb642ba735fdd27bb7c
URL:
https://github.com/llvm/llvm-project/commit/41b5880c957320b1be68cdb642ba735fdd27bb7c
DIFF:
https://github.com/llvm/llvm-project/commit/41b5880c957320b1be68cdb642ba735fdd27bb7c.diff
LOG: [LLDB] Run a few more PDB tests with native PDB as well (#152580)
Some DIA PDB tests pass with the native plugin already, but didn't test
this. This adds test runs with the native plugin - no functional
changes.
In addition to the x86 calling convention test, there's also
https://github.com/llvm/llvm-project/blob/9f102a90042fd3757c207112cfe64ee10182ace5/lldb/test/Shell/SymbolFile/PDB/calling-conventions-arm.test,
but I can't test this.
Added:
Modified:
lldb/test/Shell/SymbolFile/PDB/ast-restore.test
lldb/test/Shell/SymbolFile/PDB/calling-conventions-x86.test
lldb/test/Shell/SymbolFile/PDB/vbases.test
Removed:
diff --git a/lldb/test/Shell/SymbolFile/PDB/ast-restore.test
b/lldb/test/Shell/SymbolFile/PDB/ast-restore.test
index a91364bbbee63..f127acda90d22 100644
--- a/lldb/test/Shell/SymbolFile/PDB/ast-restore.test
+++ b/lldb/test/Shell/SymbolFile/PDB/ast-restore.test
@@ -3,13 +3,19 @@ RUN: %build --compiler=msvc --nodefaultlib --output=%t.exe
%S/Inputs/AstRestoreT
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=ENUM %s
RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe |
FileCheck --check-prefix=ENUM %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=GLOBAL %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe |
FileCheck --check-prefix=GLOBAL %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=BASE %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe |
FileCheck --check-prefix=BASE %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=CLASS %s
RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe |
FileCheck --check-prefix=CLASS %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=INNER %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe |
FileCheck --check-prefix=INNER %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=TEMPLATE %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe |
FileCheck --check-prefix=TEMPLATE %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=FOO %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe |
FileCheck --check-prefix=FOO %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=MAIN %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe |
FileCheck --check-prefix=MAIN %s
ENUM: Module: {{.*}}
ENUM: namespace N0 {
diff --git a/lldb/test/Shell/SymbolFile/PDB/calling-conventions-x86.test
b/lldb/test/Shell/SymbolFile/PDB/calling-conventions-x86.test
index 065c8b69b06dd..ceb7ad18919da 100644
--- a/lldb/test/Shell/SymbolFile/PDB/calling-conventions-x86.test
+++ b/lldb/test/Shell/SymbolFile/PDB/calling-conventions-x86.test
@@ -1,8 +1,12 @@
REQUIRES: system-windows, lld, (target-x86 || target-x86_64)
-RUN: %build --compiler=clang-cl --arch=32 --nodefaultlib --output=%t.exe
%S/Inputs/CallingConventionsTest.cpp \
-RUN: && lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix
32BIT-CHECK %s
-RUN: %build --compiler=clang-cl --arch=64 --nodefaultlib --output=%t.exe
%S/Inputs/CallingConventionsTest.cpp \
-RUN: && lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix
64BIT-CHECK %s
+
+RUN: %build --compiler=clang-cl --arch=32 --nodefaultlib --output=%t-32.exe
%S/Inputs/CallingConventionsTest.cpp
+RUN: lldb-test symbols -dump-ast %t-32.exe | FileCheck --check-prefix
32BIT-CHECK %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t-32.exe |
FileCheck --check-prefix 32BIT-CHECK %s
+
+RUN: %build --compiler=clang-cl --arch=64 --nodefaultlib --output=%t-64.exe
%S/Inputs/CallingConventionsTest.cpp
+RUN: lldb-test symbols -dump-ast %t-64.exe | FileCheck --check-prefix
64BIT-CHECK %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t-64.exe |
FileCheck --check-prefix 64BIT-CHECK %s
64BIT-CHECK: Module: {{.*}}
64BIT-CHECK-DAG: int (*FuncCCallPtr)();
diff --git a/lldb/test/Shell/SymbolFile/PDB/vbases.test
b/lldb/test/Shell/SymbolFile/PDB/vbases.test
index b58e3edc3cc80..e5ab80b0205a4 100644
--- a/lldb/test/Shell/SymbolFile/PDB/vbases.test
+++ b/lldb/test/Shell/SymbolFile/PDB/vbases.test
@@ -1,6 +1,7 @@
REQUIRES: target-windows, lld
RUN: %build --compiler=clang-cl --output=%t.exe %S/Inputs/VBases.cpp
RUN: %lldb -b -s %S/Inputs/VBases.script -- %t.exe | FileCheck %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -b -s %S/Inputs/VBases.script --
%t.exe | FileCheck %s
CHECK: {
CHE
[Lldb-commits] [lldb] [NFC][lldb] Speed up lookup of shared modules (PR #152054)
@@ -755,11 +755,237 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
+/// A wrapper around ModuleList for shared modules. Provides fast lookups for
+/// file-based ModuleSpec queries.
+class SharedModuleList {
+public:
+ /// Finds all the modules matching the module_spec, and adds them to \p
+ /// matching_module_list.
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+std::lock_guard guard(GetMutex());
+// Try index first for performance - if found, skip expensive full list
+// search
+if (FindModulesInIndex(module_spec, matching_module_list))
+ return;
+m_list.FindModules(module_spec, matching_module_list);
+// Assertion validates that if we found modules in the list but not the
+// index, it's because the module_spec has no filename or the found module
+// has a different filename (e.g., when searching by UUID and finding a
+// module with an alias)
+assert((matching_module_list.IsEmpty() ||
+module_spec.GetFileSpec().GetFilename().IsEmpty() ||
+module_spec.GetFileSpec().GetFilename() !=
+matching_module_list.GetModuleAtIndex(0)
+->GetFileSpec()
+.GetFilename()) &&
+ "Search by name not found in SharedModuleList's index");
+ }
+
+ ModuleSP FindModule(const Module *module_ptr) {
+if (!module_ptr)
+ return ModuleSP();
+
+std::lock_guard guard(GetMutex());
+// Try index first, fallback to full list search
+if (ModuleSP result = FindModuleInIndex(module_ptr))
+ return result;
+return m_list.FindModule(module_ptr);
+ }
+
+ // UUID searches bypass index since UUIDs aren't indexed by filename
+ ModuleSP FindModule(const UUID &uuid) const {
+return m_list.FindModule(uuid);
+ }
+
+ void Append(const ModuleSP &module_sp, bool use_notifier) {
+if (!module_sp)
+ return;
+std::lock_guard guard(GetMutex());
+m_list.Append(module_sp, use_notifier);
+AddToIndex(module_sp);
+ }
+
+ size_t RemoveOrphans(bool mandatory) {
+std::unique_lock lock(GetMutex(), std::defer_lock);
+if (mandatory) {
+ lock.lock();
+} else {
+ // Skip orphan removal if mutex unavailable (non-blocking)
+ if (!lock.try_lock())
+return 0;
+}
+size_t total_count = 0;
+size_t run_count;
+do {
+ // Remove indexed orphans first, then remove non-indexed orphans. This
+ // order is important because the shared count will be different if a
+ // module if indexed or not.
+ run_count = RemoveOrphansFromIndexAndList();
+ run_count += m_list.RemoveOrphans(mandatory);
+ total_count += run_count;
+ // Because removing orphans might make new orphans, we must continuously
+ // remove from both until both operations fail to remove new orphans.
+} while (run_count != 0);
+
+return total_count;
+ }
+
+ bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
+if (!module_sp)
+ return false;
+std::lock_guard guard(GetMutex());
+RemoveFromIndex(module_sp.get());
+bool success = m_list.Remove(module_sp, use_notifier);
+return success;
+ }
+
+ void ReplaceEquivalent(const ModuleSP &module_sp,
+ llvm::SmallVectorImpl *old_modules) {
+std::lock_guard guard(GetMutex());
+m_list.ReplaceEquivalent(module_sp, old_modules);
+ReplaceEquivalentInIndex(module_sp);
+ }
+
+ bool RemoveIfOrphaned(const Module *module_ptr) {
+std::lock_guard guard(GetMutex());
+RemoveFromIndex(module_ptr, /*if_orphaned =*/true);
+bool result = m_list.RemoveIfOrphaned(module_ptr);
+return result;
+ }
+
+ std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); }
+
+private:
+ ModuleSP FindModuleInIndex(const Module *module_ptr) {
+if (!module_ptr->GetFileSpec().GetFilename())
+ return ModuleSP();
+ConstString name = module_ptr->GetFileSpec().GetFilename();
+auto it = m_index.find(name);
+if (it != m_index.end()) {
+ auto &vector = it->getSecond();
+ for (auto &module_sp : vector)
+if (module_sp.get() == module_ptr)
+ return module_sp;
+}
+return ModuleSP();
+ }
+
+ bool FindModulesInIndex(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+auto it = m_index.find(module_spec.GetFileSpec().GetFilename());
+if (it == m_index.end())
+ return false;
+auto vector = it->getSecond();
+bool found = false;
+for (auto &module_sp : vector) {
+ if (module_sp->MatchesModuleSpec(module_spec)) {
+matching_module_list.Append(module_sp);
+found = true;
+ }
+}
+return found;
+ }
+
+ void AddToIndex(const ModuleSP &module_sp) {
+auto name = module_sp->GetFileSpec().GetFilename();
+if (name.IsEmpty())
+ return;
+auto &vec = m
[Lldb-commits] [lldb] [NFC][lldb] Speed up lookup of shared modules (PR #152054)
https://github.com/felipepiovezan deleted https://github.com/llvm/llvm-project/pull/152054 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [NFC][lldb] Speed up lookup of shared modules (PR #152054)
@@ -755,11 +755,237 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
+/// A wrapper around ModuleList for shared modules. Provides fast lookups for
+/// file-based ModuleSpec queries.
+class SharedModuleList {
+public:
+ /// Finds all the modules matching the module_spec, and adds them to \p
+ /// matching_module_list.
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+std::lock_guard guard(GetMutex());
+// Try index first for performance - if found, skip expensive full list
+// search
+if (FindModulesInIndex(module_spec, matching_module_list))
+ return;
+m_list.FindModules(module_spec, matching_module_list);
+// Assertion validates that if we found modules in the list but not the
+// index, it's because the module_spec has no filename or the found module
+// has a different filename (e.g., when searching by UUID and finding a
+// module with an alias)
+assert((matching_module_list.IsEmpty() ||
+module_spec.GetFileSpec().GetFilename().IsEmpty() ||
+module_spec.GetFileSpec().GetFilename() !=
+matching_module_list.GetModuleAtIndex(0)
+->GetFileSpec()
+.GetFilename()) &&
+ "Search by name not found in SharedModuleList's index");
+ }
+
+ ModuleSP FindModule(const Module *module_ptr) {
+if (!module_ptr)
+ return ModuleSP();
+
+std::lock_guard guard(GetMutex());
+// Try index first, fallback to full list search
+if (ModuleSP result = FindModuleInIndex(module_ptr))
+ return result;
+return m_list.FindModule(module_ptr);
+ }
+
+ // UUID searches bypass index since UUIDs aren't indexed by filename
+ ModuleSP FindModule(const UUID &uuid) const {
+return m_list.FindModule(uuid);
+ }
+
+ void Append(const ModuleSP &module_sp, bool use_notifier) {
+if (!module_sp)
+ return;
+std::lock_guard guard(GetMutex());
+m_list.Append(module_sp, use_notifier);
+AddToIndex(module_sp);
+ }
+
+ size_t RemoveOrphans(bool mandatory) {
+std::unique_lock lock(GetMutex(), std::defer_lock);
+if (mandatory) {
+ lock.lock();
+} else {
+ // Skip orphan removal if mutex unavailable (non-blocking)
+ if (!lock.try_lock())
+return 0;
+}
+size_t total_count = 0;
+size_t run_count;
+do {
+ // Remove indexed orphans first, then remove non-indexed orphans. This
+ // order is important because the shared count will be different if a
+ // module if indexed or not.
+ run_count = RemoveOrphansFromIndexAndList();
+ run_count += m_list.RemoveOrphans(mandatory);
+ total_count += run_count;
+ // Because removing orphans might make new orphans, we must continuously
+ // remove from both until both operations fail to remove new orphans.
+} while (run_count != 0);
+
+return total_count;
+ }
+
+ bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
+if (!module_sp)
+ return false;
+std::lock_guard guard(GetMutex());
+RemoveFromIndex(module_sp.get());
+bool success = m_list.Remove(module_sp, use_notifier);
+return success;
+ }
+
+ void ReplaceEquivalent(const ModuleSP &module_sp,
+ llvm::SmallVectorImpl *old_modules) {
+std::lock_guard guard(GetMutex());
+m_list.ReplaceEquivalent(module_sp, old_modules);
+ReplaceEquivalentInIndex(module_sp);
+ }
+
+ bool RemoveIfOrphaned(const Module *module_ptr) {
+std::lock_guard guard(GetMutex());
+RemoveFromIndex(module_ptr, /*if_orphaned =*/true);
+bool result = m_list.RemoveIfOrphaned(module_ptr);
+return result;
+ }
+
+ std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); }
+
+private:
+ ModuleSP FindModuleInIndex(const Module *module_ptr) {
+if (!module_ptr->GetFileSpec().GetFilename())
+ return ModuleSP();
+ConstString name = module_ptr->GetFileSpec().GetFilename();
+auto it = m_index.find(name);
+if (it != m_index.end()) {
+ auto &vector = it->getSecond();
+ for (auto &module_sp : vector)
+if (module_sp.get() == module_ptr)
+ return module_sp;
+}
+return ModuleSP();
+ }
+
+ bool FindModulesInIndex(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+auto it = m_index.find(module_spec.GetFileSpec().GetFilename());
+if (it == m_index.end())
+ return false;
+auto vector = it->getSecond();
+bool found = false;
+for (auto &module_sp : vector) {
+ if (module_sp->MatchesModuleSpec(module_spec)) {
+matching_module_list.Append(module_sp);
+found = true;
+ }
+}
+return found;
+ }
+
+ void AddToIndex(const ModuleSP &module_sp) {
+auto name = module_sp->GetFileSpec().GetFilename();
+if (name.IsEmpty())
+ return;
+auto &vec = m
[Lldb-commits] [lldb] [lldb] Support the Python stable C API in PythonString::AsUTF8 (PR #152599)
https://github.com/bulbazord approved this pull request. ConstString? ugh. https://github.com/llvm/llvm-project/pull/152599 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix race condition in Process::WaitForProcessToStop() (PR #144919)
jimingham wrote: You can easily unwind when you're done looking at a crashed expression with `thread return -x` - there is probably an SB API way to do that as well but I don't remember it off the top of my head. So you could support the `UnwindOnError(False)` pretty easily by doing that after successfully stopping in the expression. https://github.com/llvm/llvm-project/pull/144919 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reland "[NFC][lldb] Speed up lookup of shared modules" (229d860) (PR #152607)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: Augusto Noronha (augusto2112)
Changes
The previous commit was reverted because it broke a test on the bots.
Original commit message:
By profiling LLDB debugging a Swift application without a dSYM and a large
amount of .o files, I identified that querying shared modules was the biggest
bottleneck when running "frame variable", and Clang types need to be searched.
One of the reasons for that slowness is that the shared module list can can
grow very large, and the search through it is O(n).
To solve this issue, this patch adds a new hashmap to the shared module list
whose key is the name of the module, and the value is all the modules that
share that name. This should speed up any search where the query contains the
module name.
rdar://156753350
---
Full diff: https://github.com/llvm/llvm-project/pull/152607.diff
1 Files Affected:
- (modified) lldb/source/Core/ModuleList.cpp (+229)
``diff
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index d5ddc2b249e56..bb732a28eddc9 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -755,6 +755,235 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
+/// A wrapper around ModuleList for shared modules. Provides fast lookups for
+/// file-based ModuleSpec queries.
+class SharedModuleList {
+public:
+ /// Finds all the modules matching the module_spec, and adds them to \p
+ /// matching_module_list.
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+std::lock_guard guard(GetMutex());
+// Try map first for performance - if found, skip expensive full list
+// search.
+if (FindModulesInMap(module_spec, matching_module_list))
+ return;
+m_list.FindModules(module_spec, matching_module_list);
+// Assert that modules were found in the list but not the map, it's
+// because the module_spec has no filename or the found module has a
+// different filename. For example, when searching by UUID and finding a
+// module with an alias.
+assert((matching_module_list.IsEmpty() ||
+module_spec.GetFileSpec().GetFilename().IsEmpty() ||
+module_spec.GetFileSpec().GetFilename() !=
+matching_module_list.GetModuleAtIndex(0)
+->GetFileSpec()
+.GetFilename()) &&
+ "Search by name not found in SharedModuleList's map");
+ }
+
+ ModuleSP FindModule(const Module *module_ptr) {
+if (!module_ptr)
+ return ModuleSP();
+
+std::lock_guard guard(GetMutex());
+if (ModuleSP result = FindModuleInMap(module_ptr))
+ return result;
+return m_list.FindModule(module_ptr);
+ }
+
+ // UUID searches bypass map since UUIDs aren't indexed by filename.
+ ModuleSP FindModule(const UUID &uuid) const {
+return m_list.FindModule(uuid);
+ }
+
+ void Append(const ModuleSP &module_sp, bool use_notifier) {
+if (!module_sp)
+ return;
+std::lock_guard guard(GetMutex());
+m_list.Append(module_sp, use_notifier);
+AddToMap(module_sp);
+ }
+
+ size_t RemoveOrphans(bool mandatory) {
+std::unique_lock lock(GetMutex(), std::defer_lock);
+if (mandatory) {
+ lock.lock();
+} else {
+ if (!lock.try_lock())
+return 0;
+}
+size_t total_count = 0;
+size_t run_count;
+do {
+ // Remove indexed orphans first, then remove non-indexed orphans. This
+ // order is important because the shared count will be different if a
+ // module is indexed or not.
+ run_count = RemoveOrphansFromMapAndList();
+ run_count += m_list.RemoveOrphans(mandatory);
+ total_count += run_count;
+ // Because removing orphans might make new orphans, remove from both
+ // containers until a fixed-point is reached.
+} while (run_count != 0);
+
+return total_count;
+ }
+
+ bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
+if (!module_sp)
+ return false;
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_sp.get());
+return m_list.Remove(module_sp, use_notifier);
+ }
+
+ void ReplaceEquivalent(const ModuleSP &module_sp,
+ llvm::SmallVectorImpl *old_modules) {
+std::lock_guard guard(GetMutex());
+m_list.ReplaceEquivalent(module_sp, old_modules);
+ReplaceEquivalentInMap(module_sp);
+ }
+
+ bool RemoveIfOrphaned(const Module *module_ptr) {
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_ptr, /*if_orphaned=*/true);
+return m_list.RemoveIfOrphaned(module_ptr);
+ }
+
+ std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); }
+
+private:
+ ModuleSP FindModuleInMap(const Module *module_ptr) const {
+if (!module_ptr->GetFileSpec().GetFilename())
+ return ModuleSP();
+ConstString name = module_ptr->GetFileSpec().GetFilename();
+
[Lldb-commits] [lldb] Reland "[NFC][lldb] Speed up lookup of shared modules" (229d860) (PR #152607)
https://github.com/augusto2112 created
https://github.com/llvm/llvm-project/pull/152607
The previous commit was reverted because it broke a test on the bots.
Original commit message:
By profiling LLDB debugging a Swift application without a dSYM and a large
amount of .o files, I identified that querying shared modules was the biggest
bottleneck when running "frame variable", and Clang types need to be searched.
One of the reasons for that slowness is that the shared module list can can
grow very large, and the search through it is O(n).
To solve this issue, this patch adds a new hashmap to the shared module list
whose key is the name of the module, and the value is all the modules that
share that name. This should speed up any search where the query contains the
module name.
rdar://156753350
>From cf8f7b8fca2d4910425fe39cddd997652b444d58 Mon Sep 17 00:00:00 2001
From: Augusto Noronha
Date: Thu, 7 Aug 2025 15:32:49 -0700
Subject: [PATCH] Reland "[NFC][lldb] Speed up lookup of shared modules"
(229d860)
Original commit message:
By profiling LLDB debugging a Swift application without a dSYM and a
large amount of .o files, I identified that querying shared modules was
the biggest bottleneck when running "frame variable", and Clang types
need to be searched.
One of the reasons for that slowness is that the shared module list can
can grow very large, and the search through it is O(n).
To solve this issue, this patch adds a new hashmap to the shared module
list whose key is the name of the module, and the value is all the
modules that share that name. This should speed up any search where the
query contains the module name.
rdar://156753350
---
lldb/source/Core/ModuleList.cpp | 229
1 file changed, 229 insertions(+)
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index d5ddc2b249e56..bb732a28eddc9 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -755,6 +755,235 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
+/// A wrapper around ModuleList for shared modules. Provides fast lookups for
+/// file-based ModuleSpec queries.
+class SharedModuleList {
+public:
+ /// Finds all the modules matching the module_spec, and adds them to \p
+ /// matching_module_list.
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+std::lock_guard guard(GetMutex());
+// Try map first for performance - if found, skip expensive full list
+// search.
+if (FindModulesInMap(module_spec, matching_module_list))
+ return;
+m_list.FindModules(module_spec, matching_module_list);
+// Assert that modules were found in the list but not the map, it's
+// because the module_spec has no filename or the found module has a
+// different filename. For example, when searching by UUID and finding a
+// module with an alias.
+assert((matching_module_list.IsEmpty() ||
+module_spec.GetFileSpec().GetFilename().IsEmpty() ||
+module_spec.GetFileSpec().GetFilename() !=
+matching_module_list.GetModuleAtIndex(0)
+->GetFileSpec()
+.GetFilename()) &&
+ "Search by name not found in SharedModuleList's map");
+ }
+
+ ModuleSP FindModule(const Module *module_ptr) {
+if (!module_ptr)
+ return ModuleSP();
+
+std::lock_guard guard(GetMutex());
+if (ModuleSP result = FindModuleInMap(module_ptr))
+ return result;
+return m_list.FindModule(module_ptr);
+ }
+
+ // UUID searches bypass map since UUIDs aren't indexed by filename.
+ ModuleSP FindModule(const UUID &uuid) const {
+return m_list.FindModule(uuid);
+ }
+
+ void Append(const ModuleSP &module_sp, bool use_notifier) {
+if (!module_sp)
+ return;
+std::lock_guard guard(GetMutex());
+m_list.Append(module_sp, use_notifier);
+AddToMap(module_sp);
+ }
+
+ size_t RemoveOrphans(bool mandatory) {
+std::unique_lock lock(GetMutex(), std::defer_lock);
+if (mandatory) {
+ lock.lock();
+} else {
+ if (!lock.try_lock())
+return 0;
+}
+size_t total_count = 0;
+size_t run_count;
+do {
+ // Remove indexed orphans first, then remove non-indexed orphans. This
+ // order is important because the shared count will be different if a
+ // module is indexed or not.
+ run_count = RemoveOrphansFromMapAndList();
+ run_count += m_list.RemoveOrphans(mandatory);
+ total_count += run_count;
+ // Because removing orphans might make new orphans, remove from both
+ // containers until a fixed-point is reached.
+} while (run_count != 0);
+
+return total_count;
+ }
+
+ bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
+if (!module_sp)
+ return false;
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_sp.get());
[Lldb-commits] [lldb] Reland "[NFC][lldb] Speed up lookup of shared modules" (229d860) (PR #152607)
augusto2112 wrote: @JDevlieghere I addresses the comments you left on https://github.com/llvm/llvm-project/pull/152054 https://github.com/llvm/llvm-project/pull/152607 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Propagate ExpressionErrors from ValueObjectPrinter::GetDescriptionForDisplay (PR #152417)
kastiglione wrote: The ultimate intent is to show errors preventing an expected successful object description. If producing an object description fails, printing an object's address (value) is not what users expect. We can change this to print the error and the value, but I don't expect any users to find any use from the value/address when their intended `po` has failed. https://github.com/llvm/llvm-project/pull/152417 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix race condition in Process::WaitForProcessToStop() (PR #144919)
athierry-oct wrote:
Sounds good, thank you!
In the test, it seems the intention was originally to set UnwindOnError to
true, but it's still set to false when evaluating the expression (there's no
call to `options.SetUnwindOnError(False)` after the comment that says "now set
UnwindOnError to true"):
TestCallThatRestarts.py
```python
options.SetUnwindOnError(False)
[...]
# Okay, now set UnwindOnError to true, and then make the signal behavior to stop
# and see that now we do stop at the signal point:
self.runCmd("process handle SIGCHLD -s 1 -p 1 -n 1")
value = frame.EvaluateExpression("call_me (%d)" % (num_sigchld), options)
self.assertTrue(value.IsValid())
self.assertFalse(value.GetError().Success())
# Set signal handling back to no-stop, and continue and we should end
# up back in out starting frame:
self.runCmd("process handle SIGCHLD -s 0 -p 1 -n 1")
error = process.Continue()
self.assertSuccess(error, "Continuing after stopping for signal succeeds.")
frame = self.thread.GetFrameAtIndex(0)
self.assertEqual(
frame.GetPC(),
self.orig_frame_pc,
"Continuing returned to the place we started.",
)
```
Do you prefer:
- keeping UnwindOnError set to false and having the test consume the stop event
- or setting UnwindOnError to true as the comment says, and adapt the rest of
the test (because after continuing, we won't stop at the same place as when
UnwindOnError is false, and the last assertion will fail) ?
https://github.com/llvm/llvm-project/pull/144919
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Propagate ExpressionErrors from ValueObjectPrinter::GetDescriptionForDisplay (PR #152417)
jimingham wrote: The way we've been doing the `po` implementations for a while now is: "If the object description succeeds, print the object description, otherwise print the value." This routine gets used here: llvm::Expected object_desc = (value_printed || summary_printed) ? GetMostSpecializedValue().GetObjectDescription() : GetDescriptionForDisplay(); So it's supposed to handle the case where we haven't yet printed any value or summary for the `po` result. By returning if you see an expression error, you're changing this UI to NOT print the value if the `po` expression fails for some reason. Is that your intent? https://github.com/llvm/llvm-project/pull/152417 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix auto advance PC in `EmulateInstructionARM64` if PC >= 4G (PR #151460)
igorkudrin wrote: > Seems like this is [tripping > up](https://ci.swift.org/view/all/job/llvm.org/view/LLDB/job/lldb-cmake-sanitized/2038/testReport/lldb-unit/Instruction___EmulatorTests_1/16/) > UBSan: Thanks for reporting, fixed in 11e1d46 https://github.com/llvm/llvm-project/pull/151460 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Only use PyConfig when LLDB_EMBED_PYTHON_HOME is enabled (PR #152588)
https://github.com/JDevlieghere created
https://github.com/llvm/llvm-project/pull/152588
PyConfig and friends are not part of the stable API. We could switch back to
Py_SetPythonHome, which has been deprecated, but still part of the stable API.
For now, limit the use of PyConfig to when LLDB_EMBED_PYTHON_HOME is enabled,
which essentially means Windows. Changing the order doesn't seem to matter.
>From b6a1c76c488fcea21920545f8bedfd22f2eed692 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere
Date: Thu, 7 Aug 2025 13:05:30 -0700
Subject: [PATCH] [lldb] Only use PyConfig when LLDB_EMBED_PYTHON_HOME is
enabled
PyConfig and friends are not part of the stable API. We could switch
back to Py_SetPythonHome, which has been deprecated, but still part of
the stable API. For now, limit the use of PyConfig to when
LLDB_EMBED_PYTHON_HOME is enabled, which essentially means Windows.
---
.../Python/ScriptInterpreterPython.cpp| 40 ++-
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git
a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 24d604f22a765..5b97fcb5acf58 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -92,25 +92,6 @@ namespace {
struct InitializePythonRAII {
public:
InitializePythonRAII() {
-PyConfig config;
-PyConfig_InitPythonConfig(&config);
-
-#if LLDB_EMBED_PYTHON_HOME
-static std::string g_python_home = []() -> std::string {
- if (llvm::sys::path::is_absolute(LLDB_PYTHON_HOME))
-return LLDB_PYTHON_HOME;
-
- FileSpec spec = HostInfo::GetShlibDir();
- if (!spec)
-return {};
- spec.AppendPathComponent(LLDB_PYTHON_HOME);
- return spec.GetPath();
-}();
-if (!g_python_home.empty()) {
- PyConfig_SetBytesString(&config, &config.home, g_python_home.c_str());
-}
-#endif
-
// The table of built-in modules can only be extended before Python is
// initialized.
if (!Py_IsInitialized()) {
@@ -134,9 +115,30 @@ struct InitializePythonRAII {
PyImport_AppendInittab("_lldb", LLDBSwigPyInit);
}
+#if LLDB_EMBED_PYTHON_HOME
+PyConfig config;
+PyConfig_InitPythonConfig(&config);
+
+static std::string g_python_home = []() -> std::string {
+ if (llvm::sys::path::is_absolute(LLDB_PYTHON_HOME))
+return LLDB_PYTHON_HOME;
+
+ FileSpec spec = HostInfo::GetShlibDir();
+ if (!spec)
+return {};
+ spec.AppendPathComponent(LLDB_PYTHON_HOME);
+ return spec.GetPath();
+}();
+if (!g_python_home.empty()) {
+ PyConfig_SetBytesString(&config, &config.home, g_python_home.c_str());
+}
+
config.install_signal_handlers = 0;
Py_InitializeFromConfig(&config);
PyConfig_Clear(&config);
+#else
+Py_InitializeEx(/*install_sigs=*/0);
+#endif
// The only case we should go further and acquire the GIL: it is unlocked.
PyGILState_STATE gil_state = PyGILState_Ensure();
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Only use PyConfig when LLDB_EMBED_PYTHON_HOME is enabled (PR #152588)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: Jonas Devlieghere (JDevlieghere)
Changes
PyConfig and friends are not part of the stable API. We could switch back to
Py_SetPythonHome, which has been deprecated, but still part of the stable API.
For now, limit the use of PyConfig to when LLDB_EMBED_PYTHON_HOME is enabled,
which essentially means Windows. Changing the order doesn't seem to matter.
---
Full diff: https://github.com/llvm/llvm-project/pull/152588.diff
1 Files Affected:
- (modified)
lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
(+21-19)
``diff
diff --git
a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 24d604f22a765..5b97fcb5acf58 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -92,25 +92,6 @@ namespace {
struct InitializePythonRAII {
public:
InitializePythonRAII() {
-PyConfig config;
-PyConfig_InitPythonConfig(&config);
-
-#if LLDB_EMBED_PYTHON_HOME
-static std::string g_python_home = []() -> std::string {
- if (llvm::sys::path::is_absolute(LLDB_PYTHON_HOME))
-return LLDB_PYTHON_HOME;
-
- FileSpec spec = HostInfo::GetShlibDir();
- if (!spec)
-return {};
- spec.AppendPathComponent(LLDB_PYTHON_HOME);
- return spec.GetPath();
-}();
-if (!g_python_home.empty()) {
- PyConfig_SetBytesString(&config, &config.home, g_python_home.c_str());
-}
-#endif
-
// The table of built-in modules can only be extended before Python is
// initialized.
if (!Py_IsInitialized()) {
@@ -134,9 +115,30 @@ struct InitializePythonRAII {
PyImport_AppendInittab("_lldb", LLDBSwigPyInit);
}
+#if LLDB_EMBED_PYTHON_HOME
+PyConfig config;
+PyConfig_InitPythonConfig(&config);
+
+static std::string g_python_home = []() -> std::string {
+ if (llvm::sys::path::is_absolute(LLDB_PYTHON_HOME))
+return LLDB_PYTHON_HOME;
+
+ FileSpec spec = HostInfo::GetShlibDir();
+ if (!spec)
+return {};
+ spec.AppendPathComponent(LLDB_PYTHON_HOME);
+ return spec.GetPath();
+}();
+if (!g_python_home.empty()) {
+ PyConfig_SetBytesString(&config, &config.home, g_python_home.c_str());
+}
+
config.install_signal_handlers = 0;
Py_InitializeFromConfig(&config);
PyConfig_Clear(&config);
+#else
+Py_InitializeEx(/*install_sigs=*/0);
+#endif
// The only case we should go further and acquire the GIL: it is unlocked.
PyGILState_STATE gil_state = PyGILState_Ensure();
``
https://github.com/llvm/llvm-project/pull/152588
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Only use PyConfig when LLDB_EMBED_PYTHON_HOME is enabled (PR #152588)
JDevlieghere wrote: Part of https://github.com/llvm/llvm-project/issues/151617 https://github.com/llvm/llvm-project/pull/152588 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Support the Python stable C API in PythonString::AsUTF8 (PR #152599)
https://github.com/JDevlieghere updated
https://github.com/llvm/llvm-project/pull/152599
>From 296b5377ae0e24e43d9de9e508e88f67011c1356 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere
Date: Thu, 7 Aug 2025 14:50:06 -0700
Subject: [PATCH 1/2] [lldb] Support the Python stable C API in
PythonString::AsUTF8
This conditionally reimplements PythonString::AsUTF8 using
PyUnicode_AsUTF8String instead of PyUnicode_AsUTF8AndSize.
PyUnicode_AsUTF8AndSize caches the UTF-8 representation of the string in
the Unicode object, which makes it more efficient and ties the lifetime
of the data to the Python string. However, it was only added to the
Stable API in Python 3.10. Older versions that want to use the Stable
API must use PyUnicode_AsUTF8String in combination with ConstString.
---
.../Python/PythonDataObjects.cpp | 28 +++
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 27ac54322165e..cf8c22ff230ec 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -405,15 +405,33 @@ Expected PythonString::AsUTF8() const {
if (!IsValid())
return nullDeref();
- Py_ssize_t size;
- const char *data;
+ // PyUnicode_AsUTF8AndSize caches the UTF-8 representation of the string in
+ // the Unicode object, which makes it more efficient and ties the lifetime of
+ // the data to the Python string. However, it was only added to the Stable
API
+ // in Python 3.10. Older versions that want to use the Stable API must use
+ // PyUnicode_AsUTF8String in combination with ConstString.
+#if defined(Py_LIMITED_API) && (Py_LIMITED_API < 0x030a)
+ PyObject *py_bytes = PyUnicode_AsUTF8String(m_py_obj);
+ if (!py_bytes)
+ return exception();
+ auto release_py_str =
+llvm::make_scope_exit([py_bytes] { Py_DECREF(py_bytes); });
+ Py_ssize_t size = PyBytes_Size(py_bytes);
+ const char *str = PyBytes_AsString(py_bytes);
+
+ if (!str)
+return exception();
- data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
+ return ConstString(str, size).GetStringRef();
+#else
+ Py_ssize_t size;
+ const char *str = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
- if (!data)
+ if (!str)
return exception();
- return llvm::StringRef(data, size);
+ return llvm::StringRef(str, size);
+#endif
}
size_t PythonString::GetSize() const {
>From 4303f603d64c4ff53eedc1f2cb7174f9c1c3b7eb Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere
Date: Thu, 7 Aug 2025 15:02:59 -0700
Subject: [PATCH 2/2] Formatting
---
.../Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp| 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index cf8c22ff230ec..a2a287a6714db 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -413,9 +413,9 @@ Expected PythonString::AsUTF8() const {
#if defined(Py_LIMITED_API) && (Py_LIMITED_API < 0x030a)
PyObject *py_bytes = PyUnicode_AsUTF8String(m_py_obj);
if (!py_bytes)
- return exception();
+return exception();
auto release_py_str =
-llvm::make_scope_exit([py_bytes] { Py_DECREF(py_bytes); });
+ llvm::make_scope_exit([py_bytes] { Py_DECREF(py_bytes); });
Py_ssize_t size = PyBytes_Size(py_bytes);
const char *str = PyBytes_AsString(py_bytes);
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add `ScalarLiteralNode` and literal parsing in DIL (PR #152308)
https://github.com/kuilpd updated
https://github.com/llvm/llvm-project/pull/152308
>From 55fbd4724159eea9868df1eeac9b83bf5894544b Mon Sep 17 00:00:00 2001
From: Ilia Kuklin
Date: Fri, 1 Aug 2025 20:14:59 +0500
Subject: [PATCH 1/4] Add ScalarLiteralNode
---
lldb/include/lldb/ValueObject/DILAST.h| 23 +
lldb/include/lldb/ValueObject/DILEval.h | 2 +
lldb/include/lldb/ValueObject/DILParser.h | 2 +
lldb/source/ValueObject/DILAST.cpp| 5 ++
lldb/source/ValueObject/DILEval.cpp | 28 +++
lldb/source/ValueObject/DILParser.cpp | 48 +++
.../TestFrameVarDILArraySubscript.py | 2 +-
.../Indirection/TestFrameVarDILIndirection.py | 2 +-
8 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILAST.h
b/lldb/include/lldb/ValueObject/DILAST.h
index 709f0639135f1..a174e28ea5c06 100644
--- a/lldb/include/lldb/ValueObject/DILAST.h
+++ b/lldb/include/lldb/ValueObject/DILAST.h
@@ -23,6 +23,7 @@ enum class NodeKind {
eErrorNode,
eIdentifierNode,
eMemberOfNode,
+ eScalarLiteralNode,
eUnaryOpNode,
};
@@ -178,6 +179,26 @@ class BitFieldExtractionNode : public ASTNode {
int64_t m_last_index;
};
+class ScalarLiteralNode : public ASTNode {
+public:
+ ScalarLiteralNode(uint32_t location, lldb::BasicType type, Scalar value)
+ : ASTNode(location, NodeKind::eScalarLiteralNode), m_type(type),
+m_value(value) {}
+
+ llvm::Expected Accept(Visitor *v) const override;
+
+ lldb::BasicType GetType() const { return m_type; }
+ Scalar GetValue() const & { return m_value; }
+
+ static bool classof(const ASTNode *node) {
+return node->GetKind() == NodeKind::eScalarLiteralNode;
+ }
+
+private:
+ lldb::BasicType m_type;
+ Scalar m_value;
+};
+
/// This class contains one Visit method for each specialized type of
/// DIL AST node. The Visit methods are used to dispatch a DIL AST node to
/// the correct function in the DIL expression evaluator for evaluating that
@@ -195,6 +216,8 @@ class Visitor {
Visit(const ArraySubscriptNode *node) = 0;
virtual llvm::Expected
Visit(const BitFieldExtractionNode *node) = 0;
+ virtual llvm::Expected
+ Visit(const ScalarLiteralNode *node) = 0;
};
} // namespace lldb_private::dil
diff --git a/lldb/include/lldb/ValueObject/DILEval.h
b/lldb/include/lldb/ValueObject/DILEval.h
index 45e29b3ddcd7b..cb2a81d1c7ba1 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -54,6 +54,8 @@ class Interpreter : Visitor {
Visit(const ArraySubscriptNode *node) override;
llvm::Expected
Visit(const BitFieldExtractionNode *node) override;
+ llvm::Expected
+ Visit(const ScalarLiteralNode *node) override;
// Used by the interpreter to create objects, perform casts, etc.
lldb::TargetSP m_target;
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index 9eda7bac4a364..2cd8ca3be3c02 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -96,6 +96,8 @@ class DILParser {
std::string ParseIdExpression();
std::string ParseUnqualifiedId();
std::optional ParseIntegerConstant();
+ ASTNodeUP ParseNumericLiteral();
+ ASTNodeUP ParseNumericConstant();
void BailOut(const std::string &error, uint32_t loc, uint16_t err_len);
diff --git a/lldb/source/ValueObject/DILAST.cpp
b/lldb/source/ValueObject/DILAST.cpp
index b1cd824c2299e..38215ae18f6ce 100644
--- a/lldb/source/ValueObject/DILAST.cpp
+++ b/lldb/source/ValueObject/DILAST.cpp
@@ -37,4 +37,9 @@ BitFieldExtractionNode::Accept(Visitor *v) const {
return v->Visit(this);
}
+llvm::Expected
+ScalarLiteralNode::Accept(Visitor *v) const {
+ return v->Visit(this);
+}
+
} // namespace lldb_private::dil
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 6f28434c646cd..18cc30d589829 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -7,7 +7,9 @@
//===--===//
#include "lldb/ValueObject/DILEval.h"
+#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
@@ -402,4 +404,30 @@ Interpreter::Visit(const BitFieldExtractionNode *node) {
return child_valobj_sp;
}
+static CompilerType GetBasicTypeFromCU(std::shared_ptr ctx,
+ lldb::BasicType basic_type) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ auto language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ auto type_system =
+ symbol_context.module_sp->GetTypeSystemForLanguage(language);
+
+
[Lldb-commits] [lldb] [LLDB][NativePDB] Resolve declaration for tag types (PR #152579)
https://github.com/Nerixyz created
https://github.com/llvm/llvm-project/pull/152579
Tag types like stucts or enums didn't have a declaration attached to them. The
source locations are present in the IPI stream in `LF_UDT_MOD_SRC_LINE` records:
```
0x101F | LF_UDT_MOD_SRC_LINE [size = 18, hash = 0x1C63]
udt = 0x1058, mod = 3, file = 1, line = 0
0x2789 | LF_UDT_MOD_SRC_LINE [size = 18, hash = 0x1E5A]
udt = 0x1253, mod = 35, file = 93, line = 17069
```
The file is an ID in the string table `/names`:
```
ID | String
1 | '\'
12 |
'D:\a\_work\1\s\src\ExternalAPIs\WindowsSDKInc\c\Include\10.0.22621.0\um\wingdi.h'
93 |
'D:\a\_work\1\s\src\ExternalAPIs\WindowsSDKInc\c\Include\10.0.22621.0\um\winnt.h'
```
Here, we're not interested in `mod`. This would indicate which module
contributed the UDT.
I was looking at Rustc's PDB and found that it uses `` for some types,
so I added a check for that.
This makes two DIA PDB shell tests to work with the native PDB plugin.
>From 004b3c9c1ef959edc6eb25b173a11f7b57a344b0 Mon Sep 17 00:00:00 2001
From: Nerixyz
Date: Thu, 7 Aug 2025 17:39:16 +0200
Subject: [PATCH] [LLDB][NativePDB] Resolve declaration for tag types
---
.../NativePDB/SymbolFileNativePDB.cpp | 57 ++-
.../NativePDB/SymbolFileNativePDB.h | 10
.../Shell/SymbolFile/PDB/class-layout.test| 12 +++-
.../Shell/SymbolFile/PDB/enums-layout.test| 6 ++
4 files changed, 81 insertions(+), 4 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index dcea33dd9f854..684d46d1da4e6 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -643,8 +643,7 @@ SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId
type_id,
std::string uname = GetUnqualifiedTypeName(record);
- // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE.
- Declaration decl;
+ Declaration decl = ResolveUdtDeclaration(type_id);
return MakeType(toOpaqueUid(type_id), ConstString(uname), size, nullptr,
LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
Type::ResolveState::Forward);
@@ -667,7 +666,7 @@ lldb::TypeSP
SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
CompilerType ct) {
std::string uname = GetUnqualifiedTypeName(er);
- Declaration decl;
+ Declaration decl = ResolveUdtDeclaration(type_id);
TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);
return MakeType(
@@ -2441,3 +2440,55 @@ SymbolFileNativePDB::GetContextForType(TypeIndex ti) {
}
return ctx;
}
+
+void SymbolFileNativePDB::CacheUdtDeclarations() {
+ if (m_has_cached_udt_declatations)
+return;
+ m_has_cached_udt_declatations = true;
+
+ for (CVType cvt : m_index->ipi().typeArray()) {
+if (cvt.kind() != LF_UDT_MOD_SRC_LINE)
+ continue;
+
+UdtModSourceLineRecord udt_mod_src;
+llvm::cantFail(TypeDeserializer::deserializeAs(cvt, udt_mod_src));
+// Some types might be contributed by multiple modules. We assume that they
+// all point to the same file and line because we can only provide one
+// location.
+m_udt_declarations.try_emplace(udt_mod_src.UDT,
+ udt_mod_src.SourceFile.getIndex(),
+ udt_mod_src.LineNumber);
+ }
+}
+
+Declaration SymbolFileNativePDB::ResolveUdtDeclaration(PdbTypeSymId type_id) {
+ CacheUdtDeclarations();
+ auto it = m_udt_declarations.find(type_id.index);
+ if (it == m_udt_declarations.end())
+return Declaration();
+
+ auto [file_index, line] = it->second;
+ auto string_table = m_index->pdb().getStringTable();
+ if (!string_table) {
+LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), string_table.takeError(),
+ "Failed to get string table: {0}");
+return Declaration();
+ }
+
+ llvm::Expected file_name =
+ string_table->getStringTable().getString(file_index);
+ if (!file_name) {
+LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), file_name.takeError(),
+ "Failed to get string with id {1}: {0}", file_index);
+return Declaration();
+ }
+
+ // rustc sets the filename to "" for some files
+ if (*file_name == "\\")
+return Declaration();
+
+ FileSpec::Style style = file_name->starts_with("/")
+ ? FileSpec::Style::posix
+ : FileSpec::Style::windows;
+ return Declaration(FileSpec(*file_name, style), line);
+}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index eda375d4cebe7..2e8270794af1a 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativeP
[Lldb-commits] [lldb] [LLDB][NativePDB] Resolve declaration for tag types (PR #152579)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: nerix (Nerixyz) Changes Tag types like stucts or enums didn't have a declaration attached to them. The source locations are present in the IPI stream in `LF_UDT_MOD_SRC_LINE` records: ``` 0x101F | LF_UDT_MOD_SRC_LINE [size = 18, hash = 0x1C63] udt = 0x1058, mod = 3, file = 1, line = 0 0x2789 | LF_UDT_MOD_SRC_LINE [size = 18, hash = 0x1E5A] udt = 0x1253, mod = 35, file = 93, line = 17069 ``` The file is an ID in the string table `/names`: ``` ID | String 1 | '\' 12 | 'D:\a\_work\1\s\src\ExternalAPIs\WindowsSDKInc\c\Include\10.0.22621.0\um\wingdi.h' 93 | 'D:\a\_work\1\s\src\ExternalAPIs\WindowsSDKInc\c\Include\10.0.22621.0\um\winnt.h' ``` Here, we're not interested in `mod`. This would indicate which module contributed the UDT. I was looking at Rustc's PDB and found that it uses ` ` for some types, so I added a check for that. This makes two DIA PDB shell tests to work with the native PDB plugin. --- Full diff: https://github.com/llvm/llvm-project/pull/152579.diff 4 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp (+54-3) - (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h (+10) - (modified) lldb/test/Shell/SymbolFile/PDB/class-layout.test (+11-1) - (modified) lldb/test/Shell/SymbolFile/PDB/enums-layout.test (+6) ``diff diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index dcea33dd9f854..684d46d1da4e6 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -643,8 +643,7 @@ SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id, std::string uname = GetUnqualifiedTypeName(record); - // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE. - Declaration decl; + Declaration decl = ResolveUdtDeclaration(type_id); return MakeType(toOpaqueUid(type_id), ConstString(uname), size, nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, Type::ResolveState::Forward); @@ -667,7 +666,7 @@ lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, CompilerType ct) { std::string uname = GetUnqualifiedTypeName(er); - Declaration decl; + Declaration decl = ResolveUdtDeclaration(type_id); TypeSP underlying_type = GetOrCreateType(er.UnderlyingType); return MakeType( @@ -2441,3 +2440,55 @@ SymbolFileNativePDB::GetContextForType(TypeIndex ti) { } return ctx; } + +void SymbolFileNativePDB::CacheUdtDeclarations() { + if (m_has_cached_udt_declatations) +return; + m_has_cached_udt_declatations = true; + + for (CVType cvt : m_index->ipi().typeArray()) { +if (cvt.kind() != LF_UDT_MOD_SRC_LINE) + continue; + +UdtModSourceLineRecord udt_mod_src; +llvm::cantFail(TypeDeserializer::deserializeAs(cvt, udt_mod_src)); +// Some types might be contributed by multiple modules. We assume that they +// all point to the same file and line because we can only provide one +// location. +m_udt_declarations.try_emplace(udt_mod_src.UDT, + udt_mod_src.SourceFile.getIndex(), + udt_mod_src.LineNumber); + } +} + +Declaration SymbolFileNativePDB::ResolveUdtDeclaration(PdbTypeSymId type_id) { + CacheUdtDeclarations(); + auto it = m_udt_declarations.find(type_id.index); + if (it == m_udt_declarations.end()) +return Declaration(); + + auto [file_index, line] = it->second; + auto string_table = m_index->pdb().getStringTable(); + if (!string_table) { +LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), string_table.takeError(), + "Failed to get string table: {0}"); +return Declaration(); + } + + llvm::Expected file_name = + string_table->getStringTable().getString(file_index); + if (!file_name) { +LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), file_name.takeError(), + "Failed to get string with id {1}: {0}", file_index); +return Declaration(); + } + + // rustc sets the filename to "" for some files + if (*file_name == "\\") +return Declaration(); + + FileSpec::Style style = file_name->starts_with("/") + ? FileSpec::Style::posix + : FileSpec::Style::windows; + return Declaration(FileSpec(*file_name, style), line); +} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index eda375d4cebe7..2e8270794af1a 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -260,6 +260,9 @@ class SymbolFileNativePDB : public
[Lldb-commits] [lldb] [LLDB] Run a few more PDB tests with native PDB as well (PR #152580)
https://github.com/JDevlieghere approved this pull request. LGTM. I wonder though if there's something better we can do here. IIUC, if you don't have DIA enabled, these tests will basically run the same test twice (both using the NativePDB reader). It would be nice if we could avoid that, and run the same test once (NativePDB) or twice (DIA + NativePDB) that doesn't involve duplicating all the lines. https://github.com/llvm/llvm-project/pull/152580 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Revert "[NFC][lldb] Speed up lookup of shared modules (#152054)" (PR #152582)
https://github.com/augusto2112 created
https://github.com/llvm/llvm-project/pull/152582
This reverts commit 229d86026fa0e5d9412a0d5004532f0d9733aac6.
>From 2c9d14251c8a5bd2354d2747d44b8bb7db30c3b1 Mon Sep 17 00:00:00 2001
From: Augusto Noronha
Date: Thu, 7 Aug 2025 12:44:40 -0700
Subject: [PATCH] Revert "[NFC][lldb] Speed up lookup of shared modules
(#152054)"
This reverts commit 229d86026fa0e5d9412a0d5004532f0d9733aac6.
---
lldb/source/Core/ModuleList.cpp | 242 +---
1 file changed, 7 insertions(+), 235 deletions(-)
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index 34caa474c1e32..d5ddc2b249e56 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -755,240 +755,11 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
-/// A wrapper around ModuleList for shared modules. Provides fast lookups for
-/// file-based ModuleSpec queries.
-class SharedModuleList {
-public:
- /// Finds all the modules matching the module_spec, and adds them to \p
- /// matching_module_list.
- void FindModules(const ModuleSpec &module_spec,
- ModuleList &matching_module_list) const {
-std::lock_guard guard(GetMutex());
-// Try map first for performance - if found, skip expensive full list
-// search
-if (FindModulesInMap(module_spec, matching_module_list))
- return;
-m_list.FindModules(module_spec, matching_module_list);
-// Assert that modules were found in the list but not the map, it's
-// because the module_spec has no filename or the found module has a
-// different filename. For example, when searching by UUID and finding a
-// module with an alias.
-assert((matching_module_list.IsEmpty() ||
-module_spec.GetFileSpec().GetFilename().IsEmpty() ||
-module_spec.GetFileSpec().GetFilename() !=
-matching_module_list.GetModuleAtIndex(0)
-->GetFileSpec()
-.GetFilename()) &&
- "Search by name not found in SharedModuleList's map");
- }
-
- ModuleSP FindModule(const Module *module_ptr) {
-if (!module_ptr)
- return ModuleSP();
-
-std::lock_guard guard(GetMutex());
-if (ModuleSP result = FindModuleInMap(module_ptr))
- return result;
-return m_list.FindModule(module_ptr);
- }
-
- // UUID searches bypass map since UUIDs aren't indexed by filename.
- ModuleSP FindModule(const UUID &uuid) const {
-return m_list.FindModule(uuid);
- }
-
- void Append(const ModuleSP &module_sp, bool use_notifier) {
-if (!module_sp)
- return;
-std::lock_guard guard(GetMutex());
-m_list.Append(module_sp, use_notifier);
-AddToMap(module_sp);
- }
-
- size_t RemoveOrphans(bool mandatory) {
-std::unique_lock lock(GetMutex(), std::defer_lock);
-if (mandatory) {
- lock.lock();
-} else {
- if (!lock.try_lock())
-return 0;
-}
-size_t total_count = 0;
-size_t run_count;
-do {
- // Remove indexed orphans first, then remove non-indexed orphans. This
- // order is important because the shared count will be different if a
- // module is indexed or not.
- run_count = RemoveOrphansFromMapAndList();
- run_count += m_list.RemoveOrphans(mandatory);
- total_count += run_count;
- // Because removing orphans might make new orphans, remove from both
- // containers until a fixed-point is reached.
-} while (run_count != 0);
-
-return total_count;
- }
-
- bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
-if (!module_sp)
- return false;
-std::lock_guard guard(GetMutex());
-RemoveFromMap(module_sp.get());
-return m_list.Remove(module_sp, use_notifier);
- }
-
- void ReplaceEquivalent(const ModuleSP &module_sp,
- llvm::SmallVectorImpl *old_modules) {
-std::lock_guard guard(GetMutex());
-m_list.ReplaceEquivalent(module_sp, old_modules);
-ReplaceEquivalentInMap(module_sp);
- }
-
- bool RemoveIfOrphaned(const Module *module_ptr) {
-std::lock_guard guard(GetMutex());
-RemoveFromMap(module_ptr, /*if_orphaned =*/true);
-return m_list.RemoveIfOrphaned(module_ptr);
- }
-
- std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); }
-
-private:
- ModuleSP FindModuleInMap(const Module *module_ptr) {
-if (!module_ptr->GetFileSpec().GetFilename())
- return ModuleSP();
-ConstString name = module_ptr->GetFileSpec().GetFilename();
-auto it = m_name_to_modules.find(name);
-if (it == m_name_to_modules.end())
- return ModuleSP();
-const llvm::SmallVectorImpl &vector = it->second;
-for (auto &module_sp : vector) {
- if (module_sp.get() == module_ptr)
-return module_sp;
-}
-return ModuleSP();
- }
-
- bool FindModulesInMap(const ModuleSpec &module_spec,
-ModuleList &matching_module_list) cons
[Lldb-commits] [lldb] Revert "[NFC][lldb] Speed up lookup of shared modules (#152054)" (PR #152582)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: Augusto Noronha (augusto2112)
Changes
This reverts commit 229d86026fa0e5d9412a0d5004532f0d9733aac6.
---
Full diff: https://github.com/llvm/llvm-project/pull/152582.diff
1 Files Affected:
- (modified) lldb/source/Core/ModuleList.cpp (+7-235)
``diff
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index 34caa474c1e32..d5ddc2b249e56 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -755,240 +755,11 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
-/// A wrapper around ModuleList for shared modules. Provides fast lookups for
-/// file-based ModuleSpec queries.
-class SharedModuleList {
-public:
- /// Finds all the modules matching the module_spec, and adds them to \p
- /// matching_module_list.
- void FindModules(const ModuleSpec &module_spec,
- ModuleList &matching_module_list) const {
-std::lock_guard guard(GetMutex());
-// Try map first for performance - if found, skip expensive full list
-// search
-if (FindModulesInMap(module_spec, matching_module_list))
- return;
-m_list.FindModules(module_spec, matching_module_list);
-// Assert that modules were found in the list but not the map, it's
-// because the module_spec has no filename or the found module has a
-// different filename. For example, when searching by UUID and finding a
-// module with an alias.
-assert((matching_module_list.IsEmpty() ||
-module_spec.GetFileSpec().GetFilename().IsEmpty() ||
-module_spec.GetFileSpec().GetFilename() !=
-matching_module_list.GetModuleAtIndex(0)
-->GetFileSpec()
-.GetFilename()) &&
- "Search by name not found in SharedModuleList's map");
- }
-
- ModuleSP FindModule(const Module *module_ptr) {
-if (!module_ptr)
- return ModuleSP();
-
-std::lock_guard guard(GetMutex());
-if (ModuleSP result = FindModuleInMap(module_ptr))
- return result;
-return m_list.FindModule(module_ptr);
- }
-
- // UUID searches bypass map since UUIDs aren't indexed by filename.
- ModuleSP FindModule(const UUID &uuid) const {
-return m_list.FindModule(uuid);
- }
-
- void Append(const ModuleSP &module_sp, bool use_notifier) {
-if (!module_sp)
- return;
-std::lock_guard guard(GetMutex());
-m_list.Append(module_sp, use_notifier);
-AddToMap(module_sp);
- }
-
- size_t RemoveOrphans(bool mandatory) {
-std::unique_lock lock(GetMutex(), std::defer_lock);
-if (mandatory) {
- lock.lock();
-} else {
- if (!lock.try_lock())
-return 0;
-}
-size_t total_count = 0;
-size_t run_count;
-do {
- // Remove indexed orphans first, then remove non-indexed orphans. This
- // order is important because the shared count will be different if a
- // module is indexed or not.
- run_count = RemoveOrphansFromMapAndList();
- run_count += m_list.RemoveOrphans(mandatory);
- total_count += run_count;
- // Because removing orphans might make new orphans, remove from both
- // containers until a fixed-point is reached.
-} while (run_count != 0);
-
-return total_count;
- }
-
- bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
-if (!module_sp)
- return false;
-std::lock_guard guard(GetMutex());
-RemoveFromMap(module_sp.get());
-return m_list.Remove(module_sp, use_notifier);
- }
-
- void ReplaceEquivalent(const ModuleSP &module_sp,
- llvm::SmallVectorImpl *old_modules) {
-std::lock_guard guard(GetMutex());
-m_list.ReplaceEquivalent(module_sp, old_modules);
-ReplaceEquivalentInMap(module_sp);
- }
-
- bool RemoveIfOrphaned(const Module *module_ptr) {
-std::lock_guard guard(GetMutex());
-RemoveFromMap(module_ptr, /*if_orphaned =*/true);
-return m_list.RemoveIfOrphaned(module_ptr);
- }
-
- std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); }
-
-private:
- ModuleSP FindModuleInMap(const Module *module_ptr) {
-if (!module_ptr->GetFileSpec().GetFilename())
- return ModuleSP();
-ConstString name = module_ptr->GetFileSpec().GetFilename();
-auto it = m_name_to_modules.find(name);
-if (it == m_name_to_modules.end())
- return ModuleSP();
-const llvm::SmallVectorImpl &vector = it->second;
-for (auto &module_sp : vector) {
- if (module_sp.get() == module_ptr)
-return module_sp;
-}
-return ModuleSP();
- }
-
- bool FindModulesInMap(const ModuleSpec &module_spec,
-ModuleList &matching_module_list) const {
-auto it = m_name_to_modules.find(module_spec.GetFileSpec().GetFilename());
-if (it == m_name_to_modules.end())
- return false;
-const llvm::SmallVectorImpl &vector = it->second;
-bool found = false;
-for (auto
[Lldb-commits] [lldb] 75cc77e - Revert "[NFC][lldb] Speed up lookup of shared modules (#152054)" (#152582)
Author: Augusto Noronha
Date: 2025-08-07T12:49:47-07:00
New Revision: 75cc77e55e12d39aed94702b0b1365e39713081e
URL:
https://github.com/llvm/llvm-project/commit/75cc77e55e12d39aed94702b0b1365e39713081e
DIFF:
https://github.com/llvm/llvm-project/commit/75cc77e55e12d39aed94702b0b1365e39713081e.diff
LOG: Revert "[NFC][lldb] Speed up lookup of shared modules (#152054)" (#152582)
This reverts commit 229d86026fa0e5d9412a0d5004532f0d9733aac6.
Added:
Modified:
lldb/source/Core/ModuleList.cpp
Removed:
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index 34caa474c1e32..d5ddc2b249e56 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -755,240 +755,11 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
-/// A wrapper around ModuleList for shared modules. Provides fast lookups for
-/// file-based ModuleSpec queries.
-class SharedModuleList {
-public:
- /// Finds all the modules matching the module_spec, and adds them to \p
- /// matching_module_list.
- void FindModules(const ModuleSpec &module_spec,
- ModuleList &matching_module_list) const {
-std::lock_guard guard(GetMutex());
-// Try map first for performance - if found, skip expensive full list
-// search
-if (FindModulesInMap(module_spec, matching_module_list))
- return;
-m_list.FindModules(module_spec, matching_module_list);
-// Assert that modules were found in the list but not the map, it's
-// because the module_spec has no filename or the found module has a
-//
diff erent filename. For example, when searching by UUID and finding a
-// module with an alias.
-assert((matching_module_list.IsEmpty() ||
-module_spec.GetFileSpec().GetFilename().IsEmpty() ||
-module_spec.GetFileSpec().GetFilename() !=
-matching_module_list.GetModuleAtIndex(0)
-->GetFileSpec()
-.GetFilename()) &&
- "Search by name not found in SharedModuleList's map");
- }
-
- ModuleSP FindModule(const Module *module_ptr) {
-if (!module_ptr)
- return ModuleSP();
-
-std::lock_guard guard(GetMutex());
-if (ModuleSP result = FindModuleInMap(module_ptr))
- return result;
-return m_list.FindModule(module_ptr);
- }
-
- // UUID searches bypass map since UUIDs aren't indexed by filename.
- ModuleSP FindModule(const UUID &uuid) const {
-return m_list.FindModule(uuid);
- }
-
- void Append(const ModuleSP &module_sp, bool use_notifier) {
-if (!module_sp)
- return;
-std::lock_guard guard(GetMutex());
-m_list.Append(module_sp, use_notifier);
-AddToMap(module_sp);
- }
-
- size_t RemoveOrphans(bool mandatory) {
-std::unique_lock lock(GetMutex(), std::defer_lock);
-if (mandatory) {
- lock.lock();
-} else {
- if (!lock.try_lock())
-return 0;
-}
-size_t total_count = 0;
-size_t run_count;
-do {
- // Remove indexed orphans first, then remove non-indexed orphans. This
- // order is important because the shared count will be
diff erent if a
- // module is indexed or not.
- run_count = RemoveOrphansFromMapAndList();
- run_count += m_list.RemoveOrphans(mandatory);
- total_count += run_count;
- // Because removing orphans might make new orphans, remove from both
- // containers until a fixed-point is reached.
-} while (run_count != 0);
-
-return total_count;
- }
-
- bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
-if (!module_sp)
- return false;
-std::lock_guard guard(GetMutex());
-RemoveFromMap(module_sp.get());
-return m_list.Remove(module_sp, use_notifier);
- }
-
- void ReplaceEquivalent(const ModuleSP &module_sp,
- llvm::SmallVectorImpl *old_modules) {
-std::lock_guard guard(GetMutex());
-m_list.ReplaceEquivalent(module_sp, old_modules);
-ReplaceEquivalentInMap(module_sp);
- }
-
- bool RemoveIfOrphaned(const Module *module_ptr) {
-std::lock_guard guard(GetMutex());
-RemoveFromMap(module_ptr, /*if_orphaned =*/true);
-return m_list.RemoveIfOrphaned(module_ptr);
- }
-
- std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); }
-
-private:
- ModuleSP FindModuleInMap(const Module *module_ptr) {
-if (!module_ptr->GetFileSpec().GetFilename())
- return ModuleSP();
-ConstString name = module_ptr->GetFileSpec().GetFilename();
-auto it = m_name_to_modules.find(name);
-if (it == m_name_to_modules.end())
- return ModuleSP();
-const llvm::SmallVectorImpl &vector = it->second;
-for (auto &module_sp : vector) {
- if (module_sp.get() == module_ptr)
-return module_sp;
-}
-return ModuleSP();
- }
-
- bool FindModulesInMap(const ModuleSpec &module_spec,
-
[Lldb-commits] [lldb] Revert "[NFC][lldb] Speed up lookup of shared modules (#152054)" (PR #152582)
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 --
lldb/source/Core/ModuleList.cpp
``
View the diff from clang-format here.
``diff
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index d5ddc2b24..abfc54c39 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -759,7 +759,7 @@ struct SharedModuleListInfo {
ModuleList module_list;
ModuleListProperties module_list_properties;
};
-}
+} // namespace
static SharedModuleListInfo &GetSharedModuleListInfo()
{
static SharedModuleListInfo *g_shared_module_list_info = nullptr;
``
https://github.com/llvm/llvm-project/pull/152582
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Revert "[NFC][lldb] Speed up lookup of shared modules (#152054)" (PR #152582)
https://github.com/augusto2112 closed https://github.com/llvm/llvm-project/pull/152582 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 11e1d46 - [lldb] Fix UBSan complaints for #151460
Author: Igor Kudrin
Date: 2025-08-07T13:01:52-07:00
New Revision: 11e1d465860903fd9ead27c0c1e60de4439011db
URL:
https://github.com/llvm/llvm-project/commit/11e1d465860903fd9ead27c0c1e60de4439011db
DIFF:
https://github.com/llvm/llvm-project/commit/11e1d465860903fd9ead27c0c1e60de4439011db.diff
LOG: [lldb] Fix UBSan complaints for #151460
Added:
Modified:
lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
lldb/unittests/Instruction/ARM64/TestAArch64Emulator.cpp
Removed:
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
index 021ec49b3d2be..bca5bff24bff0 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -46,9 +46,9 @@ class RegisterInfoPOSIX_arm64
// based on RegisterContextDarwin_arm64.h
// Pack this so there are no extra bytes, but align its start address to at
- // least 4 bytes to prevent alignment errors on Arm 32-bit.
+ // least 8 bytes to prevent alignment errors.
LLVM_PACKED_START
- struct alignas(4) GPR {
+ struct alignas(8) GPR {
uint64_t x[29]; // x0-x28
uint64_t fp;// x29
uint64_t lr;// x30
diff --git a/lldb/unittests/Instruction/ARM64/TestAArch64Emulator.cpp
b/lldb/unittests/Instruction/ARM64/TestAArch64Emulator.cpp
index 08296da564976..c6bfe0fa68759 100644
--- a/lldb/unittests/Instruction/ARM64/TestAArch64Emulator.cpp
+++ b/lldb/unittests/Instruction/ARM64/TestAArch64Emulator.cpp
@@ -62,7 +62,7 @@ struct Arch64EmulatorTester : public EmulateInstructionARM64 {
reg_value.SetUInt64(tester->gpr.pc);
return true;
case gpr_cpsr_arm64:
- reg_value.SetUInt64(tester->gpr.cpsr);
+ reg_value.SetUInt32(tester->gpr.cpsr);
return true;
default:
return false;
@@ -97,7 +97,7 @@ struct Arch64EmulatorTester : public EmulateInstructionARM64 {
tester->gpr.pc = reg_value.GetAsUInt64();
return true;
case gpr_cpsr_arm64:
- tester->gpr.cpsr = reg_value.GetAsUInt64();
+ tester->gpr.cpsr = reg_value.GetAsUInt32();
return true;
default:
return false;
@@ -112,7 +112,7 @@ struct Arch64EmulatorTester : public
EmulateInstructionARM64 {
assert(addr - tester->memory_offset + length <= sizeof(tester->memory));
if (addr >= tester->memory_offset &&
addr - tester->memory_offset + length <= sizeof(tester->memory)) {
- memcpy(dst, tester->memory + addr - tester->memory_offset, length);
+ memcpy(dst, tester->memory + (addr - tester->memory_offset), length);
return length;
}
return 0;
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Only use PyConfig when LLDB_EMBED_PYTHON_HOME is enabled (PR #152588)
@@ -134,9 +115,30 @@ struct InitializePythonRAII {
PyImport_AppendInittab("_lldb", LLDBSwigPyInit);
}
+#if LLDB_EMBED_PYTHON_HOME
medismailben wrote:
Was moving the initialization past the `if (!Py_IsInitialized()) {` needed ?
https://github.com/llvm/llvm-project/pull/152588
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [NFC][lldb] Speed up lookup of shared modules (PR #152054)
@@ -755,11 +755,240 @@ size_t ModuleList::GetIndexForModule(const Module
*module) const {
}
namespace {
+/// A wrapper around ModuleList for shared modules. Provides fast lookups for
+/// file-based ModuleSpec queries.
+class SharedModuleList {
+public:
+ /// Finds all the modules matching the module_spec, and adds them to \p
+ /// matching_module_list.
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+std::lock_guard guard(GetMutex());
+// Try map first for performance - if found, skip expensive full list
+// search
+if (FindModulesInMap(module_spec, matching_module_list))
+ return;
+m_list.FindModules(module_spec, matching_module_list);
+// Assert that modules were found in the list but not the map, it's
+// because the module_spec has no filename or the found module has a
+// different filename. For example, when searching by UUID and finding a
+// module with an alias.
+assert((matching_module_list.IsEmpty() ||
+module_spec.GetFileSpec().GetFilename().IsEmpty() ||
+module_spec.GetFileSpec().GetFilename() !=
+matching_module_list.GetModuleAtIndex(0)
+->GetFileSpec()
+.GetFilename()) &&
+ "Search by name not found in SharedModuleList's map");
+ }
+
+ ModuleSP FindModule(const Module *module_ptr) {
+if (!module_ptr)
+ return ModuleSP();
+
+std::lock_guard guard(GetMutex());
+if (ModuleSP result = FindModuleInMap(module_ptr))
+ return result;
+return m_list.FindModule(module_ptr);
+ }
+
+ // UUID searches bypass map since UUIDs aren't indexed by filename.
+ ModuleSP FindModule(const UUID &uuid) const {
+return m_list.FindModule(uuid);
+ }
+
+ void Append(const ModuleSP &module_sp, bool use_notifier) {
+if (!module_sp)
+ return;
+std::lock_guard guard(GetMutex());
+m_list.Append(module_sp, use_notifier);
+AddToMap(module_sp);
+ }
+
+ size_t RemoveOrphans(bool mandatory) {
+std::unique_lock lock(GetMutex(), std::defer_lock);
+if (mandatory) {
+ lock.lock();
+} else {
+ if (!lock.try_lock())
+return 0;
+}
+size_t total_count = 0;
+size_t run_count;
+do {
+ // Remove indexed orphans first, then remove non-indexed orphans. This
+ // order is important because the shared count will be different if a
+ // module is indexed or not.
+ run_count = RemoveOrphansFromMapAndList();
+ run_count += m_list.RemoveOrphans(mandatory);
+ total_count += run_count;
+ // Because removing orphans might make new orphans, remove from both
+ // containers until a fixed-point is reached.
+} while (run_count != 0);
+
+return total_count;
+ }
+
+ bool Remove(const ModuleSP &module_sp, bool use_notifier = true) {
+if (!module_sp)
+ return false;
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_sp.get());
+return m_list.Remove(module_sp, use_notifier);
+ }
+
+ void ReplaceEquivalent(const ModuleSP &module_sp,
+ llvm::SmallVectorImpl *old_modules) {
+std::lock_guard guard(GetMutex());
+m_list.ReplaceEquivalent(module_sp, old_modules);
+ReplaceEquivalentInMap(module_sp);
+ }
+
+ bool RemoveIfOrphaned(const Module *module_ptr) {
+std::lock_guard guard(GetMutex());
+RemoveFromMap(module_ptr, /*if_orphaned =*/true);
+return m_list.RemoveIfOrphaned(module_ptr);
+ }
+
+ std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); }
+
+private:
+ ModuleSP FindModuleInMap(const Module *module_ptr) {
+if (!module_ptr->GetFileSpec().GetFilename())
+ return ModuleSP();
+ConstString name = module_ptr->GetFileSpec().GetFilename();
+auto it = m_name_to_modules.find(name);
+if (it == m_name_to_modules.end())
+ return ModuleSP();
+const llvm::SmallVectorImpl &vector = it->second;
+for (auto &module_sp : vector) {
+ if (module_sp.get() == module_ptr)
+return module_sp;
+}
+return ModuleSP();
+ }
+
+ bool FindModulesInMap(const ModuleSpec &module_spec,
+ModuleList &matching_module_list) const {
+auto it = m_name_to_modules.find(module_spec.GetFileSpec().GetFilename());
+if (it == m_name_to_modules.end())
+ return false;
+const llvm::SmallVectorImpl &vector = it->second;
+bool found = false;
+for (auto &module_sp : vector) {
+ if (module_sp->MatchesModuleSpec(module_spec)) {
+matching_module_list.Append(module_sp);
+found = true;
+ }
+}
+return found;
+ }
+
+ void AddToMap(const ModuleSP &module_sp) {
+ConstString name = module_sp->GetFileSpec().GetFilename();
+if (name.IsEmpty())
+ return;
+llvm::SmallVectorImpl &vec = m_name_to_modules[name];
+vec.push_back(module_sp);
+ }
+
+ void RemoveFromMap(const Module *module_ptr, bool if_orp
