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 <nerix...@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;
+}

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

Reply via email to