https://github.com/eronnen updated 
https://github.com/llvm/llvm-project/pull/139969

>From d6325b3f6a8602fc96ad72acecfcccda1120614d Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sat, 10 May 2025 20:45:17 +0200
Subject: [PATCH 01/14] support assembly in BreakpointLocationsRequestHandler

---
 .../breakpoint/TestDAP_setBreakpoints.py      |  1 -
 .../TestDAP_setExceptionBreakpoints.py        |  1 -
 .../TestDAP_setFunctionBreakpoints.py         |  1 -
 lldb/tools/lldb-dap/DAP.h                     |  3 +
 .../Handler/BreakpointLocationsHandler.cpp    | 77 +++++++++++++++----
 lldb/tools/lldb-dap/Handler/RequestHandler.h  | 11 +++
 .../lldb-dap/Handler/SourceRequestHandler.cpp |  4 +-
 7 files changed, 76 insertions(+), 22 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py 
b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
index aae1251b17c93..26df2573555df 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
@@ -12,7 +12,6 @@
 import os
 
 
-@skip("Temporarily disable the breakpoint tests")
 class TestDAP_setBreakpoints(lldbdap_testcase.DAPTestCaseBase):
     def setUp(self):
         lldbdap_testcase.DAPTestCaseBase.setUp(self)
diff --git 
a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py 
b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
index 4dc8c5b3c7ded..92ac66cd44c5d 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
@@ -10,7 +10,6 @@
 import lldbdap_testcase
 
 
-@skip("Temporarily disable the breakpoint tests")
 class TestDAP_setExceptionBreakpoints(lldbdap_testcase.DAPTestCaseBase):
     @skipIfWindows
     def test_functionality(self):
diff --git 
a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py 
b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
index baaca4d974d5d..946595f639edc 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
@@ -10,7 +10,6 @@
 import lldbdap_testcase
 
 
-@skip("Temporarily disable the breakpoint tests")
 class TestDAP_setFunctionBreakpoints(lldbdap_testcase.DAPTestCaseBase):
     @skipIfWindows
     def test_set_and_clear(self):
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 8f24c6cf82924..00aa4276852c5 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -219,6 +219,9 @@ struct DAP {
   llvm::StringSet<> modules;
   /// @}
 
+  /// Number of lines of assembly code to show when no debug info is available.
+  uint32_t number_of_assembly_lines_for_nodebug = 32;
+
   /// Creates a new DAP sessions.
   ///
   /// \param[in] log
diff --git a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp 
b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
index 2ac886c3a5d2c..9eea549d72b00 100644
--- a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
@@ -7,7 +7,7 @@
 
//===----------------------------------------------------------------------===//
 
 #include "DAP.h"
-#include "JSONUtils.h"
+#include "LLDBUtils.h"
 #include "RequestHandler.h"
 #include <vector>
 
@@ -19,19 +19,50 @@ namespace lldb_dap {
 llvm::Expected<protocol::BreakpointLocationsResponseBody>
 BreakpointLocationsRequestHandler::Run(
     const protocol::BreakpointLocationsArguments &args) const {
-  std::string path = args.source.path.value_or("");
   uint32_t start_line = args.line;
   uint32_t start_column = args.column.value_or(LLDB_INVALID_COLUMN_NUMBER);
   uint32_t end_line = args.endLine.value_or(start_line);
   uint32_t end_column =
       args.endColumn.value_or(std::numeric_limits<uint32_t>::max());
 
+  // Find all relevant lines & columns
+  llvm::SmallVector<std::pair<uint32_t, uint32_t>, 8> locations;
+  if (args.source.sourceReference) {
+    AddAssemblyBreakpointLocations(locations, *args.source.sourceReference,
+                                   start_line, end_line);
+  } else {
+    std::string path = args.source.path.value_or("");
+    AddSourceBreakpointLocations(locations, std::move(path), start_line,
+                                 start_column, end_line, end_column);
+  }
+
+  // The line entries are sorted by addresses, but we must return the list
+  // ordered by line / column position.
+  std::sort(locations.begin(), locations.end());
+  locations.erase(llvm::unique(locations), locations.end());
+
+  std::vector<protocol::BreakpointLocation> breakpoint_locations;
+  for (auto &l : locations) {
+    protocol::BreakpointLocation lc;
+    lc.line = l.first;
+    lc.column = l.second;
+    breakpoint_locations.push_back(std::move(lc));
+  }
+
+  return protocol::BreakpointLocationsResponseBody{
+      /*breakpoints=*/std::move(breakpoint_locations)};
+}
+
+template <unsigned N>
+void BreakpointLocationsRequestHandler::AddSourceBreakpointLocations(
+    llvm::SmallVector<std::pair<uint32_t, uint32_t>, N> &locations,
+    std::string path, uint32_t start_line, uint32_t start_column,
+    uint32_t end_line, uint32_t end_column) const {
+
   lldb::SBFileSpec file_spec(path.c_str(), true);
   lldb::SBSymbolContextList compile_units =
       dap.target.FindCompileUnits(file_spec);
 
-  // Find all relevant lines & columns
-  llvm::SmallVector<std::pair<uint32_t, uint32_t>, 8> locations;
   for (uint32_t c_idx = 0, c_limit = compile_units.GetSize(); c_idx < c_limit;
        ++c_idx) {
     const lldb::SBCompileUnit &compile_unit =
@@ -71,22 +102,34 @@ BreakpointLocationsRequestHandler::Run(
       locations.emplace_back(line, column);
     }
   }
+}
 
-  // The line entries are sorted by addresses, but we must return the list
-  // ordered by line / column position.
-  std::sort(locations.begin(), locations.end());
-  locations.erase(llvm::unique(locations), locations.end());
+template <unsigned N>
+void BreakpointLocationsRequestHandler::AddAssemblyBreakpointLocations(
+    llvm::SmallVector<std::pair<uint32_t, uint32_t>, N> &locations,
+    int64_t sourceReference, uint32_t start_line, uint32_t end_line) const {
+  lldb::SBProcess process = dap.target.GetProcess();
+  lldb::SBThread thread =
+      process.GetThreadByIndexID(GetLLDBThreadIndexID(sourceReference));
+  lldb::SBFrame frame = 
thread.GetFrameAtIndex(GetLLDBFrameID(sourceReference));
 
-  std::vector<protocol::BreakpointLocation> breakpoint_locations;
-  for (auto &l : locations) {
-    protocol::BreakpointLocation lc;
-    lc.line = l.first;
-    lc.column = l.second;
-    breakpoint_locations.push_back(std::move(lc));
-  }
+  if (!frame.IsValid())
+    return;
 
-  return protocol::BreakpointLocationsResponseBody{
-      /*breakpoints=*/std::move(breakpoint_locations)};
+  lldb::SBSymbol symbol = frame.GetSymbol();
+  if (symbol.IsValid()) {
+    lldb::SBInstructionList insts = symbol.GetInstructions(dap.target);
+    for (uint32_t i = start_line - 1; i < insts.GetSize() && i < (end_line - 
1);
+         ++i) {
+      locations.emplace_back(i, 0);
+    }
+  } else {
+    for (uint32_t i = start_line - 1;
+         i < dap.number_of_assembly_lines_for_nodebug && i < (end_line - 1);
+         ++i) {
+      locations.emplace_back(i, 0);
+    }
+  }
 }
 
 } // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h 
b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index e6bccfe12f402..21753bc0552f9 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -16,6 +16,7 @@
 #include "Protocol/ProtocolRequests.h"
 #include "Protocol/ProtocolTypes.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/JSON.h"
@@ -232,6 +233,16 @@ class BreakpointLocationsRequestHandler
   }
   llvm::Expected<protocol::BreakpointLocationsResponseBody>
   Run(const protocol::BreakpointLocationsArguments &args) const override;
+
+  template <unsigned N>
+  void AddSourceBreakpointLocations(
+      llvm::SmallVector<std::pair<uint32_t, uint32_t>, N> &locations,
+      std::string path, uint32_t start_line, uint32_t start_column,
+      uint32_t end_line, uint32_t end_column) const;
+  template <unsigned N>
+  void AddAssemblyBreakpointLocations(
+      llvm::SmallVector<std::pair<uint32_t, uint32_t>, N> &locations,
+      int64_t sourceReference, uint32_t start_line, uint32_t end_line) const;
 };
 
 class CompletionsRequestHandler : public LegacyRequestHandler {
diff --git a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp
index 0ddd87881a164..fb396a3dc8862 100644
--- a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp
@@ -52,8 +52,8 @@ SourceRequestHandler::Run(const protocol::SourceArguments 
&args) const {
     insts.GetDescription(stream, exe_ctx);
   } else {
     // No valid symbol, just return the disassembly.
-    lldb::SBInstructionList insts =
-        dap.target.ReadInstructions(frame.GetPCAddress(), 32);
+    lldb::SBInstructionList insts = dap.target.ReadInstructions(
+        frame.GetPCAddress(), dap.number_of_assembly_lines_for_nodebug);
     insts.GetDescription(stream, exe_ctx);
   }
 

>From ee492031bee8106fb2a4ff22a8563005f5afd86c Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 11 May 2025 19:49:03 +0200
Subject: [PATCH 02/14] support assembly in SetBreakpointsRequestHandler

---
 lldb/tools/lldb-dap/DAP.h                     |  1 +
 .../Handler/BreakpointLocationsHandler.cpp    | 20 ++---
 lldb/tools/lldb-dap/Handler/RequestHandler.h  |  9 ++
 .../Handler/SetBreakpointsRequestHandler.cpp  | 90 ++++++++++++++++++-
 lldb/tools/lldb-dap/SourceBreakpoint.cpp      | 22 +++++
 lldb/tools/lldb-dap/SourceBreakpoint.h        |  1 +
 6 files changed, 127 insertions(+), 16 deletions(-)

diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 00aa4276852c5..5ce0e534611c1 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -169,6 +169,7 @@ struct DAP {
   Variables variables;
   lldb::SBBroadcaster broadcaster;
   llvm::StringMap<SourceBreakpointMap> source_breakpoints;
+  llvm::DenseMap<int64_t, SourceBreakpointMap> assembly_breakpoints;
   FunctionBreakpointMap function_breakpoints;
   InstructionBreakpointMap instruction_breakpoints;
   std::optional<std::vector<ExceptionBreakpoint>> exception_breakpoints;
diff --git a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp 
b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
index 9eea549d72b00..be02c47056310 100644
--- a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
@@ -117,18 +117,14 @@ void 
BreakpointLocationsRequestHandler::AddAssemblyBreakpointLocations(
     return;
 
   lldb::SBSymbol symbol = frame.GetSymbol();
-  if (symbol.IsValid()) {
-    lldb::SBInstructionList insts = symbol.GetInstructions(dap.target);
-    for (uint32_t i = start_line - 1; i < insts.GetSize() && i < (end_line - 
1);
-         ++i) {
-      locations.emplace_back(i, 0);
-    }
-  } else {
-    for (uint32_t i = start_line - 1;
-         i < dap.number_of_assembly_lines_for_nodebug && i < (end_line - 1);
-         ++i) {
-      locations.emplace_back(i, 0);
-    }
+  if (!symbol.IsValid())
+    return;
+
+  // start_line is relative to the symbol's start address
+  lldb::SBInstructionList insts = symbol.GetInstructions(dap.target);
+  for (uint32_t i = start_line - 1; i < insts.GetSize() && i < (end_line - 1);
+       ++i) {
+    locations.emplace_back(i, 0);
   }
 }
 
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h 
b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index 21753bc0552f9..72843aaef8150 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -389,6 +389,15 @@ class SetBreakpointsRequestHandler
   }
   llvm::Expected<protocol::SetBreakpointsResponseBody>
   Run(const protocol::SetBreakpointsArguments &args) const override;
+
+  std::vector<protocol::Breakpoint> SetSourceBreakpoints(
+      const std::string &path,
+      const std::optional<std::vector<protocol::SourceBreakpoint>> 
&breakpoints)
+      const;
+  std::vector<protocol::Breakpoint> SetAssemblyBreakpoints(
+      int64_t sourceReference,
+      const std::optional<std::vector<protocol::SourceBreakpoint>> 
&breakpoints)
+      const;
 };
 
 class SetExceptionBreakpointsRequestHandler : public LegacyRequestHandler {
diff --git a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
index 86e090b66afe9..71f9e5578ef08 100644
--- a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
@@ -9,8 +9,11 @@
 #include "DAP.h"
 #include "EventHelper.h"
 #include "JSONUtils.h"
+#include "LLDBUtils.h"
 #include "Protocol/ProtocolRequests.h"
 #include "RequestHandler.h"
+#include <cstdint>
+#include <utility>
 #include <vector>
 
 namespace lldb_dap {
@@ -23,15 +26,30 @@ llvm::Expected<protocol::SetBreakpointsResponseBody>
 SetBreakpointsRequestHandler::Run(
     const protocol::SetBreakpointsArguments &args) const {
   const auto &source = args.source;
-  const auto path = source.path.value_or("");
+  std::vector<protocol::Breakpoint> response_breakpoints;
+  if (source.sourceReference)
+    response_breakpoints = SetAssemblyBreakpoints(
+        source.sourceReference.value(), args.breakpoints);
+  else if (source.path)
+    response_breakpoints =
+        SetSourceBreakpoints(source.path.value(), args.breakpoints);
+
+  return protocol::SetBreakpointsResponseBody{std::move(response_breakpoints)};
+}
+
+std::vector<protocol::Breakpoint>
+SetBreakpointsRequestHandler::SetSourceBreakpoints(
+    const std::string &path,
+    const std::optional<std::vector<protocol::SourceBreakpoint>> &breakpoints)
+    const {
   std::vector<protocol::Breakpoint> response_breakpoints;
 
   // Decode the source breakpoint infos for this "setBreakpoints" request
   SourceBreakpointMap request_bps;
   // "breakpoints" may be unset, in which case we treat it the same as being 
set
   // to an empty array.
-  if (args.breakpoints) {
-    for (const auto &bp : *args.breakpoints) {
+  if (breakpoints) {
+    for (const auto &bp : *breakpoints) {
       SourceBreakpoint src_bp(dap, bp);
       std::pair<uint32_t, uint32_t> bp_pos(src_bp.GetLine(),
                                            src_bp.GetColumn());
@@ -73,7 +91,71 @@ SetBreakpointsRequestHandler::Run(
     }
   }
 
-  return protocol::SetBreakpointsResponseBody{std::move(response_breakpoints)};
+  return response_breakpoints;
+}
+
+std::vector<protocol::Breakpoint>
+SetBreakpointsRequestHandler::SetAssemblyBreakpoints(
+    int64_t sourceReference,
+    const std::optional<std::vector<protocol::SourceBreakpoint>> &breakpoints)
+    const {
+  std::vector<protocol::Breakpoint> response_breakpoints;
+
+  lldb::SBProcess process = dap.target.GetProcess();
+  lldb::SBThread thread =
+      process.GetThreadByIndexID(GetLLDBThreadIndexID(sourceReference));
+  lldb::SBFrame frame = 
thread.GetFrameAtIndex(GetLLDBFrameID(sourceReference));
+
+  if (!frame.IsValid())
+    return response_breakpoints;
+
+  lldb::SBSymbol symbol = frame.GetSymbol();
+  if (!symbol.IsValid())
+    return response_breakpoints; // Not yet supporting breakpoints in assembly
+                                 // without a valid symbol
+
+  SourceBreakpointMap request_bps;
+  if (breakpoints) {
+    for (const auto &bp : *breakpoints) {
+      SourceBreakpoint src_bp(dap, bp);
+      std::pair<uint32_t, uint32_t> bp_pos(src_bp.GetLine(), 0);
+      request_bps.try_emplace(bp_pos, src_bp);
+      const auto [iv, inserted] =
+          dap.assembly_breakpoints[sourceReference].try_emplace(bp_pos, 
src_bp);
+      // We check if this breakpoint already exists to update it
+      if (inserted)
+        iv->getSecond().SetBreakpoint(symbol);
+      else
+        iv->getSecond().UpdateBreakpoint(src_bp);
+
+      protocol::Breakpoint response_bp = 
iv->getSecond().ToProtocolBreakpoint();
+      protocol::Source source;
+      source.sourceReference = sourceReference;
+      source.name = symbol.GetName();
+      response_bp.source = std::move(source);
+
+      if (!response_bp.line)
+        response_bp.line = src_bp.GetLine();
+      if (!response_bp.column)
+        response_bp.column = src_bp.GetColumn();
+      response_breakpoints.push_back(response_bp);
+    }
+  }
+
+  // Delete existing breakpoints for this sourceReference that are not in the
+  // request_bps set.
+  auto old_src_bp_pos = dap.assembly_breakpoints.find(sourceReference);
+  if (old_src_bp_pos != dap.assembly_breakpoints.end()) {
+    for (auto &old_bp : old_src_bp_pos->second) {
+      auto request_pos = request_bps.find(old_bp.first);
+      if (request_pos == request_bps.end()) {
+        dap.target.BreakpointDelete(old_bp.second.GetID());
+        old_src_bp_pos->second.erase(old_bp.first);
+      }
+    }
+  }
+
+  return response_breakpoints;
 }
 
 } // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp 
b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index 4581c995b4260..938b8fb8bcdda 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -13,7 +13,9 @@
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBFileSpecList.h"
 #include "lldb/API/SBFrame.h"
+#include "lldb/API/SBInstruction.h"
 #include "lldb/API/SBMutex.h"
+#include "lldb/API/SBSymbol.h"
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBThread.h"
 #include "lldb/API/SBValue.h"
@@ -45,6 +47,26 @@ void SourceBreakpoint::SetBreakpoint(const llvm::StringRef 
source_path) {
   Breakpoint::SetBreakpoint();
 }
 
+void SourceBreakpoint::SetBreakpoint(lldb::SBSymbol &symbol) {
+  lldb::SBMutex lock = m_dap.GetAPIMutex();
+  std::lock_guard<lldb::SBMutex> guard(lock);
+
+  if (m_line == 0)
+    return;
+
+  lldb::SBInstructionList inst_list =
+      m_dap.target.ReadInstructions(symbol.GetStartAddress(), m_line);
+  if (inst_list.GetSize() < m_line)
+    return;
+  lldb::SBAddress address =
+      inst_list.GetInstructionAtIndex(m_line - 1).GetAddress();
+
+  m_bp = m_dap.target.BreakpointCreateBySBAddress(address);
+  if (!m_log_message.empty())
+    SetLogMessage();
+  Breakpoint::SetBreakpoint();
+}
+
 void SourceBreakpoint::UpdateBreakpoint(const SourceBreakpoint &request_bp) {
   if (m_log_message != request_bp.m_log_message) {
     m_log_message = request_bp.m_log_message;
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.h 
b/lldb/tools/lldb-dap/SourceBreakpoint.h
index 5b15296f861c5..8589800e50983 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.h
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.h
@@ -26,6 +26,7 @@ class SourceBreakpoint : public Breakpoint {
 
   // Set this breakpoint in LLDB as a new breakpoint
   void SetBreakpoint(const llvm::StringRef source_path);
+  void SetBreakpoint(lldb::SBSymbol &symbol);
   void UpdateBreakpoint(const SourceBreakpoint &request_bp);
 
   void SetLogMessage();

>From dbb2f9bd55b3f86247e03b2610fca9576e124637 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Wed, 14 May 2025 23:51:41 +0200
Subject: [PATCH 03/14] fix resolving of assembly source breakpoints

---
 lldb/tools/lldb-dap/Breakpoint.cpp            | 45 ++++++++++++++++---
 lldb/tools/lldb-dap/DAP.h                     |  3 +-
 .../Handler/BreakpointLocationsHandler.cpp    |  4 +-
 lldb/tools/lldb-dap/Handler/RequestHandler.h  |  4 +-
 .../Handler/SetBreakpointsRequestHandler.cpp  | 30 ++++++-------
 lldb/tools/lldb-dap/package-lock.json         |  4 +-
 lldb/tools/lldb-dap/package.json              |  5 ++-
 7 files changed, 63 insertions(+), 32 deletions(-)

diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp 
b/lldb/tools/lldb-dap/Breakpoint.cpp
index 26d633d1d172e..87fcd15b0a568 100644
--- a/lldb/tools/lldb-dap/Breakpoint.cpp
+++ b/lldb/tools/lldb-dap/Breakpoint.cpp
@@ -9,10 +9,12 @@
 #include "Breakpoint.h"
 #include "DAP.h"
 #include "JSONUtils.h"
+#include "LLDBUtils.h"
 #include "lldb/API/SBAddress.h"
 #include "lldb/API/SBBreakpointLocation.h"
 #include "lldb/API/SBLineEntry.h"
 #include "lldb/API/SBMutex.h"
+#include "lldb/lldb-enumerations.h"
 #include "llvm/ADT/StringExtras.h"
 #include <cstddef>
 #include <cstdint>
@@ -63,14 +65,43 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() {
     std::string formatted_addr =
         "0x" + llvm::utohexstr(bp_addr.GetLoadAddress(m_bp.GetTarget()));
     breakpoint.instructionReference = formatted_addr;
+
+    lldb::StopDisassemblyType stop_disassembly_display =
+        GetStopDisassemblyDisplay(m_dap.debugger);
     auto line_entry = bp_addr.GetLineEntry();
-    const auto line = line_entry.GetLine();
-    if (line != UINT32_MAX)
-      breakpoint.line = line;
-    const auto column = line_entry.GetColumn();
-    if (column != 0)
-      breakpoint.column = column;
-    breakpoint.source = CreateSource(line_entry);
+    if (!ShouldDisplayAssemblySource(line_entry, stop_disassembly_display)) {
+      const auto line = line_entry.GetLine();
+      if (line != UINT32_MAX)
+        breakpoint.line = line;
+      const auto column = line_entry.GetColumn();
+      if (column != 0)
+        breakpoint.column = column;
+      breakpoint.source = CreateSource(line_entry);
+    } else {
+      // Breakpoint made by assembly
+      auto symbol_context = bp_addr.GetSymbolContext(
+          lldb::eSymbolContextSymbol | lldb::eSymbolContextModule);
+      if (symbol_context.IsValid()) {
+        auto symbol = symbol_context.GetSymbol();
+        breakpoint.line =
+            m_bp.GetTarget()
+                .ReadInstructions(symbol.GetStartAddress(), bp_addr, nullptr)
+                .GetSize() +
+            1;
+        protocol::Source source;
+        source.name = symbol.GetName();
+
+        auto module = symbol_context.GetModule();
+        if (module.IsValid()) {
+          std::string path = module.GetFileSpec().GetDirectory();
+          path += "/";
+          path += module.GetFileSpec().GetFilename();
+          source.path = std::move(path);
+        }
+
+        breakpoint.source = std::move(source);
+      }
+    }
   }
 
   return breakpoint;
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 5ce0e534611c1..b0fe265b7bca1 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -169,7 +169,8 @@ struct DAP {
   Variables variables;
   lldb::SBBroadcaster broadcaster;
   llvm::StringMap<SourceBreakpointMap> source_breakpoints;
-  llvm::DenseMap<int64_t, SourceBreakpointMap> assembly_breakpoints;
+  llvm::DenseMap<int64_t, llvm::DenseMap<uint32_t, SourceBreakpoint>>
+      assembly_breakpoints;
   FunctionBreakpointMap function_breakpoints;
   InstructionBreakpointMap instruction_breakpoints;
   std::optional<std::vector<ExceptionBreakpoint>> exception_breakpoints;
diff --git a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp 
b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
index be02c47056310..06ada47a6f27f 100644
--- a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
@@ -122,9 +122,9 @@ void 
BreakpointLocationsRequestHandler::AddAssemblyBreakpointLocations(
 
   // start_line is relative to the symbol's start address
   lldb::SBInstructionList insts = symbol.GetInstructions(dap.target);
-  for (uint32_t i = start_line - 1; i < insts.GetSize() && i < (end_line - 1);
+  for (uint32_t i = start_line - 1; i < insts.GetSize() && i <= (end_line - 1);
        ++i) {
-    locations.emplace_back(i, 0);
+    locations.emplace_back(i, 1);
   }
 }
 
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h 
b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index 72843aaef8150..80898d1ee5ef1 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -391,11 +391,11 @@ class SetBreakpointsRequestHandler
   Run(const protocol::SetBreakpointsArguments &args) const override;
 
   std::vector<protocol::Breakpoint> SetSourceBreakpoints(
-      const std::string &path,
+      const protocol::Source &source,
       const std::optional<std::vector<protocol::SourceBreakpoint>> 
&breakpoints)
       const;
   std::vector<protocol::Breakpoint> SetAssemblyBreakpoints(
-      int64_t sourceReference,
+      const protocol::Source &source,
       const std::optional<std::vector<protocol::SourceBreakpoint>> 
&breakpoints)
       const;
 };
diff --git a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
index 71f9e5578ef08..4fefd8b440c7d 100644
--- a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
@@ -28,21 +28,20 @@ SetBreakpointsRequestHandler::Run(
   const auto &source = args.source;
   std::vector<protocol::Breakpoint> response_breakpoints;
   if (source.sourceReference)
-    response_breakpoints = SetAssemblyBreakpoints(
-        source.sourceReference.value(), args.breakpoints);
+    response_breakpoints = SetAssemblyBreakpoints(source, args.breakpoints);
   else if (source.path)
-    response_breakpoints =
-        SetSourceBreakpoints(source.path.value(), args.breakpoints);
+    response_breakpoints = SetSourceBreakpoints(source, args.breakpoints);
 
   return protocol::SetBreakpointsResponseBody{std::move(response_breakpoints)};
 }
 
 std::vector<protocol::Breakpoint>
 SetBreakpointsRequestHandler::SetSourceBreakpoints(
-    const std::string &path,
+    const protocol::Source &source,
     const std::optional<std::vector<protocol::SourceBreakpoint>> &breakpoints)
     const {
   std::vector<protocol::Breakpoint> response_breakpoints;
+  std::string path = source.path.value_or("");
 
   // Decode the source breakpoint infos for this "setBreakpoints" request
   SourceBreakpointMap request_bps;
@@ -96,10 +95,11 @@ SetBreakpointsRequestHandler::SetSourceBreakpoints(
 
 std::vector<protocol::Breakpoint>
 SetBreakpointsRequestHandler::SetAssemblyBreakpoints(
-    int64_t sourceReference,
+    const protocol::Source &source,
     const std::optional<std::vector<protocol::SourceBreakpoint>> &breakpoints)
     const {
   std::vector<protocol::Breakpoint> response_breakpoints;
+  int64_t sourceReference = source.sourceReference.value_or(0);
 
   lldb::SBProcess process = dap.target.GetProcess();
   lldb::SBThread thread =
@@ -114,14 +114,14 @@ SetBreakpointsRequestHandler::SetAssemblyBreakpoints(
     return response_breakpoints; // Not yet supporting breakpoints in assembly
                                  // without a valid symbol
 
-  SourceBreakpointMap request_bps;
+  llvm::DenseMap<uint32_t, SourceBreakpoint> request_bps;
   if (breakpoints) {
     for (const auto &bp : *breakpoints) {
       SourceBreakpoint src_bp(dap, bp);
-      std::pair<uint32_t, uint32_t> bp_pos(src_bp.GetLine(), 0);
-      request_bps.try_emplace(bp_pos, src_bp);
+      request_bps.try_emplace(src_bp.GetLine(), src_bp);
       const auto [iv, inserted] =
-          dap.assembly_breakpoints[sourceReference].try_emplace(bp_pos, 
src_bp);
+          dap.assembly_breakpoints[sourceReference].try_emplace(
+              src_bp.GetLine(), src_bp);
       // We check if this breakpoint already exists to update it
       if (inserted)
         iv->getSecond().SetBreakpoint(symbol);
@@ -129,15 +129,11 @@ SetBreakpointsRequestHandler::SetAssemblyBreakpoints(
         iv->getSecond().UpdateBreakpoint(src_bp);
 
       protocol::Breakpoint response_bp = 
iv->getSecond().ToProtocolBreakpoint();
-      protocol::Source source;
-      source.sourceReference = sourceReference;
-      source.name = symbol.GetName();
-      response_bp.source = std::move(source);
-
+      response_bp.source = source;
       if (!response_bp.line)
         response_bp.line = src_bp.GetLine();
-      if (!response_bp.column)
-        response_bp.column = src_bp.GetColumn();
+      if (bp.column)
+        response_bp.column = *bp.column;
       response_breakpoints.push_back(response_bp);
     }
   }
diff --git a/lldb/tools/lldb-dap/package-lock.json 
b/lldb/tools/lldb-dap/package-lock.json
index 0a2b9e764067e..af90a9573aee6 100644
--- a/lldb/tools/lldb-dap/package-lock.json
+++ b/lldb/tools/lldb-dap/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "lldb-dap",
-  "version": "0.2.13",
+  "version": "0.2.14",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "lldb-dap",
-      "version": "0.2.13",
+      "version": "0.2.14",
       "license": "Apache 2.0 License with LLVM exceptions",
       "devDependencies": {
         "@types/node": "^18.19.41",
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index d5ca604798799..73e70cd961f4f 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -1,7 +1,7 @@
 {
   "name": "lldb-dap",
   "displayName": "LLDB DAP",
-  "version": "0.2.13",
+  "version": "0.2.14",
   "publisher": "llvm-vs-code-extensions",
   "homepage": "https://lldb.llvm.org";,
   "description": "Debugging with LLDB in Visual Studio Code",
@@ -265,6 +265,9 @@
       ]
     },
     "breakpoints": [
+      {
+        "language": "lldb.disassembly"
+      },
       {
         "language": "ada"
       },

>From 3699524618ed76f969cc26a63610fe54e3605139 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Thu, 15 May 2025 00:36:10 +0200
Subject: [PATCH 04/14] remove include

---
 lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
index 4fefd8b440c7d..d69da5bd02c1e 100644
--- a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
@@ -12,8 +12,6 @@
 #include "LLDBUtils.h"
 #include "Protocol/ProtocolRequests.h"
 #include "RequestHandler.h"
-#include <cstdint>
-#include <utility>
 #include <vector>
 
 namespace lldb_dap {

>From 61623deb7e249a8ca0c63e3f66955790da5e4ced Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sat, 17 May 2025 21:05:27 +0200
Subject: [PATCH 05/14] use load address as sourceReference

---
 lldb/include/lldb/API/SBFileSpec.h            |  3 +
 lldb/source/API/SBFileSpec.cpp                |  8 ++
 lldb/tools/lldb-dap/Breakpoint.cpp            | 18 +----
 .../Handler/BreakpointLocationsHandler.cpp    | 11 +--
 .../Handler/SetBreakpointsRequestHandler.cpp  | 11 +--
 .../lldb-dap/Handler/SourceRequestHandler.cpp | 18 ++---
 lldb/tools/lldb-dap/JSONUtils.cpp             | 75 +++++++++++++------
 lldb/tools/lldb-dap/JSONUtils.h               | 14 ++++
 8 files changed, 96 insertions(+), 62 deletions(-)

diff --git a/lldb/include/lldb/API/SBFileSpec.h 
b/lldb/include/lldb/API/SBFileSpec.h
index 36641843aabeb..303cb7d712cbf 100644
--- a/lldb/include/lldb/API/SBFileSpec.h
+++ b/lldb/include/lldb/API/SBFileSpec.h
@@ -10,6 +10,7 @@
 #define LLDB_API_SBFILESPEC_H
 
 #include "lldb/API/SBDefines.h"
+#include "lldb/API/SBStream.h"
 
 namespace lldb {
 
@@ -53,6 +54,8 @@ class LLDB_API SBFileSpec {
 
   uint32_t GetPath(char *dst_path, size_t dst_len) const;
 
+  bool GetPath(lldb::SBStream &dst_path) const;
+
   static int ResolvePath(const char *src_path, char *dst_path, size_t dst_len);
 
   bool GetDescription(lldb::SBStream &description) const;
diff --git a/lldb/source/API/SBFileSpec.cpp b/lldb/source/API/SBFileSpec.cpp
index a7df9afc4b8eb..cb44dac1d4fcc 100644
--- a/lldb/source/API/SBFileSpec.cpp
+++ b/lldb/source/API/SBFileSpec.cpp
@@ -19,6 +19,7 @@
 
 #include <cinttypes>
 #include <climits>
+#include <string>
 
 using namespace lldb;
 using namespace lldb_private;
@@ -147,6 +148,13 @@ uint32_t SBFileSpec::GetPath(char *dst_path, size_t 
dst_len) const {
   return result;
 }
 
+bool SBFileSpec::GetPath(SBStream &dst_path) const {
+  LLDB_INSTRUMENT_VA(this, dst_path);
+
+  std::string path = m_opaque_up->GetPath();
+  return dst_path->PutCString(path.c_str()) > 0;
+}
+
 const lldb_private::FileSpec *SBFileSpec::operator->() const {
   return m_opaque_up.get();
 }
diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp 
b/lldb/tools/lldb-dap/Breakpoint.cpp
index 87fcd15b0a568..a54a34e0f936d 100644
--- a/lldb/tools/lldb-dap/Breakpoint.cpp
+++ b/lldb/tools/lldb-dap/Breakpoint.cpp
@@ -79,27 +79,15 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() {
       breakpoint.source = CreateSource(line_entry);
     } else {
       // Breakpoint made by assembly
-      auto symbol_context = bp_addr.GetSymbolContext(
-          lldb::eSymbolContextSymbol | lldb::eSymbolContextModule);
-      if (symbol_context.IsValid()) {
-        auto symbol = symbol_context.GetSymbol();
+      auto symbol = bp_addr.GetSymbol();
+      if (symbol.IsValid()) {
         breakpoint.line =
             m_bp.GetTarget()
                 .ReadInstructions(symbol.GetStartAddress(), bp_addr, nullptr)
                 .GetSize() +
             1;
-        protocol::Source source;
-        source.name = symbol.GetName();
 
-        auto module = symbol_context.GetModule();
-        if (module.IsValid()) {
-          std::string path = module.GetFileSpec().GetDirectory();
-          path += "/";
-          path += module.GetFileSpec().GetFilename();
-          source.path = std::move(path);
-        }
-
-        breakpoint.source = std::move(source);
+        breakpoint.source = CreateAssemblySource(m_dap.target, bp_addr);
       }
     }
   }
diff --git a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp 
b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
index 06ada47a6f27f..c4d658caeee2d 100644
--- a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
@@ -7,7 +7,6 @@
 
//===----------------------------------------------------------------------===//
 
 #include "DAP.h"
-#include "LLDBUtils.h"
 #include "RequestHandler.h"
 #include <vector>
 
@@ -108,15 +107,11 @@ template <unsigned N>
 void BreakpointLocationsRequestHandler::AddAssemblyBreakpointLocations(
     llvm::SmallVector<std::pair<uint32_t, uint32_t>, N> &locations,
     int64_t sourceReference, uint32_t start_line, uint32_t end_line) const {
-  lldb::SBProcess process = dap.target.GetProcess();
-  lldb::SBThread thread =
-      process.GetThreadByIndexID(GetLLDBThreadIndexID(sourceReference));
-  lldb::SBFrame frame = 
thread.GetFrameAtIndex(GetLLDBFrameID(sourceReference));
-
-  if (!frame.IsValid())
+  lldb::SBAddress address(sourceReference, dap.target);
+  if (!address.IsValid())
     return;
 
-  lldb::SBSymbol symbol = frame.GetSymbol();
+  lldb::SBSymbol symbol = address.GetSymbol();
   if (!symbol.IsValid())
     return;
 
diff --git a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
index d69da5bd02c1e..7b401f06e9a85 100644
--- a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
@@ -9,7 +9,6 @@
 #include "DAP.h"
 #include "EventHelper.h"
 #include "JSONUtils.h"
-#include "LLDBUtils.h"
 #include "Protocol/ProtocolRequests.h"
 #include "RequestHandler.h"
 #include <vector>
@@ -99,15 +98,11 @@ SetBreakpointsRequestHandler::SetAssemblyBreakpoints(
   std::vector<protocol::Breakpoint> response_breakpoints;
   int64_t sourceReference = source.sourceReference.value_or(0);
 
-  lldb::SBProcess process = dap.target.GetProcess();
-  lldb::SBThread thread =
-      process.GetThreadByIndexID(GetLLDBThreadIndexID(sourceReference));
-  lldb::SBFrame frame = 
thread.GetFrameAtIndex(GetLLDBFrameID(sourceReference));
-
-  if (!frame.IsValid())
+  lldb::SBAddress address(sourceReference, dap.target);
+  if (!address.IsValid())
     return response_breakpoints;
 
-  lldb::SBSymbol symbol = frame.GetSymbol();
+  lldb::SBSymbol symbol = address.GetSymbol();
   if (!symbol.IsValid())
     return response_breakpoints; // Not yet supporting breakpoints in assembly
                                  // without a valid symbol
diff --git a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp
index fb396a3dc8862..9249e2aa6fef7 100644
--- a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp
@@ -11,6 +11,7 @@
 #include "LLDBUtils.h"
 #include "Protocol/ProtocolRequests.h"
 #include "Protocol/ProtocolTypes.h"
+#include "lldb/API/SBAddress.h"
 #include "lldb/API/SBExecutionContext.h"
 #include "lldb/API/SBFrame.h"
 #include "lldb/API/SBInstructionList.h"
@@ -19,6 +20,7 @@
 #include "lldb/API/SBSymbol.h"
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBThread.h"
+#include "lldb/lldb-types.h"
 #include "llvm/Support/Error.h"
 
 namespace lldb_dap {
@@ -34,18 +36,14 @@ SourceRequestHandler::Run(const protocol::SourceArguments 
&args) const {
     return llvm::make_error<DAPError>(
         "invalid arguments, expected source.sourceReference to be set");
 
-  lldb::SBProcess process = dap.target.GetProcess();
-  // Upper 32 bits is the thread index ID
-  lldb::SBThread thread =
-      process.GetThreadByIndexID(GetLLDBThreadIndexID(source));
-  // Lower 32 bits is the frame index
-  lldb::SBFrame frame = thread.GetFrameAtIndex(GetLLDBFrameID(source));
-  if (!frame.IsValid())
+  lldb::SBAddress address(source, dap.target);
+  if (!address.IsValid())
     return llvm::make_error<DAPError>("source not found");
 
+  lldb::SBSymbol symbol = address.GetSymbol();
+
   lldb::SBStream stream;
-  lldb::SBExecutionContext exe_ctx(frame);
-  lldb::SBSymbol symbol = frame.GetSymbol();
+  lldb::SBExecutionContext exe_ctx(dap.target);
 
   if (symbol.IsValid()) {
     lldb::SBInstructionList insts = symbol.GetInstructions(dap.target);
@@ -53,7 +51,7 @@ SourceRequestHandler::Run(const protocol::SourceArguments 
&args) const {
   } else {
     // No valid symbol, just return the disassembly.
     lldb::SBInstructionList insts = dap.target.ReadInstructions(
-        frame.GetPCAddress(), dap.number_of_assembly_lines_for_nodebug);
+        address, dap.number_of_assembly_lines_for_nodebug);
     insts.GetDescription(stream, exe_ctx);
   }
 
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 714947a4d3b9c..c8151c3d64ea4 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -490,6 +490,13 @@ CreateExceptionBreakpointFilter(const ExceptionBreakpoint 
&bp) {
   return filter;
 }
 
+static std::string GetLoadAddressString(const lldb::addr_t addr) {
+  std::string result;
+  llvm::raw_string_ostream os(result);
+  os << llvm::format_hex(addr, 18);
+  return result;
+}
+
 protocol::Source CreateSource(const lldb::SBFileSpec &file) {
   protocol::Source source;
   if (file.IsValid()) {
@@ -516,6 +523,43 @@ protocol::Source CreateSource(llvm::StringRef source_path) 
{
   return source;
 }
 
+protocol::Source CreateAssemblySource(const lldb::SBTarget &target,
+                                      lldb::SBAddress &address) {
+  protocol::Source source;
+
+  auto symbol = address.GetSymbol();
+  std::string name;
+  if (symbol.IsValid()) {
+    source.sourceReference = symbol.GetStartAddress().GetLoadAddress(target);
+    name = symbol.GetName();
+  } else {
+    const auto load_addr = address.GetLoadAddress(target);
+    source.sourceReference = load_addr;
+    name = GetLoadAddressString(load_addr);
+  }
+
+  lldb::SBModule module = address.GetModule();
+  if (module.IsValid()) {
+    lldb::SBFileSpec file_spec = module.GetFileSpec();
+    if (file_spec.IsValid()) {
+      lldb::SBStream module_path;
+      if (file_spec.GetPath(module_path)) {
+        std::string path = module_path.GetData();
+        source.path = path + '`' + name;
+      }
+    }
+  }
+
+  source.name = std::move(name);
+
+  // Mark the source as deemphasized since users will only be able to view
+  // assembly for these frames.
+  source.presentationHint =
+      protocol::Source::PresentationHint::eSourcePresentationHintDeemphasize;
+
+  return source;
+}
+
 bool ShouldDisplayAssemblySource(
     const lldb::SBLineEntry &line_entry,
     lldb::StopDisassemblyType stop_disassembly_display) {
@@ -619,12 +663,10 @@ CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat 
&format,
     frame_name = name;
   }
 
-  if (frame_name.empty()) {
+  if (frame_name.empty())
     // If the function name is unavailable, display the pc address as a 
16-digit
     // hex string, e.g. "0x0000000000012345"
-    llvm::raw_string_ostream os(frame_name);
-    os << llvm::format_hex(frame.GetPC(), 18);
-  }
+    frame_name = GetLoadAddressString(frame.GetPC());
 
   // We only include `[opt]` if a custom frame format is not specified.
   if (!format && frame.GetFunction().GetIsOptimized())
@@ -641,17 +683,10 @@ CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat 
&format,
   } else if (frame.GetSymbol().IsValid()) {
     // If no source is associated with the frame, use the DAPFrameID to track
     // the 'source' and generate assembly.
-    llvm::json::Object source;
-    EmplaceSafeString(source, "name", frame_name);
-    char buf[PATH_MAX] = {0};
-    size_t size = frame.GetModule().GetFileSpec().GetPath(buf, PATH_MAX);
-    EmplaceSafeString(source, "path",
-                      std::string(buf, size) + '`' + frame_name);
-    source.try_emplace("sourceReference", MakeDAPFrameID(frame));
-    // Mark the source as deemphasized since users will only be able to view
-    // assembly for these frames.
-    EmplaceSafeString(source, "presentationHint", "deemphasize");
-    object.try_emplace("source", std::move(source));
+    auto frame_address = frame.GetPCAddress();
+    object.try_emplace("source", CreateAssemblySource(
+                                     
frame.GetThread().GetProcess().GetTarget(),
+                                     frame_address));
 
     // Calculate the line of the current PC from the start of the current
     // symbol.
@@ -665,12 +700,10 @@ CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat 
&format,
     object.try_emplace("column", 1);
   } else {
     // No valid line entry or symbol.
-    llvm::json::Object source;
-    EmplaceSafeString(source, "name", frame_name);
-    source.try_emplace("sourceReference", MakeDAPFrameID(frame));
-    EmplaceSafeString(source, "presentationHint", "deemphasize");
-    object.try_emplace("source", std::move(source));
-
+    auto frame_address = frame.GetPCAddress();
+    object.try_emplace("source", CreateAssemblySource(
+                                     
frame.GetThread().GetProcess().GetTarget(),
+                                     frame_address));
     object.try_emplace("line", 1);
     object.try_emplace("column", 1);
   }
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index 783f291338d8c..ac9b39739104f 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -269,6 +269,20 @@ protocol::Source CreateSource(const lldb::SBLineEntry 
&line_entry);
 ///     definition outlined by Microsoft.
 protocol::Source CreateSource(llvm::StringRef source_path);
 
+/// Create a "Source" object for a given frame, using its assembly for source.
+///
+/// \param[in] target
+///     The relevant target.
+///
+/// \param[in] address
+///     The address to use when creating the "Source" object.
+///
+/// \return
+///     A "Source" JSON object that follows the formal JSON
+///     definition outlined by Microsoft.
+protocol::Source CreateAssemblySource(const lldb::SBTarget &target,
+                                      lldb::SBAddress &address);
+
 /// Return true if the given line entry should be displayed as assembly.
 ///
 /// \param[in] line_entry

>From f5fd76de3ad25b9cbf6ce065e06c98ff30b070a8 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 18 May 2025 02:22:19 +0200
Subject: [PATCH 06/14] add breakpoint-assembly test

---
 .../test/tools/lldb-dap/dap_server.py         |  7 ++++
 .../test/tools/lldb-dap/lldbdap_testcase.py   | 10 +++++
 .../lldb-dap/breakpoint-assembly/Makefile     |  3 ++
 .../TestDAP_breakpointAssembly.py             | 42 +++++++++++++++++++
 .../tools/lldb-dap/breakpoint-assembly/main.c | 14 +++++++
 .../breakpoint/TestDAP_setBreakpoints.py      |  1 +
 .../TestDAP_setExceptionBreakpoints.py        |  1 +
 .../TestDAP_setFunctionBreakpoints.py         |  1 +
 8 files changed, 79 insertions(+)
 create mode 100644 lldb/test/API/tools/lldb-dap/breakpoint-assembly/Makefile
 create mode 100644 
lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
 create mode 100644 lldb/test/API/tools/lldb-dap/breakpoint-assembly/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 70fd0b0c419db..4a907a5e36901 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -955,6 +955,13 @@ def request_setBreakpoints(self, file_path, line_array, 
data=None):
         """
         (dir, base) = os.path.split(file_path)
         source_dict = {"name": base, "path": file_path}
+        return self.request_setBreakpoints_with_source(source_dict, 
line_array, data)
+
+    def request_setBreakpointsAssembly(self, sourceReference, line_array, 
data=None):
+        source_dict = {"sourceReference": sourceReference}
+        return self.request_setBreakpoints_with_source(source_dict, 
line_array, data)
+
+    def request_setBreakpoints_with_source(self, source_dict, line_array, 
data=None):
         args_dict = {
             "source": source_dict,
             "sourceModified": False,
diff --git 
a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index afdc746ed0d0d..427f66a7da0c8 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -63,6 +63,16 @@ def set_source_breakpoints(self, source_path, lines, 
data=None):
         for breakpoint in breakpoints:
             breakpoint_ids.append("%i" % (breakpoint["id"]))
         return breakpoint_ids
+    
+    def set_source_breakpoints_assembly(self, source_reference, lines, 
data=None):
+        response = 
self.dap_server.request_setBreakpointsAssembly(source_reference, lines, data)
+        if response is None:
+            return []
+        breakpoints = response["body"]["breakpoints"]
+        breakpoint_ids = []
+        for breakpoint in breakpoints:
+            breakpoint_ids.append("%i" % (breakpoint["id"]))
+        return breakpoint_ids
 
     def set_function_breakpoints(self, functions, condition=None, 
hitCondition=None):
         """Sets breakpoints by function name given an array of function names
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/Makefile 
b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/Makefile
new file mode 100644
index 0000000000000..10495940055b6
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git 
a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
 
b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
new file mode 100644
index 0000000000000..ba9df3a18590b
--- /dev/null
+++ 
b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
@@ -0,0 +1,42 @@
+"""
+Test lldb-dap setBreakpoints request
+"""
+
+
+import dap_server
+import shutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_setBreakpointsAssembly(lldbdap_testcase.DAPTestCaseBase):
+    # @skipIfWindows
+    def test_functionality(self):
+        """Tests hitting assembly source breakpoints"""
+        program = self.getBuildArtifact("a.out")
+        self.build_and_launch(program)
+
+        self.dap_server.request_evaluate(
+            "`settings set stop-disassembly-display no-debuginfo", 
context="repl"
+        )
+
+        assmebly_func_breakpoints = 
self.set_function_breakpoints(["assembly_func"])
+        self.continue_to_breakpoints(assmebly_func_breakpoints)
+
+        assembly_func_frame = self.get_stackFrames()[0]
+        self.assertIn(
+            "sourceReference",
+            assembly_func_frame.get("source"),
+            "Expected assembly source frame",
+        )
+
+        line = assembly_func_frame["line"]
+
+        # Set an assembly breakpoint in the next line and check that it's hit
+        assembly_breakpoint_ids = self.set_source_breakpoints_assembly(
+            assembly_func_frame["source"]["sourceReference"], [line + 1]
+        )
+        self.continue_to_breakpoints(assembly_breakpoint_ids)
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/main.c 
b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/main.c
new file mode 100644
index 0000000000000..350739006f903
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/main.c
@@ -0,0 +1,14 @@
+#include <stddef.h>
+
+__attribute__((nodebug)) int assembly_func(int n) {
+  n += 1;
+  n += 2;
+  n += 3;
+
+  return n;
+}
+
+int main(int argc, char const *argv[]) {
+  assembly_func(10);
+  return 0;
+}
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py 
b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
index 26df2573555df..aae1251b17c93 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
@@ -12,6 +12,7 @@
 import os
 
 
+@skip("Temporarily disable the breakpoint tests")
 class TestDAP_setBreakpoints(lldbdap_testcase.DAPTestCaseBase):
     def setUp(self):
         lldbdap_testcase.DAPTestCaseBase.setUp(self)
diff --git 
a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py 
b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
index 92ac66cd44c5d..4dc8c5b3c7ded 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
@@ -10,6 +10,7 @@
 import lldbdap_testcase
 
 
+@skip("Temporarily disable the breakpoint tests")
 class TestDAP_setExceptionBreakpoints(lldbdap_testcase.DAPTestCaseBase):
     @skipIfWindows
     def test_functionality(self):
diff --git 
a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py 
b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
index 946595f639edc..baaca4d974d5d 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
@@ -10,6 +10,7 @@
 import lldbdap_testcase
 
 
+@skip("Temporarily disable the breakpoint tests")
 class TestDAP_setFunctionBreakpoints(lldbdap_testcase.DAPTestCaseBase):
     @skipIfWindows
     def test_set_and_clear(self):

>From 40f68e418bfbb6564b3834382c4a33a3104fc33d Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 18 May 2025 10:23:11 +0200
Subject: [PATCH 07/14] python format

---
 .../lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py       | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git 
a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 427f66a7da0c8..3bf649a087fdb 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -63,9 +63,11 @@ def set_source_breakpoints(self, source_path, lines, 
data=None):
         for breakpoint in breakpoints:
             breakpoint_ids.append("%i" % (breakpoint["id"]))
         return breakpoint_ids
-    
+
     def set_source_breakpoints_assembly(self, source_reference, lines, 
data=None):
-        response = 
self.dap_server.request_setBreakpointsAssembly(source_reference, lines, data)
+        response = self.dap_server.request_setBreakpointsAssembly(
+            source_reference, lines, data
+        )
         if response is None:
             return []
         breakpoints = response["body"]["breakpoints"]

>From 199512fd7a0900d45070b95dd52ef5ef136e2719 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 18 May 2025 10:54:43 +0200
Subject: [PATCH 08/14] restore SBFileSpec and fix assembly breakpoints CR

---
 lldb/include/lldb/API/SBFileSpec.h            |  2 -
 lldb/source/API/SBFileSpec.cpp                |  7 ---
 lldb/tools/lldb-dap/DAP.h                     |  2 +-
 .../Handler/BreakpointLocationsHandler.cpp    | 47 ++++++++++---------
 lldb/tools/lldb-dap/Handler/RequestHandler.h  | 17 ++++---
 .../Handler/SetBreakpointsRequestHandler.cpp  |  9 ++--
 lldb/tools/lldb-dap/JSONUtils.cpp             |  6 +--
 lldb/tools/lldb-dap/LLDBUtils.cpp             | 10 ++++
 lldb/tools/lldb-dap/LLDBUtils.h               | 10 ++++
 9 files changed, 60 insertions(+), 50 deletions(-)

diff --git a/lldb/include/lldb/API/SBFileSpec.h 
b/lldb/include/lldb/API/SBFileSpec.h
index 303cb7d712cbf..1bb28b2ddab01 100644
--- a/lldb/include/lldb/API/SBFileSpec.h
+++ b/lldb/include/lldb/API/SBFileSpec.h
@@ -54,8 +54,6 @@ class LLDB_API SBFileSpec {
 
   uint32_t GetPath(char *dst_path, size_t dst_len) const;
 
-  bool GetPath(lldb::SBStream &dst_path) const;
-
   static int ResolvePath(const char *src_path, char *dst_path, size_t dst_len);
 
   bool GetDescription(lldb::SBStream &description) const;
diff --git a/lldb/source/API/SBFileSpec.cpp b/lldb/source/API/SBFileSpec.cpp
index cb44dac1d4fcc..f18857f59171a 100644
--- a/lldb/source/API/SBFileSpec.cpp
+++ b/lldb/source/API/SBFileSpec.cpp
@@ -148,13 +148,6 @@ uint32_t SBFileSpec::GetPath(char *dst_path, size_t 
dst_len) const {
   return result;
 }
 
-bool SBFileSpec::GetPath(SBStream &dst_path) const {
-  LLDB_INSTRUMENT_VA(this, dst_path);
-
-  std::string path = m_opaque_up->GetPath();
-  return dst_path->PutCString(path.c_str()) > 0;
-}
-
 const lldb_private::FileSpec *SBFileSpec::operator->() const {
   return m_opaque_up.get();
 }
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index b0fe265b7bca1..20f95be792f41 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -222,7 +222,7 @@ struct DAP {
   /// @}
 
   /// Number of lines of assembly code to show when no debug info is available.
-  uint32_t number_of_assembly_lines_for_nodebug = 32;
+  static constexpr uint32_t number_of_assembly_lines_for_nodebug = 32;
 
   /// Creates a new DAP sessions.
   ///
diff --git a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp 
b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
index c4d658caeee2d..794b83a9e0e1e 100644
--- a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
@@ -8,6 +8,7 @@
 
 #include "DAP.h"
 #include "RequestHandler.h"
+#include <optional>
 #include <vector>
 
 namespace lldb_dap {
@@ -24,15 +25,15 @@ BreakpointLocationsRequestHandler::Run(
   uint32_t end_column =
       args.endColumn.value_or(std::numeric_limits<uint32_t>::max());
 
-  // Find all relevant lines & columns
-  llvm::SmallVector<std::pair<uint32_t, uint32_t>, 8> locations;
-  if (args.source.sourceReference) {
-    AddAssemblyBreakpointLocations(locations, *args.source.sourceReference,
-                                   start_line, end_line);
-  } else {
+  // Find all relevant lines & columns.
+  std::vector<std::pair<uint32_t, uint32_t>> locations;
+  if (args.source.sourceReference)
+    locations = GetAssemblyBreakpointLocations(*args.source.sourceReference,
+                                               start_line, end_line);
+  else {
     std::string path = args.source.path.value_or("");
-    AddSourceBreakpointLocations(locations, std::move(path), start_line,
-                                 start_column, end_line, end_column);
+    locations = GetSourceBreakpointLocations(
+        std::move(path), start_line, start_column, end_line, end_column);
   }
 
   // The line entries are sorted by addresses, but we must return the list
@@ -41,23 +42,19 @@ BreakpointLocationsRequestHandler::Run(
   locations.erase(llvm::unique(locations), locations.end());
 
   std::vector<protocol::BreakpointLocation> breakpoint_locations;
-  for (auto &l : locations) {
-    protocol::BreakpointLocation lc;
-    lc.line = l.first;
-    lc.column = l.second;
-    breakpoint_locations.push_back(std::move(lc));
-  }
+  for (auto &l : locations)
+    breakpoint_locations.push_back(
+        {l.first, l.second, std::nullopt, std::nullopt});
 
   return protocol::BreakpointLocationsResponseBody{
       /*breakpoints=*/std::move(breakpoint_locations)};
 }
 
-template <unsigned N>
-void BreakpointLocationsRequestHandler::AddSourceBreakpointLocations(
-    llvm::SmallVector<std::pair<uint32_t, uint32_t>, N> &locations,
+std::vector<std::pair<uint32_t, uint32_t>>
+BreakpointLocationsRequestHandler::GetSourceBreakpointLocations(
     std::string path, uint32_t start_line, uint32_t start_column,
     uint32_t end_line, uint32_t end_column) const {
-
+  std::vector<std::pair<uint32_t, uint32_t>> locations;
   lldb::SBFileSpec file_spec(path.c_str(), true);
   lldb::SBSymbolContextList compile_units =
       dap.target.FindCompileUnits(file_spec);
@@ -101,19 +98,21 @@ void 
BreakpointLocationsRequestHandler::AddSourceBreakpointLocations(
       locations.emplace_back(line, column);
     }
   }
+
+  return locations;
 }
 
-template <unsigned N>
-void BreakpointLocationsRequestHandler::AddAssemblyBreakpointLocations(
-    llvm::SmallVector<std::pair<uint32_t, uint32_t>, N> &locations,
+std::vector<std::pair<uint32_t, uint32_t>>
+BreakpointLocationsRequestHandler::GetAssemblyBreakpointLocations(
     int64_t sourceReference, uint32_t start_line, uint32_t end_line) const {
+  std::vector<std::pair<uint32_t, uint32_t>> locations;
   lldb::SBAddress address(sourceReference, dap.target);
   if (!address.IsValid())
-    return;
+    return locations;
 
   lldb::SBSymbol symbol = address.GetSymbol();
   if (!symbol.IsValid())
-    return;
+    return locations;
 
   // start_line is relative to the symbol's start address
   lldb::SBInstructionList insts = symbol.GetInstructions(dap.target);
@@ -121,6 +120,8 @@ void 
BreakpointLocationsRequestHandler::AddAssemblyBreakpointLocations(
        ++i) {
     locations.emplace_back(i, 1);
   }
+
+  return locations;
 }
 
 } // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h 
b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index 80898d1ee5ef1..e708abb50d5c0 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -23,6 +23,7 @@
 #include <optional>
 #include <type_traits>
 #include <variant>
+#include <vector>
 
 template <typename T> struct is_optional : std::false_type {};
 
@@ -234,15 +235,13 @@ class BreakpointLocationsRequestHandler
   llvm::Expected<protocol::BreakpointLocationsResponseBody>
   Run(const protocol::BreakpointLocationsArguments &args) const override;
 
-  template <unsigned N>
-  void AddSourceBreakpointLocations(
-      llvm::SmallVector<std::pair<uint32_t, uint32_t>, N> &locations,
-      std::string path, uint32_t start_line, uint32_t start_column,
-      uint32_t end_line, uint32_t end_column) const;
-  template <unsigned N>
-  void AddAssemblyBreakpointLocations(
-      llvm::SmallVector<std::pair<uint32_t, uint32_t>, N> &locations,
-      int64_t sourceReference, uint32_t start_line, uint32_t end_line) const;
+  std::vector<std::pair<uint32_t, uint32_t>>
+  GetSourceBreakpointLocations(std::string path, uint32_t start_line,
+                               uint32_t start_column, uint32_t end_line,
+                               uint32_t end_column) const;
+  std::vector<std::pair<uint32_t, uint32_t>>
+  GetAssemblyBreakpointLocations(int64_t sourceReference, uint32_t start_line,
+                                 uint32_t end_line) const;
 };
 
 class CompletionsRequestHandler : public LegacyRequestHandler {
diff --git a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
index 7b401f06e9a85..bf0b584753c07 100644
--- a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
@@ -103,9 +103,10 @@ SetBreakpointsRequestHandler::SetAssemblyBreakpoints(
     return response_breakpoints;
 
   lldb::SBSymbol symbol = address.GetSymbol();
-  if (!symbol.IsValid())
-    return response_breakpoints; // Not yet supporting breakpoints in assembly
-                                 // without a valid symbol
+  if (!symbol.IsValid()) {
+    // Not yet supporting breakpoints in assembly without a valid symbol.
+    return response_breakpoints;
+  }
 
   llvm::DenseMap<uint32_t, SourceBreakpoint> request_bps;
   if (breakpoints) {
@@ -115,7 +116,7 @@ SetBreakpointsRequestHandler::SetAssemblyBreakpoints(
       const auto [iv, inserted] =
           dap.assembly_breakpoints[sourceReference].try_emplace(
               src_bp.GetLine(), src_bp);
-      // We check if this breakpoint already exists to update it
+      // We check if this breakpoint already exists to update it.
       if (inserted)
         iv->getSecond().SetBreakpoint(symbol);
       else
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index c8151c3d64ea4..1d2a6ff60e502 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -542,11 +542,9 @@ protocol::Source CreateAssemblySource(const lldb::SBTarget 
&target,
   if (module.IsValid()) {
     lldb::SBFileSpec file_spec = module.GetFileSpec();
     if (file_spec.IsValid()) {
-      lldb::SBStream module_path;
-      if (file_spec.GetPath(module_path)) {
-        std::string path = module_path.GetData();
+      std::string path = GetSBFileSpecPath(file_spec);
+      if (!path.empty())
         source.path = path + '`' + name;
-      }
     }
   }
 
diff --git a/lldb/tools/lldb-dap/LLDBUtils.cpp 
b/lldb/tools/lldb-dap/LLDBUtils.cpp
index 0e7bb2b9058a7..3c7623ec1215d 100644
--- a/lldb/tools/lldb-dap/LLDBUtils.cpp
+++ b/lldb/tools/lldb-dap/LLDBUtils.cpp
@@ -20,6 +20,7 @@
 #include "llvm/Support/JSON.h"
 #include "llvm/Support/raw_ostream.h"
 
+#include <cstring>
 #include <mutex>
 #include <system_error>
 
@@ -242,4 +243,13 @@ ScopeSyncMode::ScopeSyncMode(lldb::SBDebugger &debugger)
 
 ScopeSyncMode::~ScopeSyncMode() { m_debugger.SetAsync(m_async); }
 
+std::string GetSBFileSpecPath(const lldb::SBFileSpec &file_spec) {
+  const auto directory_length = ::strlen(file_spec.GetDirectory());
+  const auto file_name_length = ::strlen(file_spec.GetFilename());
+
+  std::string path(directory_length + file_name_length + 2, '\0');
+  file_spec.GetPath(path.data(), path.length());
+  return path;
+}
+
 } // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/LLDBUtils.h b/lldb/tools/lldb-dap/LLDBUtils.h
index 711fc6051231c..7fdf4b859ee61 100644
--- a/lldb/tools/lldb-dap/LLDBUtils.h
+++ b/lldb/tools/lldb-dap/LLDBUtils.h
@@ -13,6 +13,7 @@
 #include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBEnvironment.h"
 #include "lldb/API/SBError.h"
+#include "lldb/API/SBFileSpec.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
@@ -161,6 +162,15 @@ uint32_t GetLLDBFrameID(uint64_t dap_frame_id);
 lldb::SBEnvironment
 GetEnvironmentFromArguments(const llvm::json::Object &arguments);
 
+/// Gets an SBFileSpec and returns its path as a string.
+///
+/// \param[in] file_spec
+///     The file spec.
+///
+/// \return
+///     The file path as a string.
+std::string GetSBFileSpecPath(const lldb::SBFileSpec &file_spec);
+
 /// Helper for sending telemetry to lldb server, if client-telemetry is 
enabled.
 class TelemetryDispatcher {
 public:

>From dbad33b314bb59f6e0d22fd07dddb35e2a0e30d9 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 18 May 2025 12:57:59 +0200
Subject: [PATCH 09/14] abstracted source breakpoints maps by DAP

---
 lldb/tools/lldb-dap/Breakpoint.cpp            |   4 +-
 lldb/tools/lldb-dap/DAP.cpp                   |  75 +++++++++++
 lldb/tools/lldb-dap/DAP.h                     |  29 +++-
 lldb/tools/lldb-dap/Handler/RequestHandler.h  |   9 --
 .../Handler/SetBreakpointsRequestHandler.cpp  | 125 +-----------------
 lldb/tools/lldb-dap/SourceBreakpoint.cpp      |  54 +++++---
 lldb/tools/lldb-dap/SourceBreakpoint.h        |   7 +-
 7 files changed, 140 insertions(+), 163 deletions(-)

diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp 
b/lldb/tools/lldb-dap/Breakpoint.cpp
index a54a34e0f936d..fd7531f42c518 100644
--- a/lldb/tools/lldb-dap/Breakpoint.cpp
+++ b/lldb/tools/lldb-dap/Breakpoint.cpp
@@ -71,10 +71,10 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() {
     auto line_entry = bp_addr.GetLineEntry();
     if (!ShouldDisplayAssemblySource(line_entry, stop_disassembly_display)) {
       const auto line = line_entry.GetLine();
-      if (line != UINT32_MAX)
+      if (line != LLDB_INVALID_LINE_NUMBER)
         breakpoint.line = line;
       const auto column = line_entry.GetColumn();
-      if (column != 0)
+      if (column != LLDB_INVALID_COLUMN_NUMBER)
         breakpoint.column = column;
       breakpoint.source = CreateSource(line_entry);
     } else {
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 0d5eba6c40961..1fe46fc619d73 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -1620,6 +1620,81 @@ void DAP::EventThread() {
   }
 }
 
+std::vector<protocol::Breakpoint> DAP::SetSourceBreakpoints(
+    const protocol::Source &source,
+    const std::optional<std::vector<protocol::SourceBreakpoint>> &breakpoints) 
{
+  std::vector<protocol::Breakpoint> response_breakpoints;
+  if (source.sourceReference) {
+    // breakpoint set by assembly source.
+    auto &existing_breakpoints_pos =
+        m_source_assembly_breakpoints[*source.sourceReference];
+    response_breakpoints =
+        SetSourceBreakpoints(source, breakpoints, existing_breakpoints_pos);
+  } else {
+    // breakpoint set by a regular source file.
+    const auto path = source.path.value_or("");
+    auto &existing_breakpoints_pos = m_source_breakpoints[path];
+    response_breakpoints =
+        SetSourceBreakpoints(source, breakpoints, existing_breakpoints_pos);
+  }
+
+  return response_breakpoints;
+}
+
+std::vector<protocol::Breakpoint> DAP::SetSourceBreakpoints(
+    const protocol::Source &source,
+    const std::optional<std::vector<protocol::SourceBreakpoint>> &breakpoints,
+    SourceBreakpointMap &existing_breakpoints) {
+  std::vector<protocol::Breakpoint> response_breakpoints;
+
+  SourceBreakpointMap request_breakpoints;
+  if (breakpoints) {
+    for (const auto &bp : *breakpoints) {
+      SourceBreakpoint src_bp(*this, bp, source);
+      std::pair<uint32_t, uint32_t> bp_pos(src_bp.GetLine(),
+                                           src_bp.GetColumn());
+      request_breakpoints.try_emplace(bp_pos, src_bp);
+
+      const auto [iv, inserted] =
+          existing_breakpoints.try_emplace(bp_pos, src_bp);
+      // We check if this breakpoint already exists to update it.
+      if (inserted)
+        iv->second.SetBreakpoint();
+      else
+        iv->second.UpdateBreakpoint(src_bp);
+
+      protocol::Breakpoint response_breakpoint =
+          iv->second.ToProtocolBreakpoint();
+      response_breakpoint.source = source;
+
+      if (!response_breakpoint.line &&
+          src_bp.GetLine() != LLDB_INVALID_LINE_NUMBER)
+        response_breakpoint.line = src_bp.GetLine();
+      if (!response_breakpoint.column &&
+          src_bp.GetColumn() != LLDB_INVALID_COLUMN_NUMBER)
+        response_breakpoint.column = src_bp.GetColumn();
+      response_breakpoints.push_back(response_breakpoint);
+    }
+  }
+
+  // Delete any breakpoints in this source file that aren't in the
+  // request_bps set. There is no call to remove breakpoints other than
+  // calling this function with a smaller or empty "breakpoints" list.
+  for (auto it = existing_breakpoints.begin();
+       it != existing_breakpoints.end();) {
+    auto request_pos = request_breakpoints.find(it->first);
+    if (request_pos == request_breakpoints.end()) {
+      // This breakpoint no longer exists in this source file, delete it
+      target.BreakpointDelete(it->second.GetID());
+      it = existing_breakpoints.erase(it);
+    } else {
+      ++it;
+    }
+  }
+
+  return response_breakpoints;
+}
+
 void DAP::RegisterRequests() {
   RegisterRequest<AttachRequestHandler>();
   RegisterRequest<BreakpointLocationsRequestHandler>();
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 20f95be792f41..3a0a7fc1678ba 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -60,7 +60,7 @@
 
 namespace lldb_dap {
 
-typedef llvm::DenseMap<std::pair<uint32_t, uint32_t>, SourceBreakpoint>
+typedef std::map<std::pair<uint32_t, uint32_t>, SourceBreakpoint>
     SourceBreakpointMap;
 typedef llvm::StringMap<FunctionBreakpoint> FunctionBreakpointMap;
 typedef llvm::DenseMap<lldb::addr_t, InstructionBreakpoint>
@@ -168,9 +168,6 @@ struct DAP {
   lldb::SBTarget target;
   Variables variables;
   lldb::SBBroadcaster broadcaster;
-  llvm::StringMap<SourceBreakpointMap> source_breakpoints;
-  llvm::DenseMap<int64_t, llvm::DenseMap<uint32_t, SourceBreakpoint>>
-      assembly_breakpoints;
   FunctionBreakpointMap function_breakpoints;
   InstructionBreakpointMap instruction_breakpoints;
   std::optional<std::vector<ExceptionBreakpoint>> exception_breakpoints;
@@ -428,7 +425,28 @@ struct DAP {
   void StartEventThread();
   void StartProgressEventThread();
 
+  /// Sets the given protocol `breakpoints` in the given `source`, while
+  /// removing any existing breakpoints in the given source if they are not in
+  /// `breakpoint`.
+  ///
+  /// \param[in] source
+  ///   The relevant source of the breakpoints.
+  ///
+  /// \param[in] breakpoints
+  ///   The breakpoints to set.
+  ///
+  /// \return a vector of the breakpoints that were set.
+  std::vector<protocol::Breakpoint> SetSourceBreakpoints(
+      const protocol::Source &source,
+      const std::optional<std::vector<protocol::SourceBreakpoint>>
+          &breakpoints);
+
 private:
+  std::vector<protocol::Breakpoint> SetSourceBreakpoints(
+      const protocol::Source &source,
+      const std::optional<std::vector<protocol::SourceBreakpoint>> 
&breakpoints,
+      SourceBreakpointMap &existing_breakpoints);
+
   /// Registration of request handler.
   /// @{
   void RegisterRequests();
@@ -457,6 +475,9 @@ struct DAP {
 
   std::mutex m_active_request_mutex;
   const protocol::Request *m_active_request;
+
+  llvm::StringMap<SourceBreakpointMap> m_source_breakpoints;
+  llvm::DenseMap<int64_t, SourceBreakpointMap> m_source_assembly_breakpoints;
 };
 
 } // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h 
b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index e708abb50d5c0..54f728414021e 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -388,15 +388,6 @@ class SetBreakpointsRequestHandler
   }
   llvm::Expected<protocol::SetBreakpointsResponseBody>
   Run(const protocol::SetBreakpointsArguments &args) const override;
-
-  std::vector<protocol::Breakpoint> SetSourceBreakpoints(
-      const protocol::Source &source,
-      const std::optional<std::vector<protocol::SourceBreakpoint>> 
&breakpoints)
-      const;
-  std::vector<protocol::Breakpoint> SetAssemblyBreakpoints(
-      const protocol::Source &source,
-      const std::optional<std::vector<protocol::SourceBreakpoint>> 
&breakpoints)
-      const;
 };
 
 class SetExceptionBreakpointsRequestHandler : public LegacyRequestHandler {
diff --git a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
index bf0b584753c07..0ff88f62f8f51 100644
--- a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
@@ -22,130 +22,9 @@ namespace lldb_dap {
 llvm::Expected<protocol::SetBreakpointsResponseBody>
 SetBreakpointsRequestHandler::Run(
     const protocol::SetBreakpointsArguments &args) const {
-  const auto &source = args.source;
-  std::vector<protocol::Breakpoint> response_breakpoints;
-  if (source.sourceReference)
-    response_breakpoints = SetAssemblyBreakpoints(source, args.breakpoints);
-  else if (source.path)
-    response_breakpoints = SetSourceBreakpoints(source, args.breakpoints);
-
+  const auto response_breakpoints =
+      dap.SetSourceBreakpoints(args.source, args.breakpoints);
   return protocol::SetBreakpointsResponseBody{std::move(response_breakpoints)};
 }
 
-std::vector<protocol::Breakpoint>
-SetBreakpointsRequestHandler::SetSourceBreakpoints(
-    const protocol::Source &source,
-    const std::optional<std::vector<protocol::SourceBreakpoint>> &breakpoints)
-    const {
-  std::vector<protocol::Breakpoint> response_breakpoints;
-  std::string path = source.path.value_or("");
-
-  // Decode the source breakpoint infos for this "setBreakpoints" request
-  SourceBreakpointMap request_bps;
-  // "breakpoints" may be unset, in which case we treat it the same as being 
set
-  // to an empty array.
-  if (breakpoints) {
-    for (const auto &bp : *breakpoints) {
-      SourceBreakpoint src_bp(dap, bp);
-      std::pair<uint32_t, uint32_t> bp_pos(src_bp.GetLine(),
-                                           src_bp.GetColumn());
-      request_bps.try_emplace(bp_pos, src_bp);
-      const auto [iv, inserted] =
-          dap.source_breakpoints[path].try_emplace(bp_pos, src_bp);
-      // We check if this breakpoint already exists to update it
-      if (inserted)
-        iv->getSecond().SetBreakpoint(path.data());
-      else
-        iv->getSecond().UpdateBreakpoint(src_bp);
-
-      protocol::Breakpoint response_bp = 
iv->getSecond().ToProtocolBreakpoint();
-
-      // Use the path from the request if it is set
-      if (!path.empty())
-        response_bp.source = CreateSource(path);
-
-      if (!response_bp.line)
-        response_bp.line = src_bp.GetLine();
-      if (!response_bp.column)
-        response_bp.column = src_bp.GetColumn();
-      response_breakpoints.push_back(response_bp);
-    }
-  }
-
-  // Delete any breakpoints in this source file that aren't in the
-  // request_bps set. There is no call to remove breakpoints other than
-  // calling this function with a smaller or empty "breakpoints" list.
-  auto old_src_bp_pos = dap.source_breakpoints.find(path);
-  if (old_src_bp_pos != dap.source_breakpoints.end()) {
-    for (auto &old_bp : old_src_bp_pos->second) {
-      auto request_pos = request_bps.find(old_bp.first);
-      if (request_pos == request_bps.end()) {
-        // This breakpoint no longer exists in this source file, delete it
-        dap.target.BreakpointDelete(old_bp.second.GetID());
-        old_src_bp_pos->second.erase(old_bp.first);
-      }
-    }
-  }
-
-  return response_breakpoints;
-}
-
-std::vector<protocol::Breakpoint>
-SetBreakpointsRequestHandler::SetAssemblyBreakpoints(
-    const protocol::Source &source,
-    const std::optional<std::vector<protocol::SourceBreakpoint>> &breakpoints)
-    const {
-  std::vector<protocol::Breakpoint> response_breakpoints;
-  int64_t sourceReference = source.sourceReference.value_or(0);
-
-  lldb::SBAddress address(sourceReference, dap.target);
-  if (!address.IsValid())
-    return response_breakpoints;
-
-  lldb::SBSymbol symbol = address.GetSymbol();
-  if (!symbol.IsValid()) {
-    // Not yet supporting breakpoints in assembly without a valid symbol.
-    return response_breakpoints;
-  }
-
-  llvm::DenseMap<uint32_t, SourceBreakpoint> request_bps;
-  if (breakpoints) {
-    for (const auto &bp : *breakpoints) {
-      SourceBreakpoint src_bp(dap, bp);
-      request_bps.try_emplace(src_bp.GetLine(), src_bp);
-      const auto [iv, inserted] =
-          dap.assembly_breakpoints[sourceReference].try_emplace(
-              src_bp.GetLine(), src_bp);
-      // We check if this breakpoint already exists to update it.
-      if (inserted)
-        iv->getSecond().SetBreakpoint(symbol);
-      else
-        iv->getSecond().UpdateBreakpoint(src_bp);
-
-      protocol::Breakpoint response_bp = 
iv->getSecond().ToProtocolBreakpoint();
-      response_bp.source = source;
-      if (!response_bp.line)
-        response_bp.line = src_bp.GetLine();
-      if (bp.column)
-        response_bp.column = *bp.column;
-      response_breakpoints.push_back(response_bp);
-    }
-  }
-
-  // Delete existing breakpoints for this sourceReference that are not in the
-  // request_bps set.
-  auto old_src_bp_pos = dap.assembly_breakpoints.find(sourceReference);
-  if (old_src_bp_pos != dap.assembly_breakpoints.end()) {
-    for (auto &old_bp : old_src_bp_pos->second) {
-      auto request_pos = request_bps.find(old_bp.first);
-      if (request_pos == request_bps.end()) {
-        dap.target.BreakpointDelete(old_bp.second.GetID());
-        old_src_bp_pos->second.erase(old_bp.first);
-      }
-    }
-  }
-
-  return response_breakpoints;
-}
-
 } // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp 
b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index 938b8fb8bcdda..50ebfbe8aef20 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -29,39 +29,49 @@
 namespace lldb_dap {
 
 SourceBreakpoint::SourceBreakpoint(DAP &dap,
-                                   const protocol::SourceBreakpoint 
&breakpoint)
+                                   const protocol::SourceBreakpoint 
&breakpoint,
+                                   const protocol::Source &source)
     : Breakpoint(dap, breakpoint.condition, breakpoint.hitCondition),
-      m_log_message(breakpoint.logMessage.value_or("")),
+      m_log_message(breakpoint.logMessage.value_or("")), m_source(source),
       m_line(breakpoint.line),
       m_column(breakpoint.column.value_or(LLDB_INVALID_COLUMN_NUMBER)) {}
 
-void SourceBreakpoint::SetBreakpoint(const llvm::StringRef source_path) {
-  lldb::SBMutex lock = m_dap.GetAPIMutex();
-  std::lock_guard<lldb::SBMutex> guard(lock);
-
-  lldb::SBFileSpecList module_list;
-  m_bp = m_dap.target.BreakpointCreateByLocation(
-      source_path.str().c_str(), m_line, m_column, 0, module_list);
-  if (!m_log_message.empty())
-    SetLogMessage();
-  Breakpoint::SetBreakpoint();
-}
-
-void SourceBreakpoint::SetBreakpoint(lldb::SBSymbol &symbol) {
+void SourceBreakpoint::SetBreakpoint() {
   lldb::SBMutex lock = m_dap.GetAPIMutex();
   std::lock_guard<lldb::SBMutex> guard(lock);
 
   if (m_line == 0)
     return;
 
-  lldb::SBInstructionList inst_list =
-      m_dap.target.ReadInstructions(symbol.GetStartAddress(), m_line);
-  if (inst_list.GetSize() < m_line)
-    return;
-  lldb::SBAddress address =
-      inst_list.GetInstructionAtIndex(m_line - 1).GetAddress();
+  if (m_source.sourceReference) {
+    // breakpoint set by assembly source.
+    lldb::SBAddress source_address(*m_source.sourceReference, m_dap.target);
+    if (!source_address.IsValid())
+      return;
+
+    lldb::SBSymbol symbol = source_address.GetSymbol();
+    if (!symbol.IsValid()) {
+      // Not yet supporting breakpoints in assembly without a valid symbol.
+      return;
+    }
+
+    lldb::SBInstructionList inst_list =
+        m_dap.target.ReadInstructions(symbol.GetStartAddress(), m_line);
+    if (inst_list.GetSize() < m_line)
+      return;
+
+    lldb::SBAddress address =
+        inst_list.GetInstructionAtIndex(m_line - 1).GetAddress();
+
+    m_bp = m_dap.target.BreakpointCreateBySBAddress(address);
+  } else {
+    // breakpoint set by a regular source file.
+    const auto source_path = m_source.path.value_or("");
+    lldb::SBFileSpecList module_list;
+    m_bp = m_dap.target.BreakpointCreateByLocation(source_path.c_str(), m_line,
+                                                   m_column, 0, module_list);
+  }
 
-  m_bp = m_dap.target.BreakpointCreateBySBAddress(address);
   if (!m_log_message.empty())
     SetLogMessage();
   Breakpoint::SetBreakpoint();
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.h 
b/lldb/tools/lldb-dap/SourceBreakpoint.h
index 8589800e50983..3221ecbf28ece 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.h
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.h
@@ -22,11 +22,11 @@ namespace lldb_dap {
 
 class SourceBreakpoint : public Breakpoint {
 public:
-  SourceBreakpoint(DAP &d, const protocol::SourceBreakpoint &breakpoint);
+  SourceBreakpoint(DAP &d, const protocol::SourceBreakpoint &breakpoint,
+                   const protocol::Source &source);
 
   // Set this breakpoint in LLDB as a new breakpoint
-  void SetBreakpoint(const llvm::StringRef source_path);
-  void SetBreakpoint(lldb::SBSymbol &symbol);
+  void SetBreakpoint();
   void UpdateBreakpoint(const SourceBreakpoint &request_bp);
 
   void SetLogMessage();
@@ -63,6 +63,7 @@ class SourceBreakpoint : public Breakpoint {
   std::string m_log_message;
   std::vector<LogMessagePart> m_log_message_parts;
 
+  protocol::Source m_source; /// The original breakpoint source.
   uint32_t m_line;   ///< The source line of the breakpoint or logpoint
   uint32_t m_column; ///< An optional source column of the breakpoint
 };

>From 2e9edca37c0953e2d2a6cf2d278bb353f1e0960b Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 18 May 2025 13:39:05 +0200
Subject: [PATCH 10/14] improve assembvly breakpoint test to check clear

---
 .../TestDAP_breakpointAssembly.py               | 17 +++++++++++++++--
 .../tools/lldb-dap/breakpoint-assembly/main.c   |  4 +++-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git 
a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
 
b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
index ba9df3a18590b..dacc1cd8349f1 100644
--- 
a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
+++ 
b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
@@ -6,7 +6,7 @@
 import dap_server
 import shutil
 from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
+from lldbsuite.test.lldbtest import line_number
 from lldbsuite.test import lldbutil
 import lldbdap_testcase
 import os
@@ -23,6 +23,9 @@ def test_functionality(self):
             "`settings set stop-disassembly-display no-debuginfo", 
context="repl"
         )
 
+        finish_line = line_number("main.c", "// Break here")
+        finish_breakpoints = self.set_source_breakpoints("main.c", 
[finish_line])
+
         assmebly_func_breakpoints = 
self.set_function_breakpoints(["assembly_func"])
         self.continue_to_breakpoints(assmebly_func_breakpoints)
 
@@ -36,7 +39,17 @@ def test_functionality(self):
         line = assembly_func_frame["line"]
 
         # Set an assembly breakpoint in the next line and check that it's hit
+        source_reference = assembly_func_frame["source"]["sourceReference"]
         assembly_breakpoint_ids = self.set_source_breakpoints_assembly(
-            assembly_func_frame["source"]["sourceReference"], [line + 1]
+            source_reference, [line + 1]
         )
         self.continue_to_breakpoints(assembly_breakpoint_ids)
+
+        # Continue again and verify it hits in the next function call
+        self.continue_to_breakpoints(assmebly_func_breakpoints)
+        self.continue_to_breakpoints(assembly_breakpoint_ids)
+
+        # Clear the breakpoint and then check that the assembly breakpoint 
does not hit next time
+        self.set_source_breakpoints_assembly(source_reference, [])
+        self.continue_to_breakpoints(assmebly_func_breakpoints)
+        self.continue_to_breakpoints(finish_breakpoints)
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/main.c 
b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/main.c
index 350739006f903..e3a21df11958f 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/main.c
+++ b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/main.c
@@ -10,5 +10,7 @@ __attribute__((nodebug)) int assembly_func(int n) {
 
 int main(int argc, char const *argv[]) {
   assembly_func(10);
-  return 0;
+  assembly_func(20);
+  assembly_func(30);
+  return 0; // Break here
 }

>From 0515c6dc6e46b6296621e871b43286ae88ea9b6b Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 18 May 2025 13:52:40 +0200
Subject: [PATCH 11/14] fix GetSBFileSpecPath extra char

---
 lldb/tools/lldb-dap/LLDBUtils.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/tools/lldb-dap/LLDBUtils.cpp 
b/lldb/tools/lldb-dap/LLDBUtils.cpp
index 3c7623ec1215d..fe0bcda19b4cd 100644
--- a/lldb/tools/lldb-dap/LLDBUtils.cpp
+++ b/lldb/tools/lldb-dap/LLDBUtils.cpp
@@ -247,8 +247,8 @@ std::string GetSBFileSpecPath(const lldb::SBFileSpec 
&file_spec) {
   const auto directory_length = ::strlen(file_spec.GetDirectory());
   const auto file_name_length = ::strlen(file_spec.GetFilename());
 
-  std::string path(directory_length + file_name_length + 2, '\0');
-  file_spec.GetPath(path.data(), path.length());
+  std::string path(directory_length + file_name_length + 1, '\0');
+  file_spec.GetPath(path.data(), path.length() + 1);
   return path;
 }
 

>From 9dbca55d01c7faddc9df4586ba25c6fac421d909 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 18 May 2025 13:59:53 +0200
Subject: [PATCH 12/14] restore SBFileSpec changes

---
 lldb/include/lldb/API/SBFileSpec.h | 1 -
 lldb/source/API/SBFileSpec.cpp     | 1 -
 lldb/tools/lldb-dap/DAP.cpp        | 8 ++++----
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/lldb/include/lldb/API/SBFileSpec.h 
b/lldb/include/lldb/API/SBFileSpec.h
index 1bb28b2ddab01..36641843aabeb 100644
--- a/lldb/include/lldb/API/SBFileSpec.h
+++ b/lldb/include/lldb/API/SBFileSpec.h
@@ -10,7 +10,6 @@
 #define LLDB_API_SBFILESPEC_H
 
 #include "lldb/API/SBDefines.h"
-#include "lldb/API/SBStream.h"
 
 namespace lldb {
 
diff --git a/lldb/source/API/SBFileSpec.cpp b/lldb/source/API/SBFileSpec.cpp
index f18857f59171a..a7df9afc4b8eb 100644
--- a/lldb/source/API/SBFileSpec.cpp
+++ b/lldb/source/API/SBFileSpec.cpp
@@ -19,7 +19,6 @@
 
 #include <cinttypes>
 #include <climits>
-#include <string>
 
 using namespace lldb;
 using namespace lldb_private;
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 1fe46fc619d73..d7ef886dd2419 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -1626,16 +1626,16 @@ std::vector<protocol::Breakpoint> 
DAP::SetSourceBreakpoints(
   std::vector<protocol::Breakpoint> response_breakpoints;
   if (source.sourceReference) {
     // breakpoint set by assembly source.
-    auto &existing_breakpoints_pos =
+    auto &existing_breakpoints =
         m_source_assembly_breakpoints[*source.sourceReference];
     response_breakpoints =
-        SetSourceBreakpoints(source, breakpoints, existing_breakpoints_pos);
+        SetSourceBreakpoints(source, breakpoints, existing_breakpoints);
   } else {
     // breakpoint set by a regular source file.
     const auto path = source.path.value_or("");
-    auto &existing_breakpoints_pos = m_source_breakpoints[path];
+    auto &existing_breakpoints = m_source_breakpoints[path];
     response_breakpoints =
-        SetSourceBreakpoints(source, breakpoints, existing_breakpoints_pos);
+        SetSourceBreakpoints(source, breakpoints, existing_breakpoints);
   }
 
   return response_breakpoints;

>From 396970d6a46063450741b6b0c9c528078e433e24 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 18 May 2025 14:01:28 +0200
Subject: [PATCH 13/14] single line if with comments curly braces

---
 lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 1d2a6ff60e502..dcc25c9212432 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -661,10 +661,11 @@ CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat 
&format,
     frame_name = name;
   }
 
-  if (frame_name.empty())
+  if (frame_name.empty()) {
     // If the function name is unavailable, display the pc address as a 
16-digit
     // hex string, e.g. "0x0000000000012345"
     frame_name = GetLoadAddressString(frame.GetPC());
+  }
 
   // We only include `[opt]` if a custom frame format is not specified.
   if (!format && frame.GetFunction().GetIsOptimized())

>From 7a0e0eeb1232028e535d2057198c8e8a7f0487d6 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 18 May 2025 14:06:40 +0200
Subject: [PATCH 14/14] unecessary include

---
 lldb/tools/lldb-dap/Handler/RequestHandler.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h 
b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index 54f728414021e..4670e23ca33d4 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -16,7 +16,6 @@
 #include "Protocol/ProtocolRequests.h"
 #include "Protocol/ProtocolTypes.h"
 #include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/JSON.h"

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to