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

>From c9fc191e93381b90b67d72799bab1b9ea19b8c42 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sat, 17 May 2025 23:49:10 +0200
Subject: [PATCH 01/19] [lldb-dap] Support persistent assembly breakpoints

---
 lldb/tools/lldb-dap/CMakeLists.txt            |  3 +-
 .../Handler/SetBreakpointsRequestHandler.cpp  |  1 -
 lldb/tools/lldb-dap/Protocol/DAPTypes.cpp     | 39 ++++++++++++++
 lldb/tools/lldb-dap/Protocol/DAPTypes.h       | 54 +++++++++++++++++++
 .../tools/lldb-dap/Protocol/ProtocolTypes.cpp |  5 +-
 lldb/tools/lldb-dap/Protocol/ProtocolTypes.h  |  8 ++-
 6 files changed, 106 insertions(+), 4 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
 create mode 100644 lldb/tools/lldb-dap/Protocol/DAPTypes.h

diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 4cddfb1bea1c2..5e0ad53b82f89 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -66,7 +66,8 @@ add_lldb_library(lldbDAP
   Handler/ThreadsRequestHandler.cpp
   Handler/VariablesRequestHandler.cpp
   Handler/WriteMemoryRequestHandler.cpp
-  
+
+  Protocol/DAPTypes.cpp
   Protocol/ProtocolBase.cpp
   Protocol/ProtocolEvents.cpp
   Protocol/ProtocolTypes.cpp
diff --git a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
index 5d336af740c99..142351fd62179 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 "Protocol/ProtocolRequests.h"
 #include "RequestHandler.h"
-#include <vector>
 
 namespace lldb_dap {
 
diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
new file mode 100644
index 0000000000000..7fc77a5de2202
--- /dev/null
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
@@ -0,0 +1,39 @@
+#include "Protocol/DAPTypes.h"
+// #include "llvm/Support/JSON.h"
+
+using namespace llvm;
+
+namespace lldb_dap::protocol {
+
+bool fromJSON(const llvm::json::Value &Params, AssemblyBreakpointData &ABD,
+              llvm::json::Path P) {
+  json::ObjectMapper O(Params, P);
+  return O && O.mapOptional("module", ABD.module) &&
+         O.mapOptional("symbol_mangled_name", ABD.symbol_mangled_name) &&
+         O.mapOptional("offset", ABD.offset);
+}
+
+llvm::json::Value toJSON(const AssemblyBreakpointData &ABD) {
+  json::Object result{
+      {"module", ABD.module},
+      {"symbol_mangled_name", ABD.symbol_mangled_name},
+      {"offset", ABD.offset},
+  };
+
+  return result;
+}
+
+bool fromJSON(const llvm::json::Value &Params, SourceLLDBData &SLD,
+              llvm::json::Path P) {
+  json::ObjectMapper O(Params, P);
+  return O && O.mapOptional("assembly_breakpoint", SLD.assembly_breakpoint);
+}
+
+llvm::json::Value toJSON(const SourceLLDBData &SLD) {
+  json::Object result;
+  if (SLD.assembly_breakpoint)
+    result.insert({"assembly_breakpoint", SLD.assembly_breakpoint});
+  return result;
+}
+
+} // namespace lldb_dap::protocol
\ No newline at end of file
diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.h 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
new file mode 100644
index 0000000000000..ff88deebc84bf
--- /dev/null
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
@@ -0,0 +1,54 @@
+//===-- ProtocolTypes.h 
---------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains private DAP types used in the protocol.
+//
+// Each struct has a toJSON and fromJSON function, that converts between
+// the struct and a JSON representation. (See JSON.h)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TOOLS_LLDB_DAP_PROTOCOL_DAP_TYPES_H
+#define LLDB_TOOLS_LLDB_DAP_PROTOCOL_DAP_TYPES_H
+
+#include "lldb/lldb-types.h"
+#include "llvm/Support/JSON.h"
+#include <optional>
+#include <string>
+
+namespace lldb_dap::protocol {
+
+/// Data used to help lldb-dap resolve assembly breakpoints across different
+/// sessions.
+struct AssemblyBreakpointData {
+  /// The source module path.
+  std::string module;
+
+  /// The symbol unique name.
+  std::string symbol_mangled_name;
+
+  /// The breakpoint offset from the symbol resolved address.
+  lldb::addr_t offset;
+};
+bool fromJSON(const llvm::json::Value &, AssemblyBreakpointData &,
+              llvm::json::Path);
+llvm::json::Value toJSON(const AssemblyBreakpointData &);
+
+/// Custom source data used by lldb-dap.
+/// This data should help lldb-dap identify sources correctly across different
+/// sessions.
+struct SourceLLDBData {
+  /// Assembly breakpoint data.
+  std::optional<AssemblyBreakpointData> assembly_breakpoint;
+};
+bool fromJSON(const llvm::json::Value &, SourceLLDBData &, llvm::json::Path);
+llvm::json::Value toJSON(const SourceLLDBData &);
+
+} // namespace lldb_dap::protocol
+
+#endif
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp 
b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
index 785830c693104..78b3d407c82b1 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
@@ -46,7 +46,8 @@ bool fromJSON(const json::Value &Params, Source &S, 
json::Path P) {
   json::ObjectMapper O(Params, P);
   return O && O.map("name", S.name) && O.map("path", S.path) &&
          O.map("presentationHint", S.presentationHint) &&
-         O.map("sourceReference", S.sourceReference);
+         O.map("sourceReference", S.sourceReference) &&
+         O.map("adapterData", S.adapterData);
 }
 
 llvm::json::Value toJSON(Source::PresentationHint hint) {
@@ -71,6 +72,8 @@ llvm::json::Value toJSON(const Source &S) {
     result.insert({"sourceReference", *S.sourceReference});
   if (S.presentationHint)
     result.insert({"presentationHint", *S.presentationHint});
+  if (S.adapterData)
+    result.insert({"adapterData", *S.adapterData});
 
   return result;
 }
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h 
b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
index 89122c8f66307..c4be7911a662b 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
@@ -20,6 +20,7 @@
 #ifndef LLDB_TOOLS_LLDB_DAP_PROTOCOL_PROTOCOL_TYPES_H
 #define LLDB_TOOLS_LLDB_DAP_PROTOCOL_PROTOCOL_TYPES_H
 
+#include "Protocol/DAPTypes.h"
 #include "lldb/lldb-defines.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/Support/JSON.h"
@@ -336,7 +337,12 @@ struct Source {
   /// skipped on stepping.
   std::optional<PresentationHint> presentationHint;
 
-  // unsupported keys: origin, sources, adapterData, checksums
+  /// Additional data that a debug adapter might want to loop through the
+  /// client. The client should leave the data intact and persist it across
+  /// sessions. The client should not interpret the data.
+  std::optional<SourceLLDBData> adapterData;
+
+  // unsupported keys: origin, sources, checksums
 };
 bool fromJSON(const llvm::json::Value &, Source::PresentationHint &,
               llvm::json::Path);

>From f48f313f04ee0877be91cce84a5135caac259fc3 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sat, 31 May 2025 16:51:10 +0200
Subject: [PATCH 02/19] save adapterData for assembly breakpoints

---
 lldb/tools/lldb-dap/SourceBreakpoint.cpp | 3 ++-
 lldb/tools/lldb-dap/SourceBreakpoint.h   | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp 
b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index 5fce9fe0ddbb3..580d126fd791a 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -10,6 +10,7 @@
 #include "BreakpointBase.h"
 #include "DAP.h"
 #include "JSONUtils.h"
+#include "ProtocolUtils.h"
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBFileSpecList.h"
 #include "lldb/API/SBFrame.h"
@@ -44,7 +45,7 @@ llvm::Error SourceBreakpoint::SetBreakpoint(const 
protocol::Source &source) {
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "Invalid line number.");
 
-  if (source.sourceReference) {
+  if (IsAssemblySource(source)) {
     // Breakpoint set by assembly source.
     std::optional<lldb::addr_t> raw_addr =
         m_dap.GetSourceReferenceAddress(*source.sourceReference);
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.h 
b/lldb/tools/lldb-dap/SourceBreakpoint.h
index 857ac4286d59d..0a053b5e4d6a6 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.h
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.h
@@ -50,6 +50,9 @@ class SourceBreakpoint : public Breakpoint {
   uint32_t GetColumn() const { return m_column; }
 
 protected:
+  llvm::Error SetAssemblyBreakpoint(const protocol::Source &source);
+  llvm::Error SetPathBreakpoint(const protocol::Source &source);
+
   // logMessage part can be either a raw text or an expression.
   struct LogMessagePart {
     LogMessagePart(llvm::StringRef text, bool is_expr)

>From 06170ea6ee33f786b11388c44c3986fd130937b0 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Mon, 2 Jun 2025 23:17:14 +0200
Subject: [PATCH 03/19] remove offset

---
 lldb/tools/lldb-dap/Protocol/DAPTypes.cpp | 20 +++---
 lldb/tools/lldb-dap/Protocol/DAPTypes.h   | 19 +++--
 lldb/tools/lldb-dap/SourceBreakpoint.cpp  | 86 ++++++++++++++---------
 lldb/tools/lldb-dap/SourceBreakpoint.h    |  6 +-
 4 files changed, 75 insertions(+), 56 deletions(-)

diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
index 7fc77a5de2202..994cef02cb63f 100644
--- a/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
@@ -5,19 +5,17 @@ using namespace llvm;
 
 namespace lldb_dap::protocol {
 
-bool fromJSON(const llvm::json::Value &Params, AssemblyBreakpointData &ABD,
+bool fromJSON(const llvm::json::Value &Params, PersistenceData &PD,
               llvm::json::Path P) {
   json::ObjectMapper O(Params, P);
-  return O && O.mapOptional("module", ABD.module) &&
-         O.mapOptional("symbol_mangled_name", ABD.symbol_mangled_name) &&
-         O.mapOptional("offset", ABD.offset);
+  return O && O.mapOptional("module", PD.module) &&
+         O.mapOptional("symbol_mangled_name", PD.symbol_mangled_name);
 }
 
-llvm::json::Value toJSON(const AssemblyBreakpointData &ABD) {
+llvm::json::Value toJSON(const PersistenceData &PD) {
   json::Object result{
-      {"module", ABD.module},
-      {"symbol_mangled_name", ABD.symbol_mangled_name},
-      {"offset", ABD.offset},
+      {"module", PD.module},
+      {"symbol_mangled_name", PD.symbol_mangled_name},
   };
 
   return result;
@@ -26,13 +24,13 @@ llvm::json::Value toJSON(const AssemblyBreakpointData &ABD) 
{
 bool fromJSON(const llvm::json::Value &Params, SourceLLDBData &SLD,
               llvm::json::Path P) {
   json::ObjectMapper O(Params, P);
-  return O && O.mapOptional("assembly_breakpoint", SLD.assembly_breakpoint);
+  return O && O.mapOptional("persistence_data", SLD.persistence_data);
 }
 
 llvm::json::Value toJSON(const SourceLLDBData &SLD) {
   json::Object result;
-  if (SLD.assembly_breakpoint)
-    result.insert({"assembly_breakpoint", SLD.assembly_breakpoint});
+  if (SLD.persistence_data)
+    result.insert({"persistence_data", SLD.persistence_data});
   return result;
 }
 
diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.h 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
index ff88deebc84bf..d853bd06e48ad 100644
--- a/lldb/tools/lldb-dap/Protocol/DAPTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
@@ -23,28 +23,27 @@
 
 namespace lldb_dap::protocol {
 
-/// Data used to help lldb-dap resolve assembly breakpoints across different
-/// sessions.
-struct AssemblyBreakpointData {
+/// Data used to help lldb-dap resolve breakpoints persistently across 
different sessions.
+/// This information is especially useful for assembly breakpoints, because 
`sourceReference`
+/// can change across sessions. For regular source breakpoints the path and 
line are the same
+/// For each session.
+struct PersistenceData {
   /// The source module path.
   std::string module;
 
   /// The symbol unique name.
   std::string symbol_mangled_name;
-
-  /// The breakpoint offset from the symbol resolved address.
-  lldb::addr_t offset;
 };
-bool fromJSON(const llvm::json::Value &, AssemblyBreakpointData &,
+bool fromJSON(const llvm::json::Value &, PersistenceData &,
               llvm::json::Path);
-llvm::json::Value toJSON(const AssemblyBreakpointData &);
+llvm::json::Value toJSON(const PersistenceData &);
 
 /// Custom source data used by lldb-dap.
 /// This data should help lldb-dap identify sources correctly across different
 /// sessions.
 struct SourceLLDBData {
-  /// Assembly breakpoint data.
-  std::optional<AssemblyBreakpointData> assembly_breakpoint;
+  /// Data that helps lldb resolve this source persistently across different 
sessions.
+  std::optional<PersistenceData> persistence_data;
 };
 bool fromJSON(const llvm::json::Value &, SourceLLDBData &, llvm::json::Path);
 llvm::json::Value toJSON(const SourceLLDBData &);
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp 
b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index 580d126fd791a..a9129cfe02f19 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -47,41 +47,17 @@ llvm::Error SourceBreakpoint::SetBreakpoint(const 
protocol::Source &source) {
 
   if (IsAssemblySource(source)) {
     // Breakpoint set by assembly source.
-    std::optional<lldb::addr_t> raw_addr =
-        m_dap.GetSourceReferenceAddress(*source.sourceReference);
-    if (!raw_addr)
-      return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                     "Invalid sourceReference.");
-
-    lldb::SBAddress source_address(*raw_addr, m_dap.target);
-    if (!source_address.IsValid())
-      return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                     "Invalid sourceReference.");
-
-    lldb::SBSymbol symbol = source_address.GetSymbol();
-    if (!symbol.IsValid()) {
-      // FIXME: Support assembly breakpoints without a valid symbol.
-      return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                     "Breakpoints in assembly without a valid "
-                                     "symbol are not supported yet.");
+    if (source.adapterData && source.adapterData->persistence_data) {
+      // Prefer use the adapter persitence data, because this could be a 
breakpoint 
+      // from a previous session where the `sourceReference` is not valid 
anymore.
+      if (llvm::Error error = 
CreateAssemblyBreakpointWithPersistenceData(*source.adapterData->persistence_data))
+        return error;
+    } else {
+      if (llvm::Error error = 
CreateAssemblyBreakpointWithSourceReference(*source.sourceReference))
+        return error;
     }
-
-    lldb::SBInstructionList inst_list =
-        m_dap.target.ReadInstructions(symbol.GetStartAddress(), m_line);
-    if (inst_list.GetSize() < m_line)
-      return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                     "Invalid instruction list size.");
-
-    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 = 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);
+    CreatePathBreakpoint(source);
   }
 
   if (!m_log_message.empty())
@@ -98,6 +74,50 @@ void SourceBreakpoint::UpdateBreakpoint(const 
SourceBreakpoint &request_bp) {
   BreakpointBase::UpdateBreakpoint(request_bp);
 }
 
+void SourceBreakpoint::CreatePathBreakpoint(const protocol::Source &source) {
+  const auto source_path = 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);
+}
+
+llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithSourceReference(int64_t 
source_reference) {
+  std::optional<lldb::addr_t> raw_addr =
+      m_dap.GetSourceReferenceAddress(source_reference);
+  if (!raw_addr)
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                    "Invalid sourceReference.");
+
+  lldb::SBAddress source_address(*raw_addr, m_dap.target);
+  if (!source_address.IsValid())
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                    "Invalid sourceReference.");
+
+  lldb::SBSymbol symbol = source_address.GetSymbol();
+  if (!symbol.IsValid()) {
+    // FIXME: Support assembly breakpoints without a valid symbol.
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                    "Breakpoints in assembly without a valid "
+                                    "symbol are not supported yet.");
+  }
+
+  lldb::SBInstructionList inst_list =
+      m_dap.target.ReadInstructions(symbol.GetStartAddress(), m_line);
+  if (inst_list.GetSize() < m_line)
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                    "Invalid instruction list size.");
+
+  lldb::SBAddress address =
+      inst_list.GetInstructionAtIndex(m_line - 1).GetAddress();
+
+  m_bp = m_dap.target.BreakpointCreateBySBAddress(address);
+  return llvm::Error::success();
+}
+
+llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithPersistenceData(const 
protocol::PersistenceData &persistence_data) {
+  return llvm::Error::success();
+}
+
 lldb::SBError SourceBreakpoint::AppendLogMessagePart(llvm::StringRef part,
                                                      bool is_expr) {
   if (is_expr) {
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.h 
b/lldb/tools/lldb-dap/SourceBreakpoint.h
index 0a053b5e4d6a6..b9086a0c8fbb7 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.h
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.h
@@ -11,6 +11,7 @@
 
 #include "Breakpoint.h"
 #include "DAPForward.h"
+#include "Protocol/DAPTypes.h"
 #include "Protocol/ProtocolTypes.h"
 #include "lldb/API/SBError.h"
 #include "llvm/ADT/StringRef.h"
@@ -50,8 +51,9 @@ class SourceBreakpoint : public Breakpoint {
   uint32_t GetColumn() const { return m_column; }
 
 protected:
-  llvm::Error SetAssemblyBreakpoint(const protocol::Source &source);
-  llvm::Error SetPathBreakpoint(const protocol::Source &source);
+  void CreatePathBreakpoint(const protocol::Source &source);
+  llvm::Error CreateAssemblyBreakpointWithSourceReference(int64_t 
source_reference);
+  llvm::Error CreateAssemblyBreakpointWithPersistenceData(const 
protocol::PersistenceData &persistence_data);
 
   // logMessage part can be either a raw text or an expression.
   struct LogMessagePart {

>From 26b7000e0ffe3ee82fab1a586dbe70e941947474 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 6 Jul 2025 00:36:22 +0200
Subject: [PATCH 04/19] create persistent breakpoints

---
 lldb/include/lldb/API/SBTarget.h          |  3 +++
 lldb/include/lldb/Target/Target.h         |  2 +-
 lldb/source/API/SBTarget.cpp              | 14 ++++++++++++++
 lldb/tools/lldb-dap/Protocol/DAPTypes.cpp |  4 ++--
 lldb/tools/lldb-dap/Protocol/DAPTypes.h   |  4 ++--
 lldb/tools/lldb-dap/SourceBreakpoint.cpp  |  3 +++
 6 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 2776a8f9010fe..af64fc06a3b4a 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -737,6 +737,9 @@ class LLDB_API SBTarget {
 
   lldb::SBBreakpoint BreakpointCreateBySBAddress(SBAddress &address);
 
+  lldb::SBBreakpoint BreakpointCreateByFileAddress(const SBFileSpec &file_spec,
+                                                   addr_t file_addr);
+
   /// Create a breakpoint using a scripted resolver.
   ///
   /// \param[in] class_name
diff --git a/lldb/include/lldb/Target/Target.h 
b/lldb/include/lldb/Target/Target.h
index 0d4e11b65339e..8716a9f81b734 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -723,7 +723,7 @@ class Target : public std::enable_shared_from_this<Target>,
   lldb::BreakpointSP CreateBreakpoint(lldb::addr_t load_addr, bool internal,
                                       bool request_hardware);
 
-  // Use this to create a breakpoint from a load address and a module file spec
+  // Use this to create a breakpoint from a file address and a module file spec
   lldb::BreakpointSP CreateAddressInModuleBreakpoint(lldb::addr_t file_addr,
                                                      bool internal,
                                                      const FileSpec &file_spec,
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index f26f7951edc6f..f21e0fb0f986e 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -66,6 +66,7 @@
 
 #include "Commands/CommandObjectBreakpoint.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/lldb-types.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Regex.h"
 
@@ -949,6 +950,19 @@ SBBreakpoint 
SBTarget::BreakpointCreateBySBAddress(SBAddress &sb_address) {
   return sb_bp;
 }
 
+SBBreakpoint SBTarget::BreakpointCreateByFileAddress(const SBFileSpec 
&file_spec, addr_t file_addr) {
+  LLDB_INSTRUMENT_VA(this, file_spec, file_addr);
+
+  SBBreakpoint sb_bp;
+  if (TargetSP target_sp = GetSP()) {
+    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+    const bool hardware = false;
+    sb_bp = target_sp->CreateAddressInModuleBreakpoint(file_addr, false, 
*file_spec.get(), hardware);
+  }
+
+  return sb_bp;
+}
+
 lldb::SBBreakpoint
 SBTarget::BreakpointCreateBySourceRegex(const char *source_regex,
                                         const lldb::SBFileSpec &source_file,
diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
index 994cef02cb63f..e45a4f30d9bcf 100644
--- a/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
@@ -9,13 +9,13 @@ bool fromJSON(const llvm::json::Value &Params, 
PersistenceData &PD,
               llvm::json::Path P) {
   json::ObjectMapper O(Params, P);
   return O && O.mapOptional("module", PD.module) &&
-         O.mapOptional("symbol_mangled_name", PD.symbol_mangled_name);
+         O.mapOptional("file_addr", PD.file_addr);
 }
 
 llvm::json::Value toJSON(const PersistenceData &PD) {
   json::Object result{
       {"module", PD.module},
-      {"symbol_mangled_name", PD.symbol_mangled_name},
+      {"file_addr", PD.file_addr},
   };
 
   return result;
diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.h 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
index d853bd06e48ad..f87a9f3984711 100644
--- a/lldb/tools/lldb-dap/Protocol/DAPTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
@@ -31,8 +31,8 @@ struct PersistenceData {
   /// The source module path.
   std::string module;
 
-  /// The symbol unique name.
-  std::string symbol_mangled_name;
+  /// The file address inside the module.
+  lldb::addr_t file_addr;
 };
 bool fromJSON(const llvm::json::Value &, PersistenceData &,
               llvm::json::Path);
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp 
b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index a9129cfe02f19..683e3c3eb1ff1 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -12,6 +12,7 @@
 #include "JSONUtils.h"
 #include "ProtocolUtils.h"
 #include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBFileSpec.h"
 #include "lldb/API/SBFileSpecList.h"
 #include "lldb/API/SBFrame.h"
 #include "lldb/API/SBInstruction.h"
@@ -115,6 +116,8 @@ llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithSourceReference(int64_
 }
 
 llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithPersistenceData(const 
protocol::PersistenceData &persistence_data) {
+  lldb::SBFileSpec file_spec(persistence_data.module.c_str());
+  m_bp = m_dap.target.BreakpointCreateByFileAddress(file_spec, 
persistence_data.file_addr);
   return llvm::Error::success();
 }
 

>From 5ea62b2c72fb4824be15efea7b4d9c2437913128 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 6 Jul 2025 16:34:53 +0200
Subject: [PATCH 05/19] add instructions_offset to breakppoint resolver

---
 lldb/include/lldb/API/SBTarget.h              |  3 +-
 .../lldb/Breakpoint/BreakpointResolver.h      |  6 +++-
 .../Breakpoint/BreakpointResolverAddress.h    |  6 ++++
 lldb/include/lldb/Core/Disassembler.h         |  2 ++
 lldb/include/lldb/Target/Target.h             |  9 ++++-
 lldb/source/API/SBTarget.cpp                  | 29 +++------------
 lldb/source/Breakpoint/BreakpointResolver.cpp | 14 ++++++--
 .../Breakpoint/BreakpointResolverAddress.cpp  |  6 ++++
 lldb/source/Core/Disassembler.cpp             | 10 ++++++
 lldb/source/Target/Target.cpp                 | 36 +++++++++++++++++--
 lldb/tools/lldb-dap/Protocol/DAPTypes.h       |  2 +-
 11 files changed, 89 insertions(+), 34 deletions(-)

diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index af64fc06a3b4a..06c1dc2ca08ca 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -23,6 +23,7 @@
 #include "lldb/API/SBValue.h"
 #include "lldb/API/SBWatchpoint.h"
 #include "lldb/API/SBWatchpointOptions.h"
+#include "lldb/lldb-types.h"
 
 namespace lldb_private {
 namespace python {
@@ -738,7 +739,7 @@ class LLDB_API SBTarget {
   lldb::SBBreakpoint BreakpointCreateBySBAddress(SBAddress &address);
 
   lldb::SBBreakpoint BreakpointCreateByFileAddress(const SBFileSpec &file_spec,
-                                                   addr_t file_addr);
+                                                   addr_t file_addr, addr_t 
offset = 0, addr_t instructions_offset = 0);
 
   /// Create a breakpoint using a scripted resolver.
   ///
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolver.h 
b/lldb/include/lldb/Breakpoint/BreakpointResolver.h
index 52cd70e934e6d..c83f4d249e6d1 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolver.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolver.h
@@ -16,6 +16,7 @@
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/lldb-private.h"
+#include "lldb/lldb-types.h"
 #include <optional>
 
 namespace lldb_private {
@@ -47,7 +48,8 @@ class BreakpointResolver : public Searcher {
   ///   The concrete breakpoint resolver type for this breakpoint.
   BreakpointResolver(const lldb::BreakpointSP &bkpt,
                      unsigned char resolverType,
-                     lldb::addr_t offset = 0);
+                     lldb::addr_t offset = 0,
+                     lldb::addr_t instructions_offset = 0);
 
   /// The Destructor is virtual, all significant breakpoint resolvers derive
   /// from this class.
@@ -182,6 +184,7 @@ class BreakpointResolver : public Searcher {
     SearchDepth,
     SkipPrologue,
     SymbolNameArray,
+    InstructionsOffset,
     LastOptionName
   };
   static const char
@@ -220,6 +223,7 @@ class BreakpointResolver : public Searcher {
   lldb::BreakpointWP m_breakpoint; // This is the breakpoint we add locations 
to.
   lldb::addr_t m_offset;    // A random offset the user asked us to add to any
                             // breakpoints we set.
+  lldb::addr_t m_instructions_offset; // Number of instructions to add to the 
resolved breakpoint address.
 
   // Subclass identifier (for llvm isa/dyn_cast)
   const unsigned char SubclassID;
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h 
b/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h
index 3a09892f3f194..bc6f057e366cb 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h
@@ -28,6 +28,12 @@ class BreakpointResolverAddress : public BreakpointResolver {
                             const Address &addr,
                             const FileSpec &module_spec);
 
+  BreakpointResolverAddress(const lldb::BreakpointSP &bkpt,
+                            const Address &addr,
+                            const FileSpec &module_spec,
+                            lldb::addr_t offset,
+                            lldb::addr_t instructions_offset);
+
   ~BreakpointResolverAddress() override = default;
 
   static lldb::BreakpointResolverSP
diff --git a/lldb/include/lldb/Core/Disassembler.h 
b/lldb/include/lldb/Core/Disassembler.h
index 21bacb14f9b25..50a5d87835844 100644
--- a/lldb/include/lldb/Core/Disassembler.h
+++ b/lldb/include/lldb/Core/Disassembler.h
@@ -291,6 +291,8 @@ class InstructionList {
 
   size_t GetSize() const;
 
+  size_t GetTotalByteSize() const;
+
   uint32_t GetMaxOpcocdeByteSize() const;
 
   lldb::InstructionSP GetInstructionAtIndex(size_t idx) const;
diff --git a/lldb/include/lldb/Target/Target.h 
b/lldb/include/lldb/Target/Target.h
index 8716a9f81b734..80c4898e957cf 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -18,6 +18,7 @@
 #include "lldb/Breakpoint/BreakpointList.h"
 #include "lldb/Breakpoint/BreakpointName.h"
 #include "lldb/Breakpoint/WatchpointList.h"
+#include "lldb/Core/Address.h"
 #include "lldb/Core/Architecture.h"
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Core/ModuleList.h"
@@ -727,7 +728,9 @@ class Target : public std::enable_shared_from_this<Target>,
   lldb::BreakpointSP CreateAddressInModuleBreakpoint(lldb::addr_t file_addr,
                                                      bool internal,
                                                      const FileSpec &file_spec,
-                                                     bool request_hardware);
+                                                     bool request_hardware,
+                                                     lldb::addr_t offset = 0,
+                                                     lldb::addr_t 
instructions_offset = 0);
 
   // Use this to create Address breakpoints:
   lldb::BreakpointSP CreateBreakpoint(const Address &addr, bool internal,
@@ -1328,6 +1331,10 @@ class Target : public 
std::enable_shared_from_this<Target>,
                                const lldb_private::RegisterFlags &flags,
                                uint32_t byte_size);
 
+  lldb::DisassemblerSP ReadInstructions(const Address &start_addr,
+                                        uint32_t count,
+                                        const char *flavor_string = nullptr);
+
   // Target Stop Hooks
   class StopHook : public UserID {
   public:
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index f21e0fb0f986e..116f527d9068c 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -950,14 +950,14 @@ SBBreakpoint 
SBTarget::BreakpointCreateBySBAddress(SBAddress &sb_address) {
   return sb_bp;
 }
 
-SBBreakpoint SBTarget::BreakpointCreateByFileAddress(const SBFileSpec 
&file_spec, addr_t file_addr) {
+SBBreakpoint SBTarget::BreakpointCreateByFileAddress(const SBFileSpec 
&file_spec, addr_t file_addr, addr_t offset, addr_t instructions_offset) {
   LLDB_INSTRUMENT_VA(this, file_spec, file_addr);
 
   SBBreakpoint sb_bp;
   if (TargetSP target_sp = GetSP()) {
     std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
     const bool hardware = false;
-    sb_bp = target_sp->CreateAddressInModuleBreakpoint(file_addr, false, 
*file_spec.get(), hardware);
+    sb_bp = target_sp->CreateAddressInModuleBreakpoint(file_addr, false, 
*file_spec.get(), hardware, offset, instructions_offset);
   }
 
   return sb_bp;
@@ -1969,29 +1969,8 @@ lldb::SBInstructionList 
SBTarget::ReadInstructions(lldb::SBAddress base_addr,
 
   if (TargetSP target_sp = GetSP()) {
     if (Address *addr_ptr = base_addr.get()) {
-      DataBufferHeap data(
-          target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);
-      bool force_live_memory = true;
-      lldb_private::Status error;
-      lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
-      const size_t bytes_read =
-          target_sp->ReadMemory(*addr_ptr, data.GetBytes(), data.GetByteSize(),
-                                error, force_live_memory, &load_addr);
-
-      const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
-      if (!flavor_string || flavor_string[0] == '\0') {
-        // FIXME - we don't have the mechanism in place to do per-architecture
-        // settings.  But since we know that for now we only support flavors on
-        // x86 & x86_64,
-        const llvm::Triple::ArchType arch =
-            target_sp->GetArchitecture().GetTriple().getArch();
-        if (arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64)
-          flavor_string = target_sp->GetDisassemblyFlavor();
-      }
-      sb_instructions.SetDisassembler(Disassembler::DisassembleBytes(
-          target_sp->GetArchitecture(), nullptr, flavor_string,
-          target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(),
-          *addr_ptr, data.GetBytes(), bytes_read, count, data_from_file));
+      sb_instructions.SetDisassembler(target_sp->ReadInstructions(
+          *addr_ptr, count, flavor_string));
     }
   }
 
diff --git a/lldb/source/Breakpoint/BreakpointResolver.cpp 
b/lldb/source/Breakpoint/BreakpointResolver.cpp
index 91fdff4a455da..a5cd9372527ac 100644
--- a/lldb/source/Breakpoint/BreakpointResolver.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolver.cpp
@@ -29,6 +29,7 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Stream.h"
 #include "lldb/Utility/StreamString.h"
+#include "lldb/lldb-forward.h"
 #include <optional>
 
 using namespace lldb_private;
@@ -45,7 +46,7 @@ const char 
*BreakpointResolver::g_option_names[static_cast<uint32_t>(
     "AddressOffset", "Exact",     "FileName",     "Inlines",     "Language",
     "LineNumber",    "Column",    "ModuleName",   "NameMask",    "Offset",
     "PythonClass",   "Regex",     "ScriptArgs",   "SectionName", "SearchDepth",
-    "SkipPrologue",  "SymbolNames"};
+    "SkipPrologue",  "SymbolNames", "InstructionsOffset"};
 
 const char *BreakpointResolver::ResolverTyToName(enum ResolverTy type) {
   if (type > LastKnownResolverType)
@@ -65,8 +66,9 @@ BreakpointResolver::NameToResolverTy(llvm::StringRef name) {
 
 BreakpointResolver::BreakpointResolver(const BreakpointSP &bkpt,
                                        const unsigned char resolverTy,
-                                       lldb::addr_t offset)
-    : m_breakpoint(bkpt), m_offset(offset), SubclassID(resolverTy) {}
+                                       lldb::addr_t offset,
+                                       lldb::addr_t instructions_offset)
+    : m_breakpoint(bkpt), m_offset(offset), 
m_instructions_offset(instructions_offset), SubclassID(resolverTy) {}
 
 BreakpointResolver::~BreakpointResolver() = default;
 
@@ -364,6 +366,12 @@ void BreakpointResolver::AddLocation(SearchFilter &filter,
 
 BreakpointLocationSP BreakpointResolver::AddLocation(Address loc_addr,
                                                      bool *new_location) {
+  if (m_instructions_offset != 0) {
+    Target &target = GetBreakpoint()->GetTarget();
+    const DisassemblerSP instructions = target.ReadInstructions(loc_addr, 
m_instructions_offset);
+    loc_addr.Slide(instructions->GetInstructionList().GetTotalByteSize());
+  }
+
   loc_addr.Slide(m_offset);
   return GetBreakpoint()->AddLocation(loc_addr, new_location);
 }
diff --git a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp 
b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
index 828647ceef637..5298cbc76dc1f 100644
--- a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
@@ -30,6 +30,12 @@ BreakpointResolverAddress::BreakpointResolverAddress(const 
BreakpointSP &bkpt,
     : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver),
       m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS) {}
 
+BreakpointResolverAddress::BreakpointResolverAddress(
+    const BreakpointSP &bkpt, const Address &addr, const FileSpec 
&module_spec, lldb::addr_t offset, lldb::addr_t instructions_offset)
+    : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver, offset, 
instructions_offset),
+      m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS),
+      m_module_filespec(module_spec) {}
+
 BreakpointResolverSP BreakpointResolverAddress::CreateFromStructuredData(
     const StructuredData::Dictionary &options_dict, Status &error) {
   llvm::StringRef module_name;
diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index 833e327579a29..90394cc9a5569 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -1014,6 +1014,16 @@ uint32_t InstructionList::GetMaxOpcocdeByteSize() const {
   return max_inst_size;
 }
 
+size_t InstructionList::GetTotalByteSize() const {
+  size_t total_byte_size = 0;
+  collection::const_iterator pos, end;
+  for (pos = m_instructions.begin(), end = m_instructions.end(); pos != end;
+       ++pos) {
+    total_byte_size += (*pos)->GetOpcode().GetByteSize();
+  }
+  return total_byte_size;
+}
+
 InstructionSP InstructionList::GetInstructionAtIndex(size_t idx) const {
   InstructionSP inst_sp;
   if (idx < m_instructions.size())
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 7f569173eba20..82f07829b05b3 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -65,6 +65,7 @@
 #include "lldb/Utility/State.h"
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/Timer.h"
+#include "lldb/lldb-forward.h"
 
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SetVector.h"
@@ -567,11 +568,13 @@ BreakpointSP Target::CreateBreakpoint(const Address 
&addr, bool internal,
 lldb::BreakpointSP
 Target::CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal,
                                         const FileSpec &file_spec,
-                                        bool request_hardware) {
+                                        bool request_hardware,
+                                        lldb::addr_t offset,
+                                        lldb::addr_t instructions_offset) {
   SearchFilterSP filter_sp(
       new SearchFilterForUnconstrainedSearches(shared_from_this()));
   BreakpointResolverSP resolver_sp(new BreakpointResolverAddress(
-      nullptr, file_addr, file_spec));
+      nullptr, file_addr, file_spec, offset, instructions_offset));
   return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware,
                           false);
 }
@@ -2990,6 +2993,35 @@ lldb::addr_t 
Target::GetBreakableLoadAddress(lldb::addr_t addr) {
   return arch_plugin ? arch_plugin->GetBreakableLoadAddress(addr, *this) : 
addr;
 }
 
+lldb::DisassemblerSP Target::ReadInstructions(const Address &start_addr, 
uint32_t count,
+                                             const char *flavor_string) {
+  if (!m_process_sp)
+    return lldb::DisassemblerSP();
+
+  DataBufferHeap data(GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);
+  bool force_live_memory = true;
+  lldb_private::Status error;
+  lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+  const size_t bytes_read = ReadMemory(start_addr, data.GetBytes(), 
data.GetByteSize(),
+                            error, force_live_memory, &load_addr);
+
+  const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
+  if (!flavor_string || flavor_string[0] == '\0') {
+    // FIXME - we don't have the mechanism in place to do per-architecture
+    // settings.  But since we know that for now we only support flavors on
+    // x86 & x86_64,
+    const llvm::Triple::ArchType arch =
+      GetArchitecture().GetTriple().getArch();
+    if (arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64)
+      flavor_string = GetDisassemblyFlavor();
+  }
+
+  return Disassembler::DisassembleBytes(
+    GetArchitecture(), nullptr, flavor_string,
+    GetDisassemblyCPU(), GetDisassemblyFeatures(),
+    start_addr, data.GetBytes(), bytes_read, count, data_from_file);
+}
+
 SourceManager &Target::GetSourceManager() {
   if (!m_source_manager_up)
     m_source_manager_up = std::make_unique<SourceManager>(shared_from_this());
diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.h 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
index f87a9f3984711..7f49a40853294 100644
--- a/lldb/tools/lldb-dap/Protocol/DAPTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
@@ -31,7 +31,7 @@ struct PersistenceData {
   /// The source module path.
   std::string module;
 
-  /// The file address inside the module.
+  /// The file address of the function.
   lldb::addr_t file_addr;
 };
 bool fromJSON(const llvm::json::Value &, PersistenceData &,

>From 189c308f229153320cda6886c407cb0f0ffb3838 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 6 Jul 2025 16:35:40 +0200
Subject: [PATCH 06/19] format

---
 lldb/include/lldb/API/SBTarget.h              |  6 ++--
 .../lldb/Breakpoint/BreakpointResolver.h      |  6 ++--
 .../Breakpoint/BreakpointResolverAddress.h    |  6 ++--
 lldb/include/lldb/Target/Target.h             | 10 +++----
 lldb/source/API/SBTarget.cpp                  | 13 ++++++---
 lldb/source/Breakpoint/BreakpointResolver.cpp | 14 +++++----
 .../Breakpoint/BreakpointResolverAddress.cpp  |  6 ++--
 lldb/source/Target/Target.cpp                 | 29 +++++++++----------
 8 files changed, 49 insertions(+), 41 deletions(-)

diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 06c1dc2ca08ca..a135e3ce4db58 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -738,8 +738,10 @@ class LLDB_API SBTarget {
 
   lldb::SBBreakpoint BreakpointCreateBySBAddress(SBAddress &address);
 
-  lldb::SBBreakpoint BreakpointCreateByFileAddress(const SBFileSpec &file_spec,
-                                                   addr_t file_addr, addr_t 
offset = 0, addr_t instructions_offset = 0);
+  lldb::SBBreakpoint
+  BreakpointCreateByFileAddress(const SBFileSpec &file_spec, addr_t file_addr,
+                                addr_t offset = 0,
+                                addr_t instructions_offset = 0);
 
   /// Create a breakpoint using a scripted resolver.
   ///
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolver.h 
b/lldb/include/lldb/Breakpoint/BreakpointResolver.h
index c83f4d249e6d1..adb577e2600b9 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolver.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolver.h
@@ -46,8 +46,7 @@ class BreakpointResolver : public Searcher {
   ///   The breakpoint that owns this resolver.
   /// \param[in] resolverType
   ///   The concrete breakpoint resolver type for this breakpoint.
-  BreakpointResolver(const lldb::BreakpointSP &bkpt,
-                     unsigned char resolverType,
+  BreakpointResolver(const lldb::BreakpointSP &bkpt, unsigned char 
resolverType,
                      lldb::addr_t offset = 0,
                      lldb::addr_t instructions_offset = 0);
 
@@ -223,7 +222,8 @@ class BreakpointResolver : public Searcher {
   lldb::BreakpointWP m_breakpoint; // This is the breakpoint we add locations 
to.
   lldb::addr_t m_offset;    // A random offset the user asked us to add to any
                             // breakpoints we set.
-  lldb::addr_t m_instructions_offset; // Number of instructions to add to the 
resolved breakpoint address.
+  lldb::addr_t m_instructions_offset; // Number of instructions to add to the
+                                      // resolved breakpoint address.
 
   // Subclass identifier (for llvm isa/dyn_cast)
   const unsigned char SubclassID;
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h 
b/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h
index bc6f057e366cb..01318bbfe0d4a 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h
@@ -28,10 +28,8 @@ class BreakpointResolverAddress : public BreakpointResolver {
                             const Address &addr,
                             const FileSpec &module_spec);
 
-  BreakpointResolverAddress(const lldb::BreakpointSP &bkpt,
-                            const Address &addr,
-                            const FileSpec &module_spec,
-                            lldb::addr_t offset,
+  BreakpointResolverAddress(const lldb::BreakpointSP &bkpt, const Address 
&addr,
+                            const FileSpec &module_spec, lldb::addr_t offset,
                             lldb::addr_t instructions_offset);
 
   ~BreakpointResolverAddress() override = default;
diff --git a/lldb/include/lldb/Target/Target.h 
b/lldb/include/lldb/Target/Target.h
index 80c4898e957cf..5730f7b369cd6 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -725,12 +725,10 @@ class Target : public 
std::enable_shared_from_this<Target>,
                                       bool request_hardware);
 
   // Use this to create a breakpoint from a file address and a module file spec
-  lldb::BreakpointSP CreateAddressInModuleBreakpoint(lldb::addr_t file_addr,
-                                                     bool internal,
-                                                     const FileSpec &file_spec,
-                                                     bool request_hardware,
-                                                     lldb::addr_t offset = 0,
-                                                     lldb::addr_t 
instructions_offset = 0);
+  lldb::BreakpointSP CreateAddressInModuleBreakpoint(
+      lldb::addr_t file_addr, bool internal, const FileSpec &file_spec,
+      bool request_hardware, lldb::addr_t offset = 0,
+      lldb::addr_t instructions_offset = 0);
 
   // Use this to create Address breakpoints:
   lldb::BreakpointSP CreateBreakpoint(const Address &addr, bool internal,
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 116f527d9068c..ce502e453dcd9 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -950,14 +950,19 @@ SBBreakpoint 
SBTarget::BreakpointCreateBySBAddress(SBAddress &sb_address) {
   return sb_bp;
 }
 
-SBBreakpoint SBTarget::BreakpointCreateByFileAddress(const SBFileSpec 
&file_spec, addr_t file_addr, addr_t offset, addr_t instructions_offset) {
+SBBreakpoint
+SBTarget::BreakpointCreateByFileAddress(const SBFileSpec &file_spec,
+                                        addr_t file_addr, addr_t offset,
+                                        addr_t instructions_offset) {
   LLDB_INSTRUMENT_VA(this, file_spec, file_addr);
 
   SBBreakpoint sb_bp;
   if (TargetSP target_sp = GetSP()) {
     std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
     const bool hardware = false;
-    sb_bp = target_sp->CreateAddressInModuleBreakpoint(file_addr, false, 
*file_spec.get(), hardware, offset, instructions_offset);
+    sb_bp = target_sp->CreateAddressInModuleBreakpoint(
+        file_addr, false, *file_spec.get(), hardware, offset,
+        instructions_offset);
   }
 
   return sb_bp;
@@ -1969,8 +1974,8 @@ lldb::SBInstructionList 
SBTarget::ReadInstructions(lldb::SBAddress base_addr,
 
   if (TargetSP target_sp = GetSP()) {
     if (Address *addr_ptr = base_addr.get()) {
-      sb_instructions.SetDisassembler(target_sp->ReadInstructions(
-          *addr_ptr, count, flavor_string));
+      sb_instructions.SetDisassembler(
+          target_sp->ReadInstructions(*addr_ptr, count, flavor_string));
     }
   }
 
diff --git a/lldb/source/Breakpoint/BreakpointResolver.cpp 
b/lldb/source/Breakpoint/BreakpointResolver.cpp
index a5cd9372527ac..0bca1337e3cff 100644
--- a/lldb/source/Breakpoint/BreakpointResolver.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolver.cpp
@@ -43,9 +43,11 @@ const char *BreakpointResolver::g_ty_to_name[] = 
{"FileAndLine", "Address",
 
 const char *BreakpointResolver::g_option_names[static_cast<uint32_t>(
     BreakpointResolver::OptionNames::LastOptionName)] = {
-    "AddressOffset", "Exact",     "FileName",     "Inlines",     "Language",
-    "LineNumber",    "Column",    "ModuleName",   "NameMask",    "Offset",
-    "PythonClass",   "Regex",     "ScriptArgs",   "SectionName", "SearchDepth",
+    "AddressOffset", "Exact",       "FileName",
+    "Inlines",       "Language",    "LineNumber",
+    "Column",        "ModuleName",  "NameMask",
+    "Offset",        "PythonClass", "Regex",
+    "ScriptArgs",    "SectionName", "SearchDepth",
     "SkipPrologue",  "SymbolNames", "InstructionsOffset"};
 
 const char *BreakpointResolver::ResolverTyToName(enum ResolverTy type) {
@@ -68,7 +70,8 @@ BreakpointResolver::BreakpointResolver(const BreakpointSP 
&bkpt,
                                        const unsigned char resolverTy,
                                        lldb::addr_t offset,
                                        lldb::addr_t instructions_offset)
-    : m_breakpoint(bkpt), m_offset(offset), 
m_instructions_offset(instructions_offset), SubclassID(resolverTy) {}
+    : m_breakpoint(bkpt), m_offset(offset),
+      m_instructions_offset(instructions_offset), SubclassID(resolverTy) {}
 
 BreakpointResolver::~BreakpointResolver() = default;
 
@@ -368,7 +371,8 @@ BreakpointLocationSP 
BreakpointResolver::AddLocation(Address loc_addr,
                                                      bool *new_location) {
   if (m_instructions_offset != 0) {
     Target &target = GetBreakpoint()->GetTarget();
-    const DisassemblerSP instructions = target.ReadInstructions(loc_addr, 
m_instructions_offset);
+    const DisassemblerSP instructions =
+        target.ReadInstructions(loc_addr, m_instructions_offset);
     loc_addr.Slide(instructions->GetInstructionList().GetTotalByteSize());
   }
 
diff --git a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp 
b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
index 5298cbc76dc1f..a0343e3957c2e 100644
--- a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
@@ -31,8 +31,10 @@ BreakpointResolverAddress::BreakpointResolverAddress(const 
BreakpointSP &bkpt,
       m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS) {}
 
 BreakpointResolverAddress::BreakpointResolverAddress(
-    const BreakpointSP &bkpt, const Address &addr, const FileSpec 
&module_spec, lldb::addr_t offset, lldb::addr_t instructions_offset)
-    : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver, offset, 
instructions_offset),
+    const BreakpointSP &bkpt, const Address &addr, const FileSpec &module_spec,
+    lldb::addr_t offset, lldb::addr_t instructions_offset)
+    : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver, offset,
+                         instructions_offset),
       m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS),
       m_module_filespec(module_spec) {}
 
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 82f07829b05b3..bb276c0a81795 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -565,12 +565,10 @@ BreakpointSP Target::CreateBreakpoint(const Address 
&addr, bool internal,
   return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, false);
 }
 
-lldb::BreakpointSP
-Target::CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal,
-                                        const FileSpec &file_spec,
-                                        bool request_hardware,
-                                        lldb::addr_t offset,
-                                        lldb::addr_t instructions_offset) {
+lldb::BreakpointSP Target::CreateAddressInModuleBreakpoint(
+    lldb::addr_t file_addr, bool internal, const FileSpec &file_spec,
+    bool request_hardware, lldb::addr_t offset,
+    lldb::addr_t instructions_offset) {
   SearchFilterSP filter_sp(
       new SearchFilterForUnconstrainedSearches(shared_from_this()));
   BreakpointResolverSP resolver_sp(new BreakpointResolverAddress(
@@ -2993,8 +2991,9 @@ lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t 
addr) {
   return arch_plugin ? arch_plugin->GetBreakableLoadAddress(addr, *this) : 
addr;
 }
 
-lldb::DisassemblerSP Target::ReadInstructions(const Address &start_addr, 
uint32_t count,
-                                             const char *flavor_string) {
+lldb::DisassemblerSP Target::ReadInstructions(const Address &start_addr,
+                                              uint32_t count,
+                                              const char *flavor_string) {
   if (!m_process_sp)
     return lldb::DisassemblerSP();
 
@@ -3002,24 +3001,24 @@ lldb::DisassemblerSP Target::ReadInstructions(const 
Address &start_addr, uint32_
   bool force_live_memory = true;
   lldb_private::Status error;
   lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
-  const size_t bytes_read = ReadMemory(start_addr, data.GetBytes(), 
data.GetByteSize(),
-                            error, force_live_memory, &load_addr);
+  const size_t bytes_read =
+      ReadMemory(start_addr, data.GetBytes(), data.GetByteSize(), error,
+                 force_live_memory, &load_addr);
 
   const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
   if (!flavor_string || flavor_string[0] == '\0') {
     // FIXME - we don't have the mechanism in place to do per-architecture
     // settings.  But since we know that for now we only support flavors on
     // x86 & x86_64,
-    const llvm::Triple::ArchType arch =
-      GetArchitecture().GetTriple().getArch();
+    const llvm::Triple::ArchType arch = 
GetArchitecture().GetTriple().getArch();
     if (arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64)
       flavor_string = GetDisassemblyFlavor();
   }
 
   return Disassembler::DisassembleBytes(
-    GetArchitecture(), nullptr, flavor_string,
-    GetDisassemblyCPU(), GetDisassemblyFeatures(),
-    start_addr, data.GetBytes(), bytes_read, count, data_from_file);
+      GetArchitecture(), nullptr, flavor_string, GetDisassemblyCPU(),
+      GetDisassemblyFeatures(), start_addr, data.GetBytes(), bytes_read, count,
+      data_from_file);
 }
 
 SourceManager &Target::GetSourceManager() {

>From 543bc2af15e665fe0be31f2972f9db339ee8733d Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 6 Jul 2025 16:42:47 +0200
Subject: [PATCH 07/19] instruction offset

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

diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp 
b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index 683e3c3eb1ff1..95c54fb18a29e 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -117,7 +117,8 @@ llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithSourceReference(int64_
 
 llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithPersistenceData(const 
protocol::PersistenceData &persistence_data) {
   lldb::SBFileSpec file_spec(persistence_data.module.c_str());
-  m_bp = m_dap.target.BreakpointCreateByFileAddress(file_spec, 
persistence_data.file_addr);
+  m_bp = m_dap.target.BreakpointCreateByFileAddress(
+      file_spec, persistence_data.file_addr, 0, m_line - 1);
   return llvm::Error::success();
 }
 

>From 19127b99a42de3e010c601da77f26945f9309f94 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 6 Jul 2025 16:43:14 +0200
Subject: [PATCH 08/19] format

---
 lldb/tools/lldb-dap/Protocol/DAPTypes.h  | 14 +++++-----
 lldb/tools/lldb-dap/SourceBreakpoint.cpp | 33 ++++++++++++++----------
 lldb/tools/lldb-dap/SourceBreakpoint.h   |  6 +++--
 3 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.h 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
index 7f49a40853294..f112b5af772e3 100644
--- a/lldb/tools/lldb-dap/Protocol/DAPTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
@@ -23,10 +23,10 @@
 
 namespace lldb_dap::protocol {
 
-/// Data used to help lldb-dap resolve breakpoints persistently across 
different sessions.
-/// This information is especially useful for assembly breakpoints, because 
`sourceReference`
-/// can change across sessions. For regular source breakpoints the path and 
line are the same
-/// For each session.
+/// Data used to help lldb-dap resolve breakpoints persistently across 
different
+/// sessions. This information is especially useful for assembly breakpoints,
+/// because `sourceReference` can change across sessions. For regular source
+/// breakpoints the path and line are the same For each session.
 struct PersistenceData {
   /// The source module path.
   std::string module;
@@ -34,15 +34,15 @@ struct PersistenceData {
   /// The file address of the function.
   lldb::addr_t file_addr;
 };
-bool fromJSON(const llvm::json::Value &, PersistenceData &,
-              llvm::json::Path);
+bool fromJSON(const llvm::json::Value &, PersistenceData &, llvm::json::Path);
 llvm::json::Value toJSON(const PersistenceData &);
 
 /// Custom source data used by lldb-dap.
 /// This data should help lldb-dap identify sources correctly across different
 /// sessions.
 struct SourceLLDBData {
-  /// Data that helps lldb resolve this source persistently across different 
sessions.
+  /// Data that helps lldb resolve this source persistently across different
+  /// sessions.
   std::optional<PersistenceData> persistence_data;
 };
 bool fromJSON(const llvm::json::Value &, SourceLLDBData &, llvm::json::Path);
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp 
b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index 95c54fb18a29e..5d87409b45a96 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -49,12 +49,15 @@ llvm::Error SourceBreakpoint::SetBreakpoint(const 
protocol::Source &source) {
   if (IsAssemblySource(source)) {
     // Breakpoint set by assembly source.
     if (source.adapterData && source.adapterData->persistence_data) {
-      // Prefer use the adapter persitence data, because this could be a 
breakpoint 
-      // from a previous session where the `sourceReference` is not valid 
anymore.
-      if (llvm::Error error = 
CreateAssemblyBreakpointWithPersistenceData(*source.adapterData->persistence_data))
+      // Prefer use the adapter persitence data, because this could be a
+      // breakpoint from a previous session where the `sourceReference` is not
+      // valid anymore.
+      if (llvm::Error error = CreateAssemblyBreakpointWithPersistenceData(
+              *source.adapterData->persistence_data))
         return error;
     } else {
-      if (llvm::Error error = 
CreateAssemblyBreakpointWithSourceReference(*source.sourceReference))
+      if (llvm::Error error = CreateAssemblyBreakpointWithSourceReference(
+              *source.sourceReference))
         return error;
     }
   } else {
@@ -77,36 +80,37 @@ void SourceBreakpoint::UpdateBreakpoint(const 
SourceBreakpoint &request_bp) {
 
 void SourceBreakpoint::CreatePathBreakpoint(const protocol::Source &source) {
   const auto source_path = 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);
+  lldb::SBFileSpecList module_list;
+  m_bp = m_dap.target.BreakpointCreateByLocation(source_path.c_str(), m_line,
+                                                 m_column, 0, module_list);
 }
 
-llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithSourceReference(int64_t 
source_reference) {
+llvm::Error SourceBreakpoint::CreateAssemblyBreakpointWithSourceReference(
+    int64_t source_reference) {
   std::optional<lldb::addr_t> raw_addr =
       m_dap.GetSourceReferenceAddress(source_reference);
   if (!raw_addr)
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                    "Invalid sourceReference.");
+                                   "Invalid sourceReference.");
 
   lldb::SBAddress source_address(*raw_addr, m_dap.target);
   if (!source_address.IsValid())
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                    "Invalid sourceReference.");
+                                   "Invalid sourceReference.");
 
   lldb::SBSymbol symbol = source_address.GetSymbol();
   if (!symbol.IsValid()) {
     // FIXME: Support assembly breakpoints without a valid symbol.
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                    "Breakpoints in assembly without a valid "
-                                    "symbol are not supported yet.");
+                                   "Breakpoints in assembly without a valid "
+                                   "symbol are not supported yet.");
   }
 
   lldb::SBInstructionList inst_list =
       m_dap.target.ReadInstructions(symbol.GetStartAddress(), m_line);
   if (inst_list.GetSize() < m_line)
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                    "Invalid instruction list size.");
+                                   "Invalid instruction list size.");
 
   lldb::SBAddress address =
       inst_list.GetInstructionAtIndex(m_line - 1).GetAddress();
@@ -115,7 +119,8 @@ llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithSourceReference(int64_
   return llvm::Error::success();
 }
 
-llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithPersistenceData(const 
protocol::PersistenceData &persistence_data) {
+llvm::Error SourceBreakpoint::CreateAssemblyBreakpointWithPersistenceData(
+    const protocol::PersistenceData &persistence_data) {
   lldb::SBFileSpec file_spec(persistence_data.module.c_str());
   m_bp = m_dap.target.BreakpointCreateByFileAddress(
       file_spec, persistence_data.file_addr, 0, m_line - 1);
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.h 
b/lldb/tools/lldb-dap/SourceBreakpoint.h
index b9086a0c8fbb7..34054a8dcfd5f 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.h
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.h
@@ -52,8 +52,10 @@ class SourceBreakpoint : public Breakpoint {
 
 protected:
   void CreatePathBreakpoint(const protocol::Source &source);
-  llvm::Error CreateAssemblyBreakpointWithSourceReference(int64_t 
source_reference);
-  llvm::Error CreateAssemblyBreakpointWithPersistenceData(const 
protocol::PersistenceData &persistence_data);
+  llvm::Error
+  CreateAssemblyBreakpointWithSourceReference(int64_t source_reference);
+  llvm::Error CreateAssemblyBreakpointWithPersistenceData(
+      const protocol::PersistenceData &persistence_data);
 
   // logMessage part can be either a raw text or an expression.
   struct LogMessagePart {

>From 61c34695865ebdb910b0e067b8cea4e208ba0c48 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 6 Jul 2025 17:17:51 +0200
Subject: [PATCH 09/19] add persistence data to response

---
 lldb/tools/lldb-dap/Breakpoint.cpp | 38 +++++++++++++++++++++++++-----
 lldb/tools/lldb-dap/DAP.cpp        | 12 +++++++---
 2 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp 
b/lldb/tools/lldb-dap/Breakpoint.cpp
index b4e593eb83d27..346a8037f6223 100644
--- a/lldb/tools/lldb-dap/Breakpoint.cpp
+++ b/lldb/tools/lldb-dap/Breakpoint.cpp
@@ -8,10 +8,13 @@
 
 #include "Breakpoint.h"
 #include "DAP.h"
+#include "Protocol/DAPTypes.h"
 #include "ProtocolUtils.h"
 #include "lldb/API/SBAddress.h"
 #include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBFileSpec.h"
 #include "lldb/API/SBLineEntry.h"
+#include "lldb/API/SBModule.h"
 #include "lldb/API/SBMutex.h"
 #include "llvm/ADT/StringExtras.h"
 #include <cstddef>
@@ -21,6 +24,22 @@
 
 using namespace lldb_dap;
 
+static std::optional<protocol::PersistenceData>
+GetPersistenceDataForAddress(lldb::SBAddress &addr) {
+  protocol::PersistenceData persistence_data;
+  lldb::SBModule module = addr.GetModule();
+  if (!module.IsValid())
+    return std::nullopt;
+
+  lldb::SBFileSpec file_spec = module.GetFileSpec();
+  if (!file_spec.IsValid())
+    return std::nullopt;
+
+  persistence_data.module = file_spec.GetFilename();
+  persistence_data.file_addr = addr.GetFileAddress();
+  return persistence_data;
+}
+
 void Breakpoint::SetCondition() { m_bp.SetCondition(m_condition.c_str()); }
 
 void Breakpoint::SetHitCondition() {
@@ -73,15 +92,22 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() {
       const auto column = line_entry.GetColumn();
       if (column != LLDB_INVALID_COLUMN_NUMBER)
         breakpoint.column = column;
-    } else {
+    } else if (source) {
       // Assembly breakpoint.
       auto symbol = bp_addr.GetSymbol();
       if (symbol.IsValid()) {
-        breakpoint.line =
-            m_bp.GetTarget()
-                .ReadInstructions(symbol.GetStartAddress(), bp_addr, nullptr)
-                .GetSize() +
-            1;
+        lldb::SBAddress start_address = symbol.GetStartAddress();
+        breakpoint.line = m_bp.GetTarget()
+                              .ReadInstructions(start_address, bp_addr, 
nullptr)
+                              .GetSize() +
+                          1;
+
+        // Add persistent data so that the breakpoint can be resolved
+        // in future sessions.
+        std::optional<protocol::PersistenceData> persistence_data =
+            GetPersistenceDataForAddress(start_address);
+        if (persistence_data)
+          source->adapterData->persistence_data = std::move(persistence_data);
       }
     }
 
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index fd89f52595ec6..d748200509643 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -31,6 +31,7 @@
 #include "lldb/API/SBStream.h"
 #include "lldb/Utility/IOObject.h"
 #include "lldb/Utility/Status.h"
+#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-types.h"
@@ -1406,11 +1407,16 @@ void DAP::EventThread() {
             // avoids sending paths that should be source mapped. Note that
             // CreateBreakpoint doesn't apply source mapping and certain
             // implementation ignore the source part of this event anyway.
-            llvm::json::Value source_bp = bp.ToProtocolBreakpoint();
-            source_bp.getAsObject()->erase("source");
+            protocol::Breakpoint protocol_bp = bp.ToProtocolBreakpoint();
+            llvm::json::Value protocol_bp_value = toJSON(protocol_bp);
+
+            // "source" is not needed here, unless we add adapter data to be
+            // saved by the client.
+            if (protocol_bp.source && !protocol_bp.source->adapterData)
+              protocol_bp_value.getAsObject()->erase("source");
 
             llvm::json::Object body;
-            body.try_emplace("breakpoint", source_bp);
+            body.try_emplace("breakpoint", protocol_bp);
             body.try_emplace("reason", "changed");
 
             llvm::json::Object bp_event = CreateEventObject("breakpoint");

>From a493c4ced971048eb159337768f6141370d3ea2b Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Sun, 6 Jul 2025 17:52:27 +0200
Subject: [PATCH 10/19] fix

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

diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp 
b/lldb/tools/lldb-dap/Breakpoint.cpp
index 346a8037f6223..64590c1845e6d 100644
--- a/lldb/tools/lldb-dap/Breakpoint.cpp
+++ b/lldb/tools/lldb-dap/Breakpoint.cpp
@@ -106,8 +106,10 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() {
         // in future sessions.
         std::optional<protocol::PersistenceData> persistence_data =
             GetPersistenceDataForAddress(start_address);
-        if (persistence_data)
-          source->adapterData->persistence_data = std::move(persistence_data);
+        if (persistence_data) {
+          source->adapterData =
+              protocol::SourceLLDBData{std::move(persistence_data)};
+        }
       }
     }
 

>From 6aaae350855df202ec468ac5640cd9c7679b91a0 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Tue, 8 Jul 2025 20:55:20 +0200
Subject: [PATCH 11/19] fix

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

diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp 
b/lldb/tools/lldb-dap/Breakpoint.cpp
index 64590c1845e6d..ac47975c4e9d2 100644
--- a/lldb/tools/lldb-dap/Breakpoint.cpp
+++ b/lldb/tools/lldb-dap/Breakpoint.cpp
@@ -8,6 +8,7 @@
 
 #include "Breakpoint.h"
 #include "DAP.h"
+#include "LLDBUtils.h"
 #include "Protocol/DAPTypes.h"
 #include "ProtocolUtils.h"
 #include "lldb/API/SBAddress.h"
@@ -35,7 +36,7 @@ GetPersistenceDataForAddress(lldb::SBAddress &addr) {
   if (!file_spec.IsValid())
     return std::nullopt;
 
-  persistence_data.module = file_spec.GetFilename();
+  persistence_data.module = GetSBFileSpecPath(file_spec);
   persistence_data.file_addr = addr.GetFileAddress();
   return persistence_data;
 }

>From 66510aa16cda65639665cdff205aa952fa440ad5 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Tue, 8 Jul 2025 22:46:48 +0200
Subject: [PATCH 12/19] fix address resolve of a module that is not loaded yet

---
 lldb/source/Breakpoint/BreakpointResolverAddress.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp 
b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
index a0343e3957c2e..fae2022220ba3 100644
--- a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
@@ -141,6 +141,11 @@ Searcher::CallbackReturn 
BreakpointResolverAddress::SearchCallback(
           Address tmp_address;
           if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))
             m_addr = tmp_address;
+          else
+            return Searcher::eCallbackReturnStop;
+        } else {
+          // If we didn't find the module, then we can't resolve the address.
+          return Searcher::eCallbackReturnStop;
         }
       }
 

>From f528713000f0f2e65eb46c71a26852f4d95d02a5 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Wed, 9 Jul 2025 02:08:50 +0200
Subject: [PATCH 13/19] fix check

---
 lldb/tools/lldb-dap/SourceBreakpoint.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp 
b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index 5d87409b45a96..ffd28c9592fba 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -46,7 +46,7 @@ llvm::Error SourceBreakpoint::SetBreakpoint(const 
protocol::Source &source) {
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "Invalid line number.");
 
-  if (IsAssemblySource(source)) {
+  if (source.sourceReference) {
     // Breakpoint set by assembly source.
     if (source.adapterData && source.adapterData->persistence_data) {
       // Prefer use the adapter persitence data, because this could be a

>From 0019d2cbbff17ba09402070d18db9c8aa2a81216 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Thu, 10 Jul 2025 22:21:38 +0200
Subject: [PATCH 14/19] conventions

---
 lldb/tools/lldb-dap/Breakpoint.cpp        |  2 +-
 lldb/tools/lldb-dap/DAP.cpp               |  3 ++-
 lldb/tools/lldb-dap/Protocol/DAPTypes.cpp | 10 +++++-----
 lldb/tools/lldb-dap/Protocol/DAPTypes.h   |  4 ++--
 lldb/tools/lldb-dap/SourceBreakpoint.cpp  |  6 +++---
 5 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp 
b/lldb/tools/lldb-dap/Breakpoint.cpp
index ac47975c4e9d2..01d46c5a29553 100644
--- a/lldb/tools/lldb-dap/Breakpoint.cpp
+++ b/lldb/tools/lldb-dap/Breakpoint.cpp
@@ -37,7 +37,7 @@ GetPersistenceDataForAddress(lldb::SBAddress &addr) {
     return std::nullopt;
 
   persistence_data.module = GetSBFileSpecPath(file_spec);
-  persistence_data.file_addr = addr.GetFileAddress();
+  persistence_data.fileAddress = addr.GetFileAddress();
   return persistence_data;
 }
 
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index d748200509643..e4fc182bf5fb4 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -1497,8 +1497,9 @@ std::vector<protocol::Breakpoint> 
DAP::SetSourceBreakpoints(
 
       protocol::Breakpoint response_breakpoint =
           iv->second.ToProtocolBreakpoint();
-      response_breakpoint.source = source;
 
+      if (!response_breakpoint.source)
+        response_breakpoint.source = source;
       if (!response_breakpoint.line &&
           src_bp.GetLine() != LLDB_INVALID_LINE_NUMBER)
         response_breakpoint.line = src_bp.GetLine();
diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
index e45a4f30d9bcf..c4b20bb06f8dc 100644
--- a/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.cpp
@@ -9,13 +9,13 @@ bool fromJSON(const llvm::json::Value &Params, 
PersistenceData &PD,
               llvm::json::Path P) {
   json::ObjectMapper O(Params, P);
   return O && O.mapOptional("module", PD.module) &&
-         O.mapOptional("file_addr", PD.file_addr);
+         O.mapOptional("fileAddress", PD.fileAddress);
 }
 
 llvm::json::Value toJSON(const PersistenceData &PD) {
   json::Object result{
       {"module", PD.module},
-      {"file_addr", PD.file_addr},
+      {"fileAddress", PD.fileAddress},
   };
 
   return result;
@@ -24,13 +24,13 @@ llvm::json::Value toJSON(const PersistenceData &PD) {
 bool fromJSON(const llvm::json::Value &Params, SourceLLDBData &SLD,
               llvm::json::Path P) {
   json::ObjectMapper O(Params, P);
-  return O && O.mapOptional("persistence_data", SLD.persistence_data);
+  return O && O.mapOptional("persistenceData", SLD.persistenceData);
 }
 
 llvm::json::Value toJSON(const SourceLLDBData &SLD) {
   json::Object result;
-  if (SLD.persistence_data)
-    result.insert({"persistence_data", SLD.persistence_data});
+  if (SLD.persistenceData)
+    result.insert({"persistenceData", SLD.persistenceData});
   return result;
 }
 
diff --git a/lldb/tools/lldb-dap/Protocol/DAPTypes.h 
b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
index f112b5af772e3..be019122f2eb5 100644
--- a/lldb/tools/lldb-dap/Protocol/DAPTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/DAPTypes.h
@@ -32,7 +32,7 @@ struct PersistenceData {
   std::string module;
 
   /// The file address of the function.
-  lldb::addr_t file_addr;
+  lldb::addr_t fileAddress;
 };
 bool fromJSON(const llvm::json::Value &, PersistenceData &, llvm::json::Path);
 llvm::json::Value toJSON(const PersistenceData &);
@@ -43,7 +43,7 @@ llvm::json::Value toJSON(const PersistenceData &);
 struct SourceLLDBData {
   /// Data that helps lldb resolve this source persistently across different
   /// sessions.
-  std::optional<PersistenceData> persistence_data;
+  std::optional<PersistenceData> persistenceData;
 };
 bool fromJSON(const llvm::json::Value &, SourceLLDBData &, llvm::json::Path);
 llvm::json::Value toJSON(const SourceLLDBData &);
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp 
b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index ffd28c9592fba..ffc38a24e82a7 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -48,12 +48,12 @@ llvm::Error SourceBreakpoint::SetBreakpoint(const 
protocol::Source &source) {
 
   if (source.sourceReference) {
     // Breakpoint set by assembly source.
-    if (source.adapterData && source.adapterData->persistence_data) {
+    if (source.adapterData && source.adapterData->persistenceData) {
       // Prefer use the adapter persitence data, because this could be a
       // breakpoint from a previous session where the `sourceReference` is not
       // valid anymore.
       if (llvm::Error error = CreateAssemblyBreakpointWithPersistenceData(
-              *source.adapterData->persistence_data))
+              *source.adapterData->persistenceData))
         return error;
     } else {
       if (llvm::Error error = CreateAssemblyBreakpointWithSourceReference(
@@ -123,7 +123,7 @@ llvm::Error 
SourceBreakpoint::CreateAssemblyBreakpointWithPersistenceData(
     const protocol::PersistenceData &persistence_data) {
   lldb::SBFileSpec file_spec(persistence_data.module.c_str());
   m_bp = m_dap.target.BreakpointCreateByFileAddress(
-      file_spec, persistence_data.file_addr, 0, m_line - 1);
+      file_spec, persistence_data.fileAddress, 0, m_line - 1);
   return llvm::Error::success();
 }
 

>From 57459f9409bd2288408eb075843936eb2bb487f3 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Thu, 10 Jul 2025 22:42:53 +0200
Subject: [PATCH 15/19] add persistence assembly breakpoint test

---
 .../test/tools/lldb-dap/dap_server.py         | 29 ++++++--
 .../test/tools/lldb-dap/lldbdap_testcase.py   | 22 +++---
 .../TestDAP_breakpointAssembly.py             | 69 +++++++++++++++++++
 3 files changed, 102 insertions(+), 18 deletions(-)

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 68f58bf1349a7..5b39540d0b876 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
@@ -107,17 +107,20 @@ def dump_dap_log(log_file):
 
 class Source(object):
     def __init__(
-        self, path: Optional[str] = None, source_reference: Optional[int] = 
None
+        self, path: Optional[str] = None, source_reference: Optional[int] = 
None, raw_dict: Optional[dict[str, Any]] = None
     ):
         self._name = None
         self._path = None
         self._source_reference = None
+        self._raw_dict = None
 
         if path is not None:
             self._name = os.path.basename(path)
             self._path = path
         elif source_reference is not None:
             self._source_reference = source_reference
+        elif raw_dict is not None:
+            self._raw_dict = raw_dict
         else:
             raise ValueError("Either path or source_reference must be 
provided")
 
@@ -125,6 +128,9 @@ def __str__(self):
         return f"Source(name={self.name}, path={self.path}), 
source_reference={self.source_reference})"
 
     def as_dict(self):
+        if self._raw_dict is not None:
+            return self._raw_dict
+
         source_dict = {}
         if self._name is not None:
             source_dict["name"] = self._name
@@ -135,6 +141,19 @@ def as_dict(self):
         return source_dict
 
 
+class Breakpoint(object):
+    def __init__(self, obj):
+        self._breakpoint = obj
+
+    def is_verified(self):
+        """Check if the breakpoint is verified."""
+        return self._breakpoint.get("verified", False)
+    
+    def source(self):
+        """Get the source of the breakpoint."""
+        return self._breakpoint.get("source", {})
+
+
 class NotSupportedError(KeyError):
     """Raised if a feature is not supported due to its capabilities."""
 
@@ -170,7 +189,7 @@ def __init__(
         self.initialized = False
         self.frame_scopes = {}
         self.init_commands = init_commands
-        self.resolved_breakpoints = {}
+        self.resolved_breakpoints: dict[str, Breakpoint] = {}
 
     @classmethod
     def encode_content(cls, s: str) -> bytes:
@@ -326,9 +345,7 @@ def _process_continued(self, all_threads_continued: bool):
     def _update_verified_breakpoints(self, breakpoints: list[Event]):
         for breakpoint in breakpoints:
             if "id" in breakpoint:
-                self.resolved_breakpoints[str(breakpoint["id"])] = 
breakpoint.get(
-                    "verified", False
-                )
+                self.resolved_breakpoints[str(breakpoint["id"])] = 
Breakpoint(breakpoint)
 
     def send_packet(self, command_dict: Request, set_sequence=True):
         """Take the "command_dict" python dictionary and encode it as a JSON
@@ -484,7 +501,7 @@ def wait_for_breakpoints_to_be_verified(
             if breakpoint_event is None:
                 break
 
-        return [id for id in breakpoint_ids if id not in 
self.resolved_breakpoints]
+        return [id for id in breakpoint_ids if (id not in 
self.resolved_breakpoints or not self.resolved_breakpoints[id].is_verified())]
 
     def wait_for_exited(self, timeout: Optional[float] = None):
         event_dict = self.wait_for_event("exited", timeout=timeout)
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 00b01d4bdb1c5..57a580052557e 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
@@ -59,24 +59,22 @@ def set_source_breakpoints(
         Each object in data is 1:1 mapping with the entry in lines.
         It contains optional location/hitCondition/logMessage parameters.
         """
-        response = self.dap_server.request_setBreakpoints(
-            Source(source_path), lines, data
+        return self.set_source_breakpoints_from_source(
+            Source(path=source_path), lines, data, wait_for_resolve
         )
-        if response is None or not response["success"]:
-            return []
-        breakpoints = response["body"]["breakpoints"]
-        breakpoint_ids = []
-        for breakpoint in breakpoints:
-            breakpoint_ids.append("%i" % (breakpoint["id"]))
-        if wait_for_resolve:
-            self.wait_for_breakpoints_to_resolve(breakpoint_ids)
-        return breakpoint_ids
 
     def set_source_breakpoints_assembly(
         self, source_reference, lines, data=None, wait_for_resolve=True
+    ):
+        return self.set_source_breakpoints_from_source(
+            Source(source_reference=source_reference), lines, data, 
wait_for_resolve
+        )
+    
+    def set_source_breakpoints_from_source(
+        self, source: Source, lines, data=None, wait_for_resolve=True
     ):
         response = self.dap_server.request_setBreakpoints(
-            Source(source_reference=source_reference),
+            source,
             lines,
             data,
         )
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 674bfe4199b4a..2ce928cef08e1 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
@@ -83,3 +83,72 @@ def test_break_on_invalid_source_reference(self):
             break_point["message"],
             "Invalid sourceReference.",
         )
+
+    @skipIfWindows
+    def test_persistent_assembly_breakpoint(self):
+        """Tests that assembly breakpoints are working persistently across 
sessions"""
+        self.build()
+        program = self.getBuildArtifact("a.out")
+        self.create_debug_adapter()
+
+        # Run the first session and set a persistent assembly breakpoint
+        try:
+            self.dap_server.request_initialize()
+            self.dap_server.request_launch(program)
+
+            assmebly_func_breakpoints = 
self.set_function_breakpoints(["assembly_func"])
+            self.continue_to_breakpoints(assmebly_func_breakpoints)
+
+            assembly_func_frame = self.get_stackFrames()[0]
+            source_reference = assembly_func_frame["source"]["sourceReference"]
+
+            # Set an assembly breakpoint in the middle of the assembly function
+            persistent_breakpoint_line = 4
+            persistent_breakpoint_ids = self.set_source_breakpoints_assembly(
+                source_reference, [persistent_breakpoint_line]
+            )
+            
+            self.assertEqual(
+                len(persistent_breakpoint_ids), 1, "Expected one assembly 
breakpoint to be set"
+            )
+
+            persistent_breakpoint_source = 
self.dap_server.resolved_breakpoints[persistent_breakpoint_ids[0]].source()
+            self.assertIn(
+                "adapterData",
+                persistent_breakpoint_source,
+                "Expected assembly breakpoint to have persistent information",
+            )
+            self.assertIn(
+                "persistenceData",
+                persistent_breakpoint_source["adapterData"],
+                "Expected assembly breakpoint to have persistent information",
+            )
+
+            self.continue_to_breakpoints(persistent_breakpoint_ids)
+        finally:
+            self.dap_server.request_disconnect(terminateDebuggee=True)
+            self.dap_server.terminate()
+
+        # Restart the session and verify the breakpoint is still there
+        self.create_debug_adapter()
+        try:
+            self.dap_server.request_initialize()
+            self.dap_server.request_launch(program)
+            new_session_breakpoints_ids = 
self.set_source_breakpoints_from_source(
+                Source(raw_dict=persistent_breakpoint_source), 
[persistent_breakpoint_line]
+            )
+            
+            self.assertEqual(
+                len(new_session_breakpoints_ids),
+                1,
+                "Expected one breakpoint to be set in the new session",
+            )
+
+            self.continue_to_breakpoints(new_session_breakpoints_ids)
+            current_line = self.get_stackFrames()[0]["line"]
+            self.assertEqual(current_line, persistent_breakpoint_line,
+                            "Expected to hit the persistent assembly 
breakpoint at the same line")
+        finally:
+            self.dap_server.request_disconnect(terminateDebuggee=True)
+            self.dap_server.terminate()
+

>From 70d369e682f2bf74fe4e92660805ac93d0a73641 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Thu, 10 Jul 2025 23:15:45 +0200
Subject: [PATCH 16/19] fix

---
 lldb/source/API/SBTarget.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index ce502e453dcd9..84478ffe22601 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -66,7 +66,6 @@
 
 #include "Commands/CommandObjectBreakpoint.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/lldb-types.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Regex.h"
 

>From 4b3412ef5c26e61344088283ee95ba517b14b6b2 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Thu, 10 Jul 2025 23:19:11 +0200
Subject: [PATCH 17/19] fix

---
 lldb/source/Target/Target.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index bb276c0a81795..b1d6fdf8f7537 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -2994,9 +2994,6 @@ lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t 
addr) {
 lldb::DisassemblerSP Target::ReadInstructions(const Address &start_addr,
                                               uint32_t count,
                                               const char *flavor_string) {
-  if (!m_process_sp)
-    return lldb::DisassemblerSP();
-
   DataBufferHeap data(GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);
   bool force_live_memory = true;
   lldb_private::Status error;

>From b0e3865596985f5c6f8054e42b12494c8420ee07 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Thu, 10 Jul 2025 23:42:20 +0200
Subject: [PATCH 18/19] python format

---
 .../test/tools/lldb-dap/dap_server.py         | 20 ++++++++++++----
 .../test/tools/lldb-dap/lldbdap_testcase.py   |  2 +-
 .../TestDAP_breakpointAssembly.py             | 23 ++++++++++++-------
 3 files changed, 32 insertions(+), 13 deletions(-)

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 5b39540d0b876..6c6a674f664ad 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
@@ -107,7 +107,10 @@ def dump_dap_log(log_file):
 
 class Source(object):
     def __init__(
-        self, path: Optional[str] = None, source_reference: Optional[int] = 
None, raw_dict: Optional[dict[str, Any]] = None
+        self,
+        path: Optional[str] = None,
+        source_reference: Optional[int] = None,
+        raw_dict: Optional[dict[str, Any]] = None,
     ):
         self._name = None
         self._path = None
@@ -148,7 +151,7 @@ def __init__(self, obj):
     def is_verified(self):
         """Check if the breakpoint is verified."""
         return self._breakpoint.get("verified", False)
-    
+
     def source(self):
         """Get the source of the breakpoint."""
         return self._breakpoint.get("source", {})
@@ -345,7 +348,9 @@ def _process_continued(self, all_threads_continued: bool):
     def _update_verified_breakpoints(self, breakpoints: list[Event]):
         for breakpoint in breakpoints:
             if "id" in breakpoint:
-                self.resolved_breakpoints[str(breakpoint["id"])] = 
Breakpoint(breakpoint)
+                self.resolved_breakpoints[str(breakpoint["id"])] = Breakpoint(
+                    breakpoint
+                )
 
     def send_packet(self, command_dict: Request, set_sequence=True):
         """Take the "command_dict" python dictionary and encode it as a JSON
@@ -501,7 +506,14 @@ def wait_for_breakpoints_to_be_verified(
             if breakpoint_event is None:
                 break
 
-        return [id for id in breakpoint_ids if (id not in 
self.resolved_breakpoints or not self.resolved_breakpoints[id].is_verified())]
+        return [
+            id
+            for id in breakpoint_ids
+            if (
+                id not in self.resolved_breakpoints
+                or not self.resolved_breakpoints[id].is_verified()
+            )
+        ]
 
     def wait_for_exited(self, timeout: Optional[float] = None):
         event_dict = self.wait_for_event("exited", timeout=timeout)
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 57a580052557e..1cb885b149dfd 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
@@ -69,7 +69,7 @@ def set_source_breakpoints_assembly(
         return self.set_source_breakpoints_from_source(
             Source(source_reference=source_reference), lines, data, 
wait_for_resolve
         )
-    
+
     def set_source_breakpoints_from_source(
         self, source: Source, lines, data=None, wait_for_resolve=True
     ):
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 2ce928cef08e1..7552a77d2280a 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
@@ -107,12 +107,16 @@ def test_persistent_assembly_breakpoint(self):
             persistent_breakpoint_ids = self.set_source_breakpoints_assembly(
                 source_reference, [persistent_breakpoint_line]
             )
-            
+
             self.assertEqual(
-                len(persistent_breakpoint_ids), 1, "Expected one assembly 
breakpoint to be set"
+                len(persistent_breakpoint_ids),
+                1,
+                "Expected one assembly breakpoint to be set",
             )
 
-            persistent_breakpoint_source = 
self.dap_server.resolved_breakpoints[persistent_breakpoint_ids[0]].source()
+            persistent_breakpoint_source = 
self.dap_server.resolved_breakpoints[
+                persistent_breakpoint_ids[0]
+            ].source()
             self.assertIn(
                 "adapterData",
                 persistent_breakpoint_source,
@@ -135,9 +139,10 @@ def test_persistent_assembly_breakpoint(self):
             self.dap_server.request_initialize()
             self.dap_server.request_launch(program)
             new_session_breakpoints_ids = 
self.set_source_breakpoints_from_source(
-                Source(raw_dict=persistent_breakpoint_source), 
[persistent_breakpoint_line]
+                Source(raw_dict=persistent_breakpoint_source),
+                [persistent_breakpoint_line],
             )
-            
+
             self.assertEqual(
                 len(new_session_breakpoints_ids),
                 1,
@@ -146,9 +151,11 @@ def test_persistent_assembly_breakpoint(self):
 
             self.continue_to_breakpoints(new_session_breakpoints_ids)
             current_line = self.get_stackFrames()[0]["line"]
-            self.assertEqual(current_line, persistent_breakpoint_line,
-                            "Expected to hit the persistent assembly 
breakpoint at the same line")
+            self.assertEqual(
+                current_line,
+                persistent_breakpoint_line,
+                "Expected to hit the persistent assembly breakpoint at the 
same line",
+            )
         finally:
             self.dap_server.request_disconnect(terminateDebuggee=True)
             self.dap_server.terminate()
-

>From 9c9052061aa4531a13f6fc4710b4758db8deebf7 Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Fri, 11 Jul 2025 09:49:31 +0200
Subject: [PATCH 19/19] remove raw json usage

---
 lldb/tools/lldb-dap/DAP.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index e4fc182bf5fb4..399bf50244994 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -1408,12 +1408,11 @@ void DAP::EventThread() {
             // CreateBreakpoint doesn't apply source mapping and certain
             // implementation ignore the source part of this event anyway.
             protocol::Breakpoint protocol_bp = bp.ToProtocolBreakpoint();
-            llvm::json::Value protocol_bp_value = toJSON(protocol_bp);
 
             // "source" is not needed here, unless we add adapter data to be
             // saved by the client.
             if (protocol_bp.source && !protocol_bp.source->adapterData)
-              protocol_bp_value.getAsObject()->erase("source");
+              protocol_bp.source = std::nullopt;
 
             llvm::json::Object body;
             body.try_emplace("breakpoint", protocol_bp);

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

Reply via email to