https://github.com/charles-zablit updated 
https://github.com/llvm/llvm-project/pull/208233

>From d6abb3698fd1419ec5c89df61a9243cf6fcc0772 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Wed, 8 Jul 2026 15:46:39 +0100
Subject: [PATCH 1/6] [lldb][Windows] ignore loader breakpoints in system
 modules

---
 .../Windows/Common/NativeProcessWindows.cpp   | 55 ++++-----------
 .../Windows/Common/ProcessDebugger.cpp        | 69 +++++++++++++++++++
 .../Process/Windows/Common/ProcessDebugger.h  |  5 ++
 .../Process/Windows/Common/ProcessWindows.cpp | 16 ++++-
 4 files changed, 101 insertions(+), 44 deletions(-)

diff --git 
a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index ada92894efc47..f1de697c34b67 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -50,44 +50,6 @@ using namespace llvm;
 
 namespace lldb_private {
 
-namespace {
-
-void NormalizeWindowsPath(std::string &s) {
-  for (char &c : s) {
-    if (c == '/')
-      c = '\\';
-    else
-      c = std::tolower(static_cast<unsigned char>(c));
-  }
-}
-
-bool IsSystemDLL(const FileSpec &spec) {
-  if (!spec)
-    return false;
-
-  static const std::string windows_prefix = []() {
-    std::string prefix;
-    wchar_t buf[MAX_PATH];
-    UINT len = ::GetWindowsDirectoryW(buf, MAX_PATH);
-    if (len == 0 || len >= MAX_PATH)
-      return prefix;
-    llvm::convertWideToUTF8(std::wstring_view(buf, len), prefix);
-    NormalizeWindowsPath(prefix);
-    if (!prefix.empty() && prefix.back() != '\\')
-      prefix += '\\';
-    return prefix;
-  }();
-
-  if (windows_prefix.empty())
-    return false;
-
-  std::string path = spec.GetPath();
-  NormalizeWindowsPath(path);
-  return llvm::StringRef(path).starts_with(windows_prefix);
-}
-
-} // namespace
-
 NativeProcessWindows::NativeProcessWindows(ProcessLaunchInfo &launch_info,
                                            NativeDelegate &delegate,
                                            llvm::Error &E)
@@ -635,9 +597,8 @@ NativeProcessWindows::HandleBreakpointException(const 
ExceptionRecord &record) {
     return ExceptionResult::BreakInDebugger;
   }
 
-  // Any remaining STATUS_BREAKPOINT is a breakpoint instruction in the
-  // program's own code (e.g. `__debugbreak()` or `__builtin_debugtrap()`).
-  // Stop the debugger and let the user decide what to do.
+  // Our own DebugBreakProcess() injection, used to implement
+  // Halt()/Interrupt().
   if (m_pending_halt) {
     LLDB_LOG(log,
              "DebugBreakProcess injection treated as Halt SIGSTOP for tid "
@@ -664,6 +625,14 @@ NativeProcessWindows::HandleBreakpointException(const 
ExceptionRecord &record) {
     return ExceptionResult::BreakInDebugger;
   }
 
+  if (IsSystemModuleAddress(exception_addr)) {
+    LLDB_LOG(log,
+             "Ignoring loader/OS breakpoint at address {0:x} in a system "
+             "module.",
+             exception_addr);
+    return ExceptionResult::MaskException;
+  }
+
   std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
                              record.GetExceptionValue(), exception_addr)
                          .str();
@@ -776,7 +745,7 @@ DllEventAction NativeProcessWindows::OnLoadDll(const 
ModuleSpec &module_spec,
     return DllEventAction::ContinueDebugLoop;
 
   // Can't resolve a breakpoint in a system DLL.
-  if (!resolved || IsSystemDLL(resolved))
+  if (!resolved || ProcessDebugger::IsSystemDLL(resolved))
     return DllEventAction::ContinueDebugLoop;
 
   NativeThreadWindows *loader_thread = GetThreadByID(thread_id);
@@ -819,7 +788,7 @@ DllEventAction 
NativeProcessWindows::OnUnloadDll(lldb::addr_t module_addr,
   if (!m_initial_stop_seen || !m_client_supports_libraries_read)
     return DllEventAction::ContinueDebugLoop;
 
-  if (!unloaded_spec || IsSystemDLL(unloaded_spec))
+  if (!unloaded_spec || ProcessDebugger::IsSystemDLL(unloaded_spec))
     return DllEventAction::ContinueDebugLoop;
 
   NativeThreadWindows *unloader_thread = GetThreadByID(thread_id);
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
index 63fc20f36b07b..a4322c3d3f536 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
@@ -19,6 +19,7 @@
 #include "lldb/Host/ProcessLaunchInfo.h"
 #include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Utility/FileSpec.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/Error.h"
 
@@ -26,9 +27,77 @@
 #include "ExceptionRecord.h"
 #include "ProcessWindowsLog.h"
 
+#include <cctype>
+#include <string>
+#include <string_view>
+
 using namespace lldb;
 using namespace lldb_private;
 
+static void NormalizeWindowsPath(std::string &s) {
+  for (char &c : s) {
+    if (c == '/')
+      c = '\\';
+    else
+      c = std::tolower(static_cast<unsigned char>(c));
+  }
+}
+
+bool ProcessDebugger::IsSystemDLL(const FileSpec &spec) {
+  if (!spec)
+    return false;
+
+  static const std::string windows_prefix = []() {
+    std::string prefix;
+    wchar_t buf[MAX_PATH];
+    UINT len = ::GetWindowsDirectoryW(buf, MAX_PATH);
+    if (len == 0 || len >= MAX_PATH)
+      return prefix;
+    llvm::convertWideToUTF8(std::wstring_view(buf, len), prefix);
+    NormalizeWindowsPath(prefix);
+    if (!prefix.empty() && prefix.back() != '\\')
+      prefix += '\\';
+    return prefix;
+  }();
+
+  if (windows_prefix.empty())
+    return false;
+
+  std::string path = spec.GetPath();
+  NormalizeWindowsPath(path);
+  return llvm::StringRef(path).starts_with(windows_prefix);
+}
+
+bool ProcessDebugger::IsSystemModuleAddress(lldb::addr_t addr) {
+  if (!m_session_data || !m_session_data->m_debugger)
+    return false;
+  lldb::process_t handle = m_session_data->m_debugger->GetProcess()
+                               .GetNativeProcess()
+                               .GetSystemHandle();
+  if (handle == nullptr || handle == LLDB_INVALID_PROCESS)
+    return false;
+
+  MEMORY_BASIC_INFORMATION mbi = {};
+  if (::VirtualQueryEx(handle, reinterpret_cast<LPCVOID>(addr), &mbi,
+                       sizeof(mbi)) != sizeof(mbi))
+    return false;
+  if (mbi.AllocationBase == nullptr)
+    return false;
+
+  // A truncated path still carries the leading directory, which is all
+  // IsSystemDLL() inspects. MAX_PATH is enough.
+  wchar_t module_path[MAX_PATH];
+  DWORD len = ::GetModuleFileNameExW(
+      handle, reinterpret_cast<HMODULE>(mbi.AllocationBase), module_path,
+      MAX_PATH);
+  if (len == 0)
+    return false;
+
+  std::string path_utf8;
+  llvm::convertWideToUTF8(std::wstring_view(module_path, len), path_utf8);
+  return IsSystemDLL(FileSpec(path_utf8));
+}
+
 static DWORD ConvertLldbToWinApiProtect(uint32_t protect) {
   // We also can process a read / write permissions here, but if the debugger
   // will make later a write into the allocated memory, it will fail. To get
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.h 
b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.h
index 77b7dfff14268..b06f022d0fe80 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.h
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.h
@@ -29,6 +29,7 @@ class HostProcess;
 class HostThread;
 class ProcessLaunchInfo;
 class ProcessAttachInfo;
+class FileSpec;
 
 class ProcessWindowsData {
 public:
@@ -68,6 +69,10 @@ class ProcessDebugger {
                              uint16_t length_lower_word);
   virtual void OnDebuggerError(const Status &error, uint32_t type);
 
+  static bool IsSystemDLL(const FileSpec &spec);
+
+  bool IsSystemModuleAddress(lldb::addr_t addr);
+
 protected:
   Status DetachProcess();
 
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 18631a1545bdc..b5793bf283c80 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -15,6 +15,7 @@
 #include <psapi.h>
 
 #include "lldb/Breakpoint/Watchpoint.h"
+#include "lldb/Core/Address.h"
 #include "lldb/Core/IOHandler.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
@@ -97,6 +98,7 @@ ProcessSP ProcessWindows::CreateInstance(lldb::TargetSP 
target_sp,
 }
 
 static bool ShouldUseLLDBServer() {
+  return true;
   llvm::StringRef use_lldb_server = ::getenv("LLDB_USE_LLDB_SERVER");
   return use_lldb_server.equals_insensitive("on") ||
          use_lldb_server.equals_insensitive("yes") ||
@@ -710,7 +712,18 @@ ProcessWindows::OnDebugException(bool first_chance,
 
   ExceptionResult result = ExceptionResult::SendToApplication;
   switch (record.GetExceptionValue()) {
-  case EXCEPTION_BREAKPOINT:
+  case EXCEPTION_BREAKPOINT: {
+    const lldb::addr_t bp_addr = record.GetExceptionAddress();
+    if (first_chance && m_session_data->m_initial_stop_received &&
+        !GetBreakpointSiteList().FindByAddress(bp_addr) &&
+        IsSystemModuleAddress(bp_addr)) {
+      LLDB_LOG(
+          log,
+          "Ignoring loader/OS breakpoint at address {0:x} in a system module.",
+          bp_addr);
+      return ExceptionResult::MaskException;
+    }
+
     // Handle breakpoints at the first chance.
     result = ExceptionResult::BreakInDebugger;
 
@@ -733,6 +746,7 @@ ProcessWindows::OnDebugException(bool first_chance,
     DrainProcessStdout();
     SetPrivateState(eStateStopped);
     break;
+  }
   case EXCEPTION_SINGLE_STEP:
     result = ExceptionResult::BreakInDebugger;
     DrainProcessStdout();

>From d5b9ef7d44aedd557b98fae0d1e223bdf76a6f87 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Wed, 8 Jul 2026 15:48:41 +0100
Subject: [PATCH 2/6] reenable test

---
 .../API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py    | 1 -
 1 file changed, 1 deletion(-)

diff --git 
a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py 
b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
index 429051c9cf9f9..4e09efadfdcdc 100644
--- a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
+++ b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
@@ -66,7 +66,6 @@ def read_pipe_message(pipe):
 
 
 @skipIfBuildType(["debug"])
-@skipIfWindows  # https://github.com/llvm/llvm-project/issues/198763
 class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
     SHARED_BUILD_TESTCASE = False
 

>From 3e765d9e58b8d885a1908035af4c77b72a15ea46 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Wed, 8 Jul 2026 15:54:12 +0100
Subject: [PATCH 3/6] fixup! [lldb][Windows] ignore loader breakpoints in
 system modules

---
 lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index b5793bf283c80..0cefd324ce93b 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -98,7 +98,6 @@ ProcessSP ProcessWindows::CreateInstance(lldb::TargetSP 
target_sp,
 }
 
 static bool ShouldUseLLDBServer() {
-  return true;
   llvm::StringRef use_lldb_server = ::getenv("LLDB_USE_LLDB_SERVER");
   return use_lldb_server.equals_insensitive("on") ||
          use_lldb_server.equals_insensitive("yes") ||

>From d14fb315cd0be905f806fefd145caa938fc45908 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Wed, 8 Jul 2026 16:40:02 +0100
Subject: [PATCH 4/6] fixup! [lldb][Windows] ignore loader breakpoints in
 system modules

---
 .../Process/Windows/Common/ProcessWindows.cpp    | 16 +++++++++++-----
 .../Process/Windows/Common/ProcessWindows.h      |  1 +
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 0cefd324ce93b..ec2572c9af7ff 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -294,8 +294,12 @@ Status ProcessWindows::DoDestroy() {
 
 Status ProcessWindows::DoHalt(bool &caused_stop) {
   StateType state = GetPrivateState();
-  if (state != eStateStopped)
-    return HaltProcess(caused_stop);
+  if (state != eStateStopped) {
+    m_pending_halt = true;
+    Status error = HaltProcess(caused_stop);
+    if (error.Fail() || !caused_stop)
+      m_pending_halt = false;
+  }
   caused_stop = false;
   return Status();
 }
@@ -713,9 +717,11 @@ ProcessWindows::OnDebugException(bool first_chance,
   switch (record.GetExceptionValue()) {
   case EXCEPTION_BREAKPOINT: {
     const lldb::addr_t bp_addr = record.GetExceptionAddress();
-    if (first_chance && m_session_data->m_initial_stop_received &&
-        !GetBreakpointSiteList().FindByAddress(bp_addr) &&
-        IsSystemModuleAddress(bp_addr)) {
+    if (m_pending_halt) {
+      m_pending_halt = false;
+    } else if (first_chance && m_session_data->m_initial_stop_received &&
+               !GetBreakpointSiteList().FindByAddress(bp_addr) &&
+               IsSystemModuleAddress(bp_addr)) {
       LLDB_LOG(
           log,
           "Ignoring loader/OS breakpoint at address {0:x} in a system module.",
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
index 71db5e57f83b1..ba6d862b61ee5 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -133,6 +133,7 @@ class ProcessWindows : public Process, public 
ProcessDebugger {
   std::map<lldb::break_id_t, WatchpointInfo> m_watchpoints;
   std::vector<lldb::break_id_t> m_watchpoint_ids;
   std::shared_ptr<PTY> m_pty;
+  bool m_pending_halt = false;
 };
 } // namespace lldb_private
 

>From 8cea0eff8c7a88d51c0c9a36eb757301e305c470 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Thu, 9 Jul 2026 15:01:35 +0100
Subject: [PATCH 5/6] only catch the first loader int3

---
 .../Windows/Common/NativeProcessWindows.cpp   | 17 +++++++++-----
 .../Windows/Common/NativeProcessWindows.h     |  2 ++
 .../Process/Windows/Common/ProcessWindows.cpp | 22 ++++++++++++-------
 .../Process/Windows/Common/ProcessWindows.h   |  1 +
 4 files changed, 28 insertions(+), 14 deletions(-)

diff --git 
a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index f1de697c34b67..2ac0434f5c1d1 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -84,6 +84,8 @@ NativeProcessWindows::NativeProcessWindows(lldb::pid_t pid, 
int terminal_fd,
   if (E)
     return;
 
+  m_expecting_loader_int3 = true;
+
   SetID(GetDebuggedProcessId());
 
   ProcessInstanceInfo info;
@@ -625,12 +627,15 @@ NativeProcessWindows::HandleBreakpointException(const 
ExceptionRecord &record) {
     return ExceptionResult::BreakInDebugger;
   }
 
-  if (IsSystemModuleAddress(exception_addr)) {
-    LLDB_LOG(log,
-             "Ignoring loader/OS breakpoint at address {0:x} in a system "
-             "module.",
-             exception_addr);
-    return ExceptionResult::MaskException;
+  if (m_expecting_loader_int3) {
+    m_expecting_loader_int3 = false;
+    if (IsSystemModuleAddress(exception_addr)) {
+      LLDB_LOG(log,
+               "Skipping expected loader breakpoint at address {0:x} in a "
+               "system module.",
+               exception_addr);
+      return ExceptionResult::MaskException;
+    }
   }
 
   std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.h 
b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.h
index fcf5d8f3c4753..17469f18fbc73 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.h
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.h
@@ -182,6 +182,8 @@ class NativeProcessWindows : public NativeProcessProtocol,
   /// launch / attach.
   bool m_initial_stop_seen = false;
 
+  bool m_expecting_loader_int3 = false;
+
   /// Set when Halt() / Interrupt() schedules a DebugBreakProcess injection.
   bool m_pending_halt = false;
 
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index ec2572c9af7ff..d3afb87506d6e 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -228,6 +228,9 @@ ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid,
   Status error = AttachProcess(pid, attach_info, delegate);
   if (error.Success())
     SetID(GetDebuggedProcessId());
+
+  m_expecting_loader_int3 = true;
+
   return error;
 }
 
@@ -719,14 +722,17 @@ ProcessWindows::OnDebugException(bool first_chance,
     const lldb::addr_t bp_addr = record.GetExceptionAddress();
     if (m_pending_halt) {
       m_pending_halt = false;
-    } else if (first_chance && m_session_data->m_initial_stop_received &&
-               !GetBreakpointSiteList().FindByAddress(bp_addr) &&
-               IsSystemModuleAddress(bp_addr)) {
-      LLDB_LOG(
-          log,
-          "Ignoring loader/OS breakpoint at address {0:x} in a system module.",
-          bp_addr);
-      return ExceptionResult::MaskException;
+    } else if (m_expecting_loader_int3 && first_chance &&
+               m_session_data->m_initial_stop_received &&
+               !GetBreakpointSiteList().FindByAddress(bp_addr)) {
+      m_expecting_loader_int3 = false;
+      if (IsSystemModuleAddress(bp_addr)) {
+        LLDB_LOG(log,
+                 "Skipping expected loader breakpoint at address {0:x} in a "
+                 "system module.",
+                 bp_addr);
+        return ExceptionResult::MaskException;
+      }
     }
 
     // Handle breakpoints at the first chance.
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
index ba6d862b61ee5..2d2f3ca59ac70 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -134,6 +134,7 @@ class ProcessWindows : public Process, public 
ProcessDebugger {
   std::vector<lldb::break_id_t> m_watchpoint_ids;
   std::shared_ptr<PTY> m_pty;
   bool m_pending_halt = false;
+  bool m_expecting_loader_int3 = false;
 };
 } // namespace lldb_private
 

>From 615fc3ba92772d465cf64111fac56649c9a9c364 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Mon, 20 Jul 2026 11:19:35 +0100
Subject: [PATCH 6/6] address comments

---
 .../Windows/Common/NativeProcessWindows.cpp   | 18 +++++++--------
 .../Windows/Common/ProcessDebugger.cpp        | 22 ++++++++-----------
 .../Process/Windows/Common/ProcessDebugger.h  |  4 ++--
 .../Process/Windows/Common/ProcessWindows.cpp | 15 ++++++-------
 4 files changed, 26 insertions(+), 33 deletions(-)

diff --git 
a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index 2ac0434f5c1d1..f87fd23f5a047 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -627,15 +627,13 @@ NativeProcessWindows::HandleBreakpointException(const 
ExceptionRecord &record) {
     return ExceptionResult::BreakInDebugger;
   }
 
-  if (m_expecting_loader_int3) {
+  if (m_expecting_loader_int3 && IsSystemModuleAddress(exception_addr)) {
     m_expecting_loader_int3 = false;
-    if (IsSystemModuleAddress(exception_addr)) {
-      LLDB_LOG(log,
-               "Skipping expected loader breakpoint at address {0:x} in a "
-               "system module.",
-               exception_addr);
-      return ExceptionResult::MaskException;
-    }
+    LLDB_LOG(log,
+             "Skipping expected loader breakpoint at address {0:x} in a "
+             "system module.",
+             exception_addr);
+    return ExceptionResult::MaskException;
   }
 
   std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
@@ -750,7 +748,7 @@ DllEventAction NativeProcessWindows::OnLoadDll(const 
ModuleSpec &module_spec,
     return DllEventAction::ContinueDebugLoop;
 
   // Can't resolve a breakpoint in a system DLL.
-  if (!resolved || ProcessDebugger::IsSystemDLL(resolved))
+  if (!resolved || ProcessDebugger::IsSystemDLL(resolved.GetPath()))
     return DllEventAction::ContinueDebugLoop;
 
   NativeThreadWindows *loader_thread = GetThreadByID(thread_id);
@@ -793,7 +791,7 @@ DllEventAction 
NativeProcessWindows::OnUnloadDll(lldb::addr_t module_addr,
   if (!m_initial_stop_seen || !m_client_supports_libraries_read)
     return DllEventAction::ContinueDebugLoop;
 
-  if (!unloaded_spec || ProcessDebugger::IsSystemDLL(unloaded_spec))
+  if (!unloaded_spec || ProcessDebugger::IsSystemDLL(unloaded_spec.GetPath()))
     return DllEventAction::ContinueDebugLoop;
 
   NativeThreadWindows *unloader_thread = GetThreadByID(thread_id);
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
index a4322c3d3f536..6594336fde655 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
@@ -27,24 +27,20 @@
 #include "ExceptionRecord.h"
 #include "ProcessWindowsLog.h"
 
-#include <cctype>
 #include <string>
 #include <string_view>
 
 using namespace lldb;
 using namespace lldb_private;
 
-static void NormalizeWindowsPath(std::string &s) {
-  for (char &c : s) {
+static void NormalizeWindowsPathSeparators(std::string &s) {
+  for (char &c : s)
     if (c == '/')
       c = '\\';
-    else
-      c = std::tolower(static_cast<unsigned char>(c));
-  }
 }
 
-bool ProcessDebugger::IsSystemDLL(const FileSpec &spec) {
-  if (!spec)
+bool ProcessDebugger::IsSystemDLL(llvm::StringRef path) {
+  if (path.empty())
     return false;
 
   static const std::string windows_prefix = []() {
@@ -54,7 +50,7 @@ bool ProcessDebugger::IsSystemDLL(const FileSpec &spec) {
     if (len == 0 || len >= MAX_PATH)
       return prefix;
     llvm::convertWideToUTF8(std::wstring_view(buf, len), prefix);
-    NormalizeWindowsPath(prefix);
+    NormalizeWindowsPathSeparators(prefix);
     if (!prefix.empty() && prefix.back() != '\\')
       prefix += '\\';
     return prefix;
@@ -63,9 +59,9 @@ bool ProcessDebugger::IsSystemDLL(const FileSpec &spec) {
   if (windows_prefix.empty())
     return false;
 
-  std::string path = spec.GetPath();
-  NormalizeWindowsPath(path);
-  return llvm::StringRef(path).starts_with(windows_prefix);
+  std::string normalized = path.str();
+  NormalizeWindowsPathSeparators(normalized);
+  return llvm::StringRef(normalized).starts_with_insensitive(windows_prefix);
 }
 
 bool ProcessDebugger::IsSystemModuleAddress(lldb::addr_t addr) {
@@ -95,7 +91,7 @@ bool ProcessDebugger::IsSystemModuleAddress(lldb::addr_t 
addr) {
 
   std::string path_utf8;
   llvm::convertWideToUTF8(std::wstring_view(module_path, len), path_utf8);
-  return IsSystemDLL(FileSpec(path_utf8));
+  return IsSystemDLL(path_utf8);
 }
 
 static DWORD ConvertLldbToWinApiProtect(uint32_t protect) {
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.h 
b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.h
index b06f022d0fe80..99b59b1918a4f 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.h
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.h
@@ -15,6 +15,7 @@
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-types.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorExtras.h"
 #include "llvm/Support/Mutex.h"
@@ -29,7 +30,6 @@ class HostProcess;
 class HostThread;
 class ProcessLaunchInfo;
 class ProcessAttachInfo;
-class FileSpec;
 
 class ProcessWindowsData {
 public:
@@ -69,7 +69,7 @@ class ProcessDebugger {
                              uint16_t length_lower_word);
   virtual void OnDebuggerError(const Status &error, uint32_t type);
 
-  static bool IsSystemDLL(const FileSpec &spec);
+  static bool IsSystemDLL(llvm::StringRef path);
 
   bool IsSystemModuleAddress(lldb::addr_t addr);
 
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index d3afb87506d6e..dfbcaf9bc9c1f 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -724,15 +724,14 @@ ProcessWindows::OnDebugException(bool first_chance,
       m_pending_halt = false;
     } else if (m_expecting_loader_int3 && first_chance &&
                m_session_data->m_initial_stop_received &&
-               !GetBreakpointSiteList().FindByAddress(bp_addr)) {
+               !GetBreakpointSiteList().FindByAddress(bp_addr) &&
+               IsSystemModuleAddress(bp_addr)) {
       m_expecting_loader_int3 = false;
-      if (IsSystemModuleAddress(bp_addr)) {
-        LLDB_LOG(log,
-                 "Skipping expected loader breakpoint at address {0:x} in a "
-                 "system module.",
-                 bp_addr);
-        return ExceptionResult::MaskException;
-      }
+      LLDB_LOG(log,
+               "Skipping expected loader breakpoint at address {0:x} in a "
+               "system module.",
+               bp_addr);
+      return ExceptionResult::MaskException;
     }
 
     // Handle breakpoints at the first chance.

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to