mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Added patch to fix differences in exception handling behaviour between Wine and Windows.
This commit is contained in:
parent
8fbca5cb69
commit
6a81960f7a
3
debian/changelog
vendored
3
debian/changelog
vendored
@ -1,11 +1,12 @@
|
||||
wine-compholio (1.7.28) UNRELEASED; urgency=low
|
||||
* Added several patches for Unity3D Editor
|
||||
* Added missing recommendation for libtxc-dxtn-s2tc0 on Ubuntu.
|
||||
* Added patch to fix issues with over-the-spot input method.
|
||||
* Added patch to fix winemenubuilder desktop icon wine path (when using multiple wine versions).
|
||||
* Added patch to support FIND_FIRST_EX_CASE_SENSITIVE flag in FindFirstFileExW.
|
||||
* Added patch to send WM_PAINT event during dialog creation.
|
||||
* Added patch to fix issues when driver dispatch routine returns different status codes.
|
||||
* Added several patches for Unity3D Editor.
|
||||
* Added patch to fix differences between exception handling behaviour in Wine and Windows.
|
||||
-- Sebastian Lackner <sebastian@fds-team.de> Sun, 21 Sep 2014 01:44:14 +0200
|
||||
|
||||
wine-compholio (1.7.27) unstable; urgency=low
|
||||
|
@ -40,6 +40,7 @@ PATCHLIST := \
|
||||
loader-Cmdline_Diagnostics.ok \
|
||||
ntdll-DOS_Attributes.ok \
|
||||
ntdll-Dynamic_DST.ok \
|
||||
ntdll-Exception.ok \
|
||||
ntdll-FD_Cache.ok \
|
||||
ntdll-FileDispositionInformation.ok \
|
||||
ntdll-Fix_Alignment.ok \
|
||||
@ -550,6 +551,22 @@ ntdll-Dynamic_DST.ok:
|
||||
echo '+ { "ntdll-Dynamic_DST", "Sebastian Lackner", "Add Dynamic DST exceptions for Israel Standard Time." },'; \
|
||||
) > ntdll-Dynamic_DST.ok
|
||||
|
||||
# Patchset ntdll-Exception
|
||||
# |
|
||||
# | Included patches:
|
||||
# | * Fix some differences in exception handling behaviour between Wine and Windows. [by Sebastian Lackner]
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/debugger.c, dlls/ntdll/om.c, dlls/ntdll/tests/exception.c
|
||||
# |
|
||||
.INTERMEDIATE: ntdll-Exception.ok
|
||||
ntdll-Exception.ok:
|
||||
$(call APPLY_FILE,ntdll-Exception/0001-ntdll-Throw-exception-if-invalid-handle-is-passed-to.patch)
|
||||
$(call APPLY_FILE,ntdll-Exception/0002-ntdll-OutputDebugString-should-throw-the-exception-a.patch)
|
||||
@( \
|
||||
echo '+ { "ntdll-Exception", "Sebastian Lackner", "Fix some differences in exception handling behaviour between Wine and Windows." },'; \
|
||||
) > ntdll-Exception.ok
|
||||
|
||||
# Patchset ntdll-FD_Cache
|
||||
# |
|
||||
# | Included patches:
|
||||
|
@ -0,0 +1,184 @@
|
||||
From 05a69d408bc84fa489f297973e3a0ab384dad635 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 28 Sep 2014 22:42:46 +0200
|
||||
Subject: ntdll: Throw exception if invalid handle is passed to NtClose and
|
||||
debugger enabled.
|
||||
|
||||
---
|
||||
dlls/ntdll/om.c | 27 ++++++++++++++++++
|
||||
dlls/ntdll/tests/exception.c | 65 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 92 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
|
||||
index 47a2614..bcc6d69 100644
|
||||
--- a/dlls/ntdll/om.c
|
||||
+++ b/dlls/ntdll/om.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "winternl.h"
|
||||
#include "ntdll_misc.h"
|
||||
#include "wine/server.h"
|
||||
+#include "wine/exception.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
||||
|
||||
@@ -343,6 +344,13 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+
|
||||
+static LONG WINAPI invalid_handle_exception_handler( EXCEPTION_POINTERS *eptr )
|
||||
+{
|
||||
+ EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
|
||||
+ return (rec->ExceptionCode == EXCEPTION_INVALID_HANDLE) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
|
||||
+}
|
||||
+
|
||||
/* Everquest 2 / Pirates of the Burning Sea hooks NtClose, so we need a wrapper */
|
||||
NTSTATUS close_handle( HANDLE handle )
|
||||
{
|
||||
@@ -356,6 +364,25 @@ NTSTATUS close_handle( HANDLE handle )
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (fd != -1) close( fd );
|
||||
+
|
||||
+ if (ret == STATUS_INVALID_HANDLE && NtCurrentTeb()->Peb->BeingDebugged)
|
||||
+ {
|
||||
+ __TRY
|
||||
+ {
|
||||
+ EXCEPTION_RECORD record;
|
||||
+ record.ExceptionCode = EXCEPTION_INVALID_HANDLE;
|
||||
+ record.ExceptionFlags = 0;
|
||||
+ record.ExceptionRecord = NULL;
|
||||
+ record.ExceptionAddress = NULL;
|
||||
+ record.NumberParameters = 0;
|
||||
+ RtlRaiseException( &record );
|
||||
+ }
|
||||
+ __EXCEPT(invalid_handle_exception_handler)
|
||||
+ {
|
||||
+ }
|
||||
+ __ENDTRY
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
|
||||
index 2074f0a..bc36242 100644
|
||||
--- a/dlls/ntdll/tests/exception.c
|
||||
+++ b/dlls/ntdll/tests/exception.c
|
||||
@@ -51,6 +51,7 @@ static NTSTATUS (WINAPI *pNtTerminateProcess)(HANDLE handle, LONG exit_code);
|
||||
static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
|
||||
static NTSTATUS (WINAPI *pNtSetInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG);
|
||||
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
|
||||
+static NTSTATUS (WINAPI *pNtClose)(HANDLE);
|
||||
|
||||
#if defined(__x86_64__)
|
||||
static BOOLEAN (CDECL *pRtlAddFunctionTable)(RUNTIME_FUNCTION*, DWORD, DWORD64);
|
||||
@@ -936,6 +937,16 @@ static void test_debugger(void)
|
||||
/* here we handle exception */
|
||||
}
|
||||
}
|
||||
+ else if (stage == 7 || stage == 8)
|
||||
+ {
|
||||
+ ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_INVALID_HANDLE,
|
||||
+ "unexpected exception code %08x, expected %08x\n", de.u.Exception.ExceptionRecord.ExceptionCode,
|
||||
+ EXCEPTION_INVALID_HANDLE);
|
||||
+ ok(de.u.Exception.ExceptionRecord.NumberParameters == 0,
|
||||
+ "unexpected number of parameters %d, expected 0\n", de.u.Exception.ExceptionRecord.NumberParameters);
|
||||
+
|
||||
+ if (stage == 8) continuestatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
+ }
|
||||
else
|
||||
ok(FALSE, "unexpected stage %x\n", stage);
|
||||
|
||||
@@ -1788,6 +1799,53 @@ static void test_ripevent(DWORD numexc)
|
||||
pRtlRemoveVectoredExceptionHandler(vectored_handler);
|
||||
}
|
||||
|
||||
+static DWORD invalid_handle_exceptions;
|
||||
+
|
||||
+static LONG CALLBACK invalid_handle_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||
+{
|
||||
+ PEXCEPTION_RECORD rec = ExceptionInfo->ExceptionRecord;
|
||||
+ trace("vect. handler %08x addr:%p\n", rec->ExceptionCode, rec->ExceptionAddress);
|
||||
+
|
||||
+ ok(rec->ExceptionCode == EXCEPTION_INVALID_HANDLE, "ExceptionCode is %08x instead of %08x\n",
|
||||
+ rec->ExceptionCode, EXCEPTION_INVALID_HANDLE);
|
||||
+ ok(rec->NumberParameters == 0, "ExceptionParameters is %d instead of 0\n", rec->NumberParameters);
|
||||
+
|
||||
+ invalid_handle_exceptions++;
|
||||
+ return (rec->ExceptionCode == EXCEPTION_INVALID_HANDLE) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
|
||||
+}
|
||||
+
|
||||
+static void test_closehandle(DWORD numexc)
|
||||
+{
|
||||
+ PVOID vectored_handler;
|
||||
+ NTSTATUS status;
|
||||
+ DWORD res;
|
||||
+
|
||||
+ if (!pRtlAddVectoredExceptionHandler || !pRtlRemoveVectoredExceptionHandler || !pRtlRaiseException)
|
||||
+ {
|
||||
+ skip("RtlAddVectoredExceptionHandler or RtlRemoveVectoredExceptionHandler or RtlRaiseException not found\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ vectored_handler = pRtlAddVectoredExceptionHandler(TRUE, &invalid_handle_vectored_handler);
|
||||
+ ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n");
|
||||
+
|
||||
+ invalid_handle_exceptions = 0;
|
||||
+ res = CloseHandle((HANDLE)0xdeadbeef);
|
||||
+ ok(!res, "CloseHandle(0xdeadbeef) unexpectedly succeeded\n");
|
||||
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error code %d instead of %d",
|
||||
+ GetLastError(), ERROR_INVALID_HANDLE);
|
||||
+ ok(invalid_handle_exceptions == numexc, "CloseHandle generated %d exceptions, expected %d\n",
|
||||
+ invalid_handle_exceptions, numexc);
|
||||
+
|
||||
+ invalid_handle_exceptions = 0;
|
||||
+ status = pNtClose((HANDLE)0xdeadbeef);
|
||||
+ ok(status == STATUS_INVALID_HANDLE, "NtClose(0xdeadbeef) returned status %08x\n", status);
|
||||
+ ok(invalid_handle_exceptions == numexc, "NtClose generated %d exceptions, expected %d\n",
|
||||
+ invalid_handle_exceptions, numexc);
|
||||
+
|
||||
+ pRtlRemoveVectoredExceptionHandler(vectored_handler);
|
||||
+}
|
||||
+
|
||||
START_TEST(exception)
|
||||
{
|
||||
HMODULE hntdll = GetModuleHandleA("ntdll.dll");
|
||||
@@ -1802,6 +1860,7 @@ START_TEST(exception)
|
||||
pNtGetContextThread = (void *)GetProcAddress( hntdll, "NtGetContextThread" );
|
||||
pNtSetContextThread = (void *)GetProcAddress( hntdll, "NtSetContextThread" );
|
||||
pNtReadVirtualMemory = (void *)GetProcAddress( hntdll, "NtReadVirtualMemory" );
|
||||
+ pNtClose = (void *)GetProcAddress( hntdll, "NtClose" );
|
||||
pRtlUnwind = (void *)GetProcAddress( hntdll, "RtlUnwind" );
|
||||
pRtlRaiseException = (void *)GetProcAddress( hntdll, "RtlRaiseException" );
|
||||
pNtTerminateProcess = (void *)GetProcAddress( hntdll, "NtTerminateProcess" );
|
||||
@@ -1865,6 +1924,10 @@ START_TEST(exception)
|
||||
test_ripevent(0);
|
||||
test_stage = 6;
|
||||
test_ripevent(1);
|
||||
+ test_stage = 7;
|
||||
+ test_closehandle(0);
|
||||
+ test_stage = 8;
|
||||
+ test_closehandle(1);
|
||||
}
|
||||
else
|
||||
skip( "RtlRaiseException not found\n" );
|
||||
@@ -1878,6 +1941,7 @@ START_TEST(exception)
|
||||
test_rtlraiseexception();
|
||||
test_outputdebugstring(1, FALSE);
|
||||
test_ripevent(1);
|
||||
+ test_closehandle(0);
|
||||
test_debugger();
|
||||
test_simd_exceptions();
|
||||
test_fpu_exceptions();
|
||||
@@ -1896,6 +1960,7 @@ START_TEST(exception)
|
||||
|
||||
test_outputdebugstring(1, FALSE);
|
||||
test_ripevent(1);
|
||||
+ test_closehandle(0);
|
||||
test_virtual_unwind();
|
||||
|
||||
if (pRtlAddFunctionTable && pRtlDeleteFunctionTable && pRtlInstallFunctionTableCallback && pRtlLookupFunctionEntry)
|
||||
--
|
||||
2.1.1
|
||||
|
@ -0,0 +1,101 @@
|
||||
From fbc7c0a7ec5822215a9da690ea75d8cb3359bc9e Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 28 Sep 2014 23:39:51 +0200
|
||||
Subject: ntdll: OutputDebugString should throw the exception a second time, if
|
||||
a debugger is attached.
|
||||
|
||||
---
|
||||
dlls/kernel32/debugger.c | 17 +++++++++++++++++
|
||||
dlls/ntdll/tests/exception.c | 19 +++++++------------
|
||||
2 files changed, 24 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/debugger.c b/dlls/kernel32/debugger.c
|
||||
index d4d66b2..981661b 100644
|
||||
--- a/dlls/kernel32/debugger.c
|
||||
+++ b/dlls/kernel32/debugger.c
|
||||
@@ -277,6 +277,23 @@ void WINAPI OutputDebugStringA( LPCSTR str )
|
||||
__ENDTRY
|
||||
if (caught_by_dbg) return;
|
||||
|
||||
+ /* for some unknown reason Windows sends the exception a second time, if a
|
||||
+ * debugger is attached, and the event wasn't handled in the first attempt */
|
||||
+ if (NtCurrentTeb()->Peb->BeingDebugged)
|
||||
+ {
|
||||
+ __TRY
|
||||
+ {
|
||||
+ ULONG_PTR args[2];
|
||||
+ args[0] = strlen(str) + 1;
|
||||
+ args[1] = (ULONG_PTR)str;
|
||||
+ RaiseException( DBG_PRINTEXCEPTION_C, 0, 2, args );
|
||||
+ }
|
||||
+ __EXCEPT(debug_exception_handler)
|
||||
+ {
|
||||
+ }
|
||||
+ __ENDTRY
|
||||
+ }
|
||||
+
|
||||
/* send string to a system-wide monitor */
|
||||
if (!mutex_inited)
|
||||
{
|
||||
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
|
||||
index bc36242..3f0e6f5 100644
|
||||
--- a/dlls/ntdll/tests/exception.c
|
||||
+++ b/dlls/ntdll/tests/exception.c
|
||||
@@ -1724,7 +1724,7 @@ static LONG CALLBACK outputdebugstring_vectored_handler(EXCEPTION_POINTERS *Exce
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
-static void test_outputdebugstring(DWORD numexc, BOOL todo)
|
||||
+static void test_outputdebugstring(DWORD numexc)
|
||||
{
|
||||
PVOID vectored_handler;
|
||||
|
||||
@@ -1739,13 +1739,8 @@ static void test_outputdebugstring(DWORD numexc, BOOL todo)
|
||||
|
||||
outputdebugstring_exceptions = 0;
|
||||
OutputDebugStringA("Hello World");
|
||||
- if (todo)
|
||||
- todo_wine
|
||||
- ok(outputdebugstring_exceptions == numexc, "OutputDebugStringA generated %d exceptions, expected %d\n",
|
||||
- outputdebugstring_exceptions, numexc);
|
||||
- else
|
||||
- ok(outputdebugstring_exceptions == numexc, "OutputDebugStringA generated %d exceptions, expected %d\n",
|
||||
- outputdebugstring_exceptions, numexc);
|
||||
+ ok(outputdebugstring_exceptions == numexc, "OutputDebugStringA generated %d exceptions, expected %d\n",
|
||||
+ outputdebugstring_exceptions, numexc);
|
||||
|
||||
pRtlRemoveVectoredExceptionHandler(vectored_handler);
|
||||
}
|
||||
@@ -1917,9 +1912,9 @@ START_TEST(exception)
|
||||
run_rtlraiseexception_test(EXCEPTION_BREAKPOINT);
|
||||
run_rtlraiseexception_test(EXCEPTION_INVALID_HANDLE);
|
||||
test_stage = 3;
|
||||
- test_outputdebugstring(0, FALSE);
|
||||
+ test_outputdebugstring(0);
|
||||
test_stage = 4;
|
||||
- test_outputdebugstring(2, TRUE); /* is this a Windows bug? */
|
||||
+ test_outputdebugstring(2);
|
||||
test_stage = 5;
|
||||
test_ripevent(0);
|
||||
test_stage = 6;
|
||||
@@ -1939,7 +1934,7 @@ START_TEST(exception)
|
||||
test_unwind();
|
||||
test_exceptions();
|
||||
test_rtlraiseexception();
|
||||
- test_outputdebugstring(1, FALSE);
|
||||
+ test_outputdebugstring(1);
|
||||
test_ripevent(1);
|
||||
test_closehandle(0);
|
||||
test_debugger();
|
||||
@@ -1958,7 +1953,7 @@ START_TEST(exception)
|
||||
pRtlLookupFunctionEntry = (void *)GetProcAddress( hntdll,
|
||||
"RtlLookupFunctionEntry" );
|
||||
|
||||
- test_outputdebugstring(1, FALSE);
|
||||
+ test_outputdebugstring(1);
|
||||
test_ripevent(1);
|
||||
test_closehandle(0);
|
||||
test_virtual_unwind();
|
||||
--
|
||||
2.1.1
|
||||
|
3
patches/ntdll-Exception/definition
Normal file
3
patches/ntdll-Exception/definition
Normal file
@ -0,0 +1,3 @@
|
||||
Author: Sebastian Lackner
|
||||
Subject: Fix some differences in exception handling behaviour between Wine and Windows.
|
||||
Revision: 1
|
Loading…
x
Reference in New Issue
Block a user