-
Notifications
You must be signed in to change notification settings - Fork 14k
[LLDB] Show exit code on Windows if process can't launch #141290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lldb Author: nerix (Nerixyz) ChangesWhen 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. 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 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 Full diff: https://github.com/llvm/llvm-project/pull/141290.diff 5 Files Affected:
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;
+}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
31aab0a
to
aacbcb4
Compare
I see the magic exit value listed in https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55. I wondered if we could say Not a big deal though, googling "windows exit code 0xC0000135" gets you pretty close to what it means. |
aacbcb4
to
339bae7
Compare
That's the part where I'm not sure either, but as you mentioned, googling for the exit code usually gets you to the right destination. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. This is a nice improvement thanks for working on it.
This PR is strictly better than before, so it's fine as it is. |
@Nerixyz Do you need someone to merge this on your behalf? |
Yes. |
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`).
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. 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
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
anNTSTATUS
by passingFORMAT_MESSAGE_FROM_HMODULE
and a handle tontdll.dll
, however, I don't think we can get the required format arguments (e.g. the missing DLL name -%hs
).