[Lldb-commits] [lldb] [LLDB] Show exit code on Windows if process can't launch (PR #141290)
via lldb-commits
lldb-commits at lists.llvm.org
Fri May 23 13:04:40 PDT 2025
https://github.com/Nerixyz created https://github.com/llvm/llvm-project/pull/141290
When running a process that would exit before LLDB could stop the target, it would try to interpret (and subsequently format) the exit code as a Win32 error. However, processes on Windows won't return Win32 errors in that case. They will often return an [NTSTATUS](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55). One common case for this to occur is when a DLL is missing. In that case, the process will start successfully, but it will exit with `STATUS_DLL_NOT_FOUND`.
LLDB would previously return "unknown error", because it tried to [`FormatMessage`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage) `0xC0000135` which doesn't work, so it fell back to "unknown error".
This PR changes the error to be the string "Process prematurely exited with {0:x}" and doesn't try to format the exit code. One could `FormatMessage` an `NTSTATUS` by passing `FORMAT_MESSAGE_FROM_HMODULE` and a handle to `ntdll.dll`, however, I don't think we can get the required format arguments (e.g. the missing DLL name - `%hs`).
>From 31aab0ad4b134925b702fa24fedf48880c108f06 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Fri, 23 May 2025 21:47:40 +0200
Subject: [PATCH] [LLDB] Show exit code on Windows if process can't launch
---
.../Windows/Common/ProcessDebugger.cpp | 3 ++-
.../API/windows/launch/missing-dll/Makefile | 5 +++++
.../launch/missing-dll/TestMissingDll.py | 22 +++++++++++++++++++
.../windows/launch/missing-dll/dummy_dll.c | 1 +
.../API/windows/launch/missing-dll/main.c | 6 +++++
5 files changed, 36 insertions(+), 1 deletion(-)
create mode 100644 lldb/test/API/windows/launch/missing-dll/Makefile
create mode 100644 lldb/test/API/windows/launch/missing-dll/TestMissingDll.py
create mode 100644 lldb/test/API/windows/launch/missing-dll/dummy_dll.c
create mode 100644 lldb/test/API/windows/launch/missing-dll/main.c
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
index bde72d61b0fee..a0f622fd69902 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
@@ -483,7 +483,8 @@ void ProcessDebugger::OnExitProcess(uint32_t exit_code) {
// of the error otherwise WaitForDebuggerConnection() will be blocked.
// An example of this issue is when a process fails to load a dependent DLL.
if (m_session_data && !m_session_data->m_initial_stop_received) {
- Status error(exit_code, eErrorTypeWin32);
+ Status error = Status::FromErrorStringWithFormatv(
+ "Process prematurely exited with {0:x}", exit_code);
OnDebuggerError(error, 0);
}
}
diff --git a/lldb/test/API/windows/launch/missing-dll/Makefile b/lldb/test/API/windows/launch/missing-dll/Makefile
new file mode 100644
index 0000000000000..43e02d1d8f22b
--- /dev/null
+++ b/lldb/test/API/windows/launch/missing-dll/Makefile
@@ -0,0 +1,5 @@
+C_SOURCES := main.c
+DYLIB_C_SOURCES := dummy_dll.c
+DYLIB_NAME := dummy_dll
+
+include Makefile.rules
diff --git a/lldb/test/API/windows/launch/missing-dll/TestMissingDll.py b/lldb/test/API/windows/launch/missing-dll/TestMissingDll.py
new file mode 100644
index 0000000000000..b47040fbf794b
--- /dev/null
+++ b/lldb/test/API/windows/launch/missing-dll/TestMissingDll.py
@@ -0,0 +1,22 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class MissingDllTestCase(TestBase):
+ @skipUnlessWindows
+ def test(self):
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+ dll = self.getBuildArtifact("dummy_dll.dll")
+ self.assertTrue(remove_file(dll))
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ launch_info = lldb.SBLaunchInfo(None)
+ launch_info.SetWorkingDirectory(self.get_process_working_directory())
+
+ error = lldb.SBError()
+ target.Launch(launch_info, error)
+ self.assertFailure(error, "Process prematurely exited with 0xc0000135")
diff --git a/lldb/test/API/windows/launch/missing-dll/dummy_dll.c b/lldb/test/API/windows/launch/missing-dll/dummy_dll.c
new file mode 100644
index 0000000000000..61bde26534966
--- /dev/null
+++ b/lldb/test/API/windows/launch/missing-dll/dummy_dll.c
@@ -0,0 +1 @@
+__declspec(dllexport) void SomeFunction(void) {}
diff --git a/lldb/test/API/windows/launch/missing-dll/main.c b/lldb/test/API/windows/launch/missing-dll/main.c
new file mode 100644
index 0000000000000..c1e0d3222c48b
--- /dev/null
+++ b/lldb/test/API/windows/launch/missing-dll/main.c
@@ -0,0 +1,6 @@
+__declspec(dllimport) void SomeFunction(void);
+
+int main(void) {
+ SomeFunction();
+ return 0;
+}
More information about the lldb-commits
mailing list