[Lldb-commits] [lldb] [lldb] Move the generic MCP server code into Protocol/MCP (NFC) (PR #152396)

2025-08-07 Thread Jonas Devlieghere via lldb-commits

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)

2025-08-07 Thread via lldb-commits


@@ -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)

2025-08-07 Thread Walter Erquinigo via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread John Harrison via lldb-commits

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)

2025-08-07 Thread John Harrison via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits


@@ -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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Michael Buch via lldb-commits


@@ -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)

2025-08-07 Thread Adrian Prantl via lldb-commits


@@ -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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits

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)

2025-08-07 Thread Michael Buch via lldb-commits


@@ -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)

2025-08-07 Thread Michael Buch via lldb-commits

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)

2025-08-07 Thread Nikita Popov via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Michael Buch via lldb-commits

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)

2025-08-07 Thread Adrian Prantl via lldb-commits

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)

2025-08-07 Thread Santhosh Kumar Ellendula via lldb-commits

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)

2025-08-07 Thread John Harrison via lldb-commits

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)

2025-08-07 Thread John Harrison via lldb-commits

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)

2025-08-07 Thread David Blaikie via lldb-commits

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)

2025-08-07 Thread Dominic Chen via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Alex Langford via lldb-commits

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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Augusto Noronha via lldb-commits

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)

2025-08-07 Thread via lldb-commits


@@ -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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Michael Buch via lldb-commits


@@ -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)

2025-08-07 Thread Michael Buch via lldb-commits


@@ -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)

2025-08-07 Thread Nikolas Klauser via lldb-commits


@@ -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)

2025-08-07 Thread Nikolas Klauser via lldb-commits


@@ -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)

2025-08-07 Thread Nikolas Klauser via lldb-commits


@@ -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)

2025-08-07 Thread Nikolas Klauser via lldb-commits


@@ -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)

2025-08-07 Thread Nikolas Klauser via lldb-commits


@@ -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)

2025-08-07 Thread Nikolas Klauser via lldb-commits


@@ -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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread David Spickett via lldb-commits

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)

2025-08-07 Thread Michael Buch via lldb-commits

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)

2025-08-07 Thread Michael Buch via lldb-commits


@@ -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)

2025-08-07 Thread via lldb-commits


@@ -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)

2025-08-07 Thread via lldb-commits


@@ -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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Michael Buch via lldb-commits

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)

2025-08-07 Thread Charles Zablit via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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.

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): image After: image 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)

2025-08-07 Thread via lldb-commits

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.

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): image After: image 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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Martin Storsjö via lldb-commits

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)

2025-08-07 Thread Michael Buch via lldb-commits

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)

2025-08-07 Thread Michael Buch via lldb-commits


@@ -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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Chad Smith via lldb-commits

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)

2025-08-07 Thread Chad Smith via lldb-commits

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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits


@@ -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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits


@@ -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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits

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)

2025-08-07 Thread Dave Lee via lldb-commits

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)

2025-08-07 Thread Ely Ronnen via lldb-commits

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)

2025-08-07 Thread Dave Lee via lldb-commits


@@ -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)

2025-08-07 Thread LLVM Continuous Integration via lldb-commits

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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits


@@ -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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Felipe de Azevedo Piovezan via lldb-commits


@@ -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)

2025-08-07 Thread Felipe de Azevedo Piovezan via lldb-commits

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)

2025-08-07 Thread Felipe de Azevedo Piovezan via lldb-commits


@@ -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)

2025-08-07 Thread Alex Langford via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Augusto Noronha via lldb-commits

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)

2025-08-07 Thread Augusto Noronha via lldb-commits

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)

2025-08-07 Thread Dave Lee via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Igor Kudrin via lldb-commits

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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits

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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits

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)

2025-08-07 Thread Ilia Kuklin via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits

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)

2025-08-07 Thread Augusto Noronha via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread via lldb-commits

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)

2025-08-07 Thread Augusto Noronha via lldb-commits

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

2025-08-07 Thread Igor Kudrin via lldb-commits

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)

2025-08-07 Thread Med Ismail Bennani via lldb-commits


@@ -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)

2025-08-07 Thread Jonas Devlieghere via lldb-commits


@@ -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

  1   2   >