[Lldb-commits] [lldb] 43bd07b - [lldb][Windows] Strip the extended-length prefix from host and process paths (#227373)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 30 03:58:42 PDT 2026
Author: Charles Zablit
Date: 2026-09-30T11:58:35+01:00
New Revision: 43bd07b665ec5496750fe12011af5f9d317b22ab
URL: https://github.com/llvm/llvm-project/commit/43bd07b665ec5496750fe12011af5f9d317b22ab
DIFF: https://github.com/llvm/llvm-project/commit/43bd07b665ec5496750fe12011af5f9d317b22ab.diff
LOG: [lldb][Windows] Strip the extended-length prefix from host and process paths (#227373)
This patch introduces a helper function to strip the extended-length
path prefix from windows paths.
Added:
lldb/include/lldb/Host/windows/PathUtils.h
lldb/unittests/Host/windows/PathUtilsTest.cpp
Modified:
lldb/source/Host/windows/FileSystem.cpp
lldb/source/Host/windows/Host.cpp
lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
lldb/unittests/Host/CMakeLists.txt
Removed:
################################################################################
diff --git a/lldb/include/lldb/Host/windows/PathUtils.h b/lldb/include/lldb/Host/windows/PathUtils.h
new file mode 100644
index 0000000000000..2678bd17f8bdb
--- /dev/null
+++ b/lldb/include/lldb/Host/windows/PathUtils.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_HOST_WINDOWS_PATHUTILS_H
+#define LLDB_HOST_WINDOWS_PATHUTILS_H
+
+#include "llvm/ADT/StringRef.h"
+
+#include <string>
+
+namespace lldb_private {
+
+/// Convert an extended-length path to a regular DOS path: "\\?\C:\a" becomes
+/// "C:\a" and "\\?\UNC\server\share" becomes "\\server\share". Other paths are
+/// returned unchanged.
+inline std::string StripExtendedLengthPrefix(llvm::StringRef path) {
+ if (path.consume_front("\\\\?\\UNC\\"))
+ return "\\\\" + path.str();
+ path.consume_front("\\\\?\\");
+ return path.str();
+}
+
+} // namespace lldb_private
+
+#endif // LLDB_HOST_WINDOWS_PATHUTILS_H
diff --git a/lldb/source/Host/windows/FileSystem.cpp b/lldb/source/Host/windows/FileSystem.cpp
index 26e2fdc2a7aa5..f070364151b3f 100644
--- a/lldb/source/Host/windows/FileSystem.cpp
+++ b/lldb/source/Host/windows/FileSystem.cpp
@@ -15,6 +15,7 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/windows/AutoHandle.h"
+#include "lldb/Host/windows/PathUtils.h"
#include "lldb/Host/windows/PosixApi.h"
#include "llvm/Support/ConvertUTF.h"
@@ -66,7 +67,7 @@ Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
std::vector<wchar_t> buf(PATH_MAX + 1);
// Subtract 1 from the path length since this function does not add a null
- // terminator.
+ // terminator. The result is an extended-length ("\\?\") path.
DWORD result = ::GetFinalPathNameByHandleW(
h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
std::string path;
@@ -75,7 +76,7 @@ Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
else if (!llvm::convertWideToUTF8(buf.data(), path))
error = Status::FromErrorString(PATH_CONVERSION_ERROR);
else
- dst.SetFile(path, FileSpec::Style::native);
+ dst.SetFile(StripExtendedLengthPrefix(path), FileSpec::Style::native);
::CloseHandle(h);
return error;
diff --git a/lldb/source/Host/windows/Host.cpp b/lldb/source/Host/windows/Host.cpp
index eb297df90b928..a9f6e65e38c10 100644
--- a/lldb/source/Host/windows/Host.cpp
+++ b/lldb/source/Host/windows/Host.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/windows/AutoHandle.h"
+#include "lldb/Host/windows/PathUtils.h"
#include "lldb/Host/windows/windows.h"
#include <cstdio>
@@ -77,7 +78,11 @@ static bool GetExecutableForProcess(const AutoHandle &handle,
DWORD dwSize = buffer.size();
if (!::QueryFullProcessImageNameW(handle.get(), 0, &buffer[0], &dwSize))
return false;
- return llvm::convertWideToUTF8(buffer.data(), path);
+ if (!llvm::convertWideToUTF8(buffer.data(), path))
+ return false;
+ // A process launched through an extended-length path has the "\\?\" prefix.
+ path = StripExtendedLengthPrefix(path);
+ return true;
}
static void GetProcessExecutableAndTriple(const AutoHandle &handle,
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
index 51d47751ed05d..346e9517f16c6 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
@@ -17,6 +17,7 @@
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/windows/PathUtils.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
@@ -59,7 +60,9 @@ bool ProcessDebugger::IsSystemDLL(llvm::StringRef path) {
if (windows_prefix.empty())
return false;
- std::string normalized = path.str();
+ // A module loaded through an extended-length path has the "\\?\" prefix,
+ // which would not match the Windows directory.
+ std::string normalized = StripExtendedLengthPrefix(path);
NormalizeWindowsPathSeparators(normalized);
return llvm::StringRef(normalized).starts_with_insensitive(windows_prefix);
}
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index d72856bdc8d2c..0490b4ba2573b 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -30,6 +30,7 @@
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/windows/ConnectionConPTYWindows.h"
#include "lldb/Host/windows/HostThreadWindows.h"
+#include "lldb/Host/windows/PathUtils.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/MemoryRegionInfo.h"
@@ -72,7 +73,8 @@ std::string GetProcessExecutableName(HANDLE process_handle) {
file_name.resize(copied);
std::string result;
llvm::convertWideToUTF8(file_name.data(), result);
- return result;
+ // A process launched through an extended-length path has the "\\?\" prefix.
+ return StripExtendedLengthPrefix(result);
}
std::string GetProcessExecutableName(DWORD pid) {
diff --git a/lldb/unittests/Host/CMakeLists.txt b/lldb/unittests/Host/CMakeLists.txt
index 6bbbd4461ff50..285f93de58c60 100644
--- a/lldb/unittests/Host/CMakeLists.txt
+++ b/lldb/unittests/Host/CMakeLists.txt
@@ -38,6 +38,7 @@ endif()
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
list(APPEND FILES
+ windows/PathUtilsTest.cpp
windows/StripConPTYSequencesTest.cpp
)
endif()
diff --git a/lldb/unittests/Host/windows/PathUtilsTest.cpp b/lldb/unittests/Host/windows/PathUtilsTest.cpp
new file mode 100644
index 0000000000000..0f11371dec904
--- /dev/null
+++ b/lldb/unittests/Host/windows/PathUtilsTest.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/windows/PathUtils.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+TEST(PathUtilsTest, StripExtendedLengthPrefixDrive) {
+ EXPECT_EQ("C:\\a\\b.exe", StripExtendedLengthPrefix("\\\\?\\C:\\a\\b.exe"));
+}
+
+TEST(PathUtilsTest, StripExtendedLengthPrefixUNC) {
+ EXPECT_EQ("\\\\server\\share\\a.dll",
+ StripExtendedLengthPrefix("\\\\?\\UNC\\server\\share\\a.dll"));
+}
+
+TEST(PathUtilsTest, StripExtendedLengthPrefixUnchanged) {
+ EXPECT_EQ("C:\\a\\b.exe", StripExtendedLengthPrefix("C:\\a\\b.exe"));
+ EXPECT_EQ("\\\\server\\share\\a.dll",
+ StripExtendedLengthPrefix("\\\\server\\share\\a.dll"));
+ EXPECT_EQ("", StripExtendedLengthPrefix(""));
+}
More information about the lldb-commits
mailing list