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
