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`).
28 lines
909 B
Python
28 lines
909 B
Python
import lldb
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
|
|
|
|
class MissingDllTestCase(TestBase):
|
|
@skipUnlessWindows
|
|
def test(self):
|
|
"""
|
|
Test that lldb reports the application's exit code (STATUS_DLL_NOT_FOUND),
|
|
rather than trying to treat it as a Win32 error number.
|
|
"""
|
|
|
|
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")
|