Dmitry Timoshkov : kernel32/tests: Add a test for holding a critical section during process termination.

Alexandre Julliard julliard at winehq.org
Thu Nov 29 15:09:36 CST 2018


Module: wine
Branch: stable
Commit: b4307ecab34b3e130046b147073a7701a6b542d6
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b4307ecab34b3e130046b147073a7701a6b542d6

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Tue Aug  7 16:03:13 2018 +0800

kernel32/tests: Add a test for holding a critical section during process termination.

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 0f99327e78b07fa0a2a40454870a75f12c48eeb9)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/kernel32/tests/loader.c | 67 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 4 deletions(-)

diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index fe2957c..5dc9308 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -1673,13 +1673,15 @@ static void test_import_resolution(void)
 #define MAX_COUNT 10
 static HANDLE attached_thread[MAX_COUNT];
 static DWORD attached_thread_count;
-HANDLE stop_event, event, mutex, semaphore, loader_lock_event, peb_lock_event, heap_lock_event, ack_event;
-static int test_dll_phase, inside_loader_lock, inside_peb_lock, inside_heap_lock;
+static HANDLE event, mutex, semaphore;
+static HANDLE stop_event, loader_lock_event, peb_lock_event, heap_lock_event, cs_lock_event, ack_event;
+static CRITICAL_SECTION cs_lock;
+static int test_dll_phase, inside_loader_lock, inside_peb_lock, inside_heap_lock, inside_cs_lock;
 static LONG fls_callback_count;
 
 static DWORD WINAPI mutex_thread_proc(void *param)
 {
-    HANDLE wait_list[4];
+    HANDLE wait_list[5];
     DWORD ret;
 
     ret = WaitForSingleObject(mutex, 0);
@@ -1691,6 +1693,7 @@ static DWORD WINAPI mutex_thread_proc(void *param)
     wait_list[1] = loader_lock_event;
     wait_list[2] = peb_lock_event;
     wait_list[3] = heap_lock_event;
+    wait_list[4] = cs_lock_event;
 
     trace("%04x: mutex_thread_proc: starting\n", GetCurrentThreadId());
     while (1)
@@ -1720,6 +1723,13 @@ static DWORD WINAPI mutex_thread_proc(void *param)
             inside_heap_lock++;
             SetEvent(ack_event);
         }
+        else if (ret == WAIT_OBJECT_0 + 4)
+        {
+            trace("%04x: mutex_thread_proc: Entering CS lock\n", GetCurrentThreadId());
+            EnterCriticalSection(&cs_lock);
+            inside_cs_lock++;
+            SetEvent(ack_event);
+        }
     }
 
     trace("%04x: mutex_thread_proc: exiting\n", GetCurrentThreadId());
@@ -1829,14 +1839,19 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param)
             ok(0, "dll_entry_point: process should already deadlock\n");
             break;
         }
+        else if (test_dll_phase == 7)
+        {
+            EnterCriticalSection(&cs_lock);
+        }
 
-        if (test_dll_phase == 0 || test_dll_phase == 1 || test_dll_phase == 3)
+        if (test_dll_phase == 0 || test_dll_phase == 1 || test_dll_phase == 3 || test_dll_phase == 7)
             ok(param != NULL, "dll: param %p\n", param);
         else
             ok(!param, "dll: param %p\n", param);
 
         if (test_dll_phase == 0 || test_dll_phase == 1) expected_code = 195;
         else if (test_dll_phase == 3) expected_code = 196;
+        else if (test_dll_phase == 7) expected_code = 199;
         else expected_code = STILL_ACTIVE;
 
         if (test_dll_phase == 3)
@@ -2154,6 +2169,11 @@ static void child_process(const char *dll_name, DWORD target_offset)
     heap_lock_event = CreateEventW(NULL, FALSE, FALSE, NULL);
     ok(heap_lock_event != 0, "CreateEvent error %d\n", GetLastError());
 
+    InitializeCriticalSection(&cs_lock);
+    SetLastError(0xdeadbeef);
+    cs_lock_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+    ok(cs_lock_event != 0, "CreateEvent error %d\n", GetLastError());
+
     SetLastError(0xdeadbeef);
     ack_event = CreateEventW(NULL, FALSE, FALSE, NULL);
     ok(ack_event != 0, "CreateEvent error %d\n", GetLastError());
@@ -2370,6 +2390,20 @@ static void child_process(const char *dll_name, DWORD target_offset)
         ok(0, "ExitProcess should not return\n");
         break;
 
+    case 7:
+        trace("setting cs_lock_event\n");
+        SetEvent(cs_lock_event);
+        WaitForSingleObject(ack_event, 1000);
+        ok(inside_cs_lock != 0, "inside_cs_lock is not set\n");
+
+        *child_failures = winetest_get_failures();
+
+        /* calling ExitProcess should not cause a deadlock */
+        trace("call ExitProcess(199)\n");
+        ExitProcess(199);
+        ok(0, "ExitProcess should not return\n");
+        break;
+
     default:
         assert(0);
         break;
@@ -2674,6 +2708,31 @@ static void test_ExitProcess(void)
     CloseHandle(pi.hThread);
     CloseHandle(pi.hProcess);
 
+    /* phase 7 */
+    *child_failures = -1;
+    sprintf(cmdline, "\"%s\" loader %s %u 7", argv[0], dll_name, target_offset);
+    ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+    ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
+    ret = WaitForSingleObject(pi.hProcess, 5000);
+todo_wine
+    ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
+    if (ret != WAIT_OBJECT_0)
+    {
+        trace("terminating child process\n");
+        TerminateProcess(pi.hProcess, 199);
+    }
+    ret = WaitForSingleObject(pi.hProcess, 1000);
+    ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
+    GetExitCodeProcess(pi.hProcess, &ret);
+    ok(ret == 199, "expected exit code 199, got %u\n", ret);
+    if (*child_failures)
+    {
+        trace("%d failures in child process\n", *child_failures);
+        winetest_add_failures(*child_failures);
+    }
+    CloseHandle(pi.hThread);
+    CloseHandle(pi.hProcess);
+
     /* test remote process termination */
     SetLastError(0xdeadbeef);
     ret = CreateProcessA(argv[0], NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);




More information about the wine-cvs mailing list