Francois Gouget : server: Fix the crashed process exit code when the debugger exits without detaching . Add a conformance test.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Aug 31 07:22:18 CDT 2007


Module: wine
Branch: master
Commit: b6aa247093affa7eb0e34a96dcd803597d4d5145
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b6aa247093affa7eb0e34a96dcd803597d4d5145

Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Fri Aug 31 02:35:54 2007 +0200

server: Fix the crashed process exit code when the debugger exits without detaching. Add a conformance test.

---

 dlls/kernel32/tests/debugger.c |   51 ++++++++++++++++++++++++++++++---------
 server/debugger.c              |    2 +-
 2 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c
index 19ab840..4328232 100644
--- a/dlls/kernel32/tests/debugger.c
+++ b/dlls/kernel32/tests/debugger.c
@@ -25,6 +25,10 @@
 #include <winreg.h>
 #include "wine/test.h"
 
+#ifndef STATUS_DEBUGGER_INACTIVE
+#define STATUS_DEBUGGER_INACTIVE         ((NTSTATUS) 0xC0000354)
+#endif
+
 static int    myARGC;
 static char** myARGV;
 
@@ -113,6 +117,8 @@ typedef struct
     DWORD pid;
     BOOL debug_rc;
     DWORD debug_err;
+    BOOL attach_rc;
+    DWORD attach_err;
 } debugger_blackbox_t;
 
 static void doDebugger(int argc, char** argv)
@@ -124,8 +130,18 @@ static void doDebugger(int argc, char** argv)
     blackbox.argc=argc;
     logfile=(argc >= 4 ? argv[3] : NULL);
     blackbox.pid=(argc >= 5 ? atol(argv[4]) : 0);
+
+    if (strstr(myARGV[2], "attach"))
+    {
+        blackbox.attach_rc=DebugActiveProcess(blackbox.pid);
+        if (!blackbox.attach_rc)
+            blackbox.attach_err=GetLastError();
+    }
+    else
+        blackbox.attach_rc=TRUE;
+
     debug_event=(argc >= 6 ? (HANDLE)atol(argv[5]) : NULL);
-    if (debug_event && strcmp(myARGV[2], "dbgnoevent") != 0)
+    if (debug_event && strstr(myARGV[2], "event"))
     {
         blackbox.debug_rc=SetEvent(debug_event);
         if (!blackbox.debug_rc)
@@ -135,7 +151,7 @@ static void doDebugger(int argc, char** argv)
         blackbox.debug_rc=TRUE;
 
     get_events(logfile, &start_event, &done_event);
-    if (strcmp(myARGV[2], "dbgnoevent") != 0)
+    if (strstr(myARGV[2], "order"))
     {
         trace("debugger: waiting for the start signal...\n");
         WaitForSingleObject(start_event, INFINITE);
@@ -149,7 +165,7 @@ static void doDebugger(int argc, char** argv)
     ExitProcess(0xdeadbeef);
 }
 
-static void crash_and_debug(HKEY hkey, const char* argv0, const char* debugger)
+static void crash_and_debug(HKEY hkey, const char* argv0, const char* dbgtasks)
 {
     DWORD ret;
     HANDLE start_event, done_event;
@@ -167,8 +183,8 @@ static void crash_and_debug(HKEY hkey, const char* argv0, const char* debugger)
 
     get_file_name(dbglog);
     get_events(dbglog, &start_event, &done_event);
-    cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+10+strlen(debugger)+1+strlen(dbglog)+34+1);
-    sprintf(cmd, "%s debugger %s %s %%ld %%ld", argv0, debugger, dbglog);
+    cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+10+strlen(dbgtasks)+1+strlen(dbglog)+34+1);
+    sprintf(cmd, "%s debugger %s %s %%ld %%ld", argv0, dbgtasks, dbglog);
     ret=RegSetValueExA(hkey, "debugger", 0, REG_SZ, (BYTE*)cmd, strlen(cmd)+1);
     ok(ret == ERROR_SUCCESS, "unable to set AeDebug/debugger: ret=%d\n", ret);
     HeapFree(GetProcessHeap(), 0, cmd);
@@ -190,11 +206,22 @@ static void crash_and_debug(HKEY hkey, const char* argv0, const char* debugger)
     trace("waiting for child exit...\n");
     ok(WaitForSingleObject(info.hProcess, 60000) == WAIT_OBJECT_0, "Timed out waiting for the child to crash\n");
     ok(GetExitCodeProcess(info.hProcess, &exit_code), "GetExitCodeProcess failed: err=%d\n", GetLastError());
-    ok(exit_code == STATUS_ACCESS_VIOLATION, "exit code = %08x\n", exit_code);
+    if (strstr(dbgtasks, "code2"))
+    {
+        /* If, after attaching to the debuggee, the debugger exits without
+         * detaching, then the debuggee gets a special exit code.
+         */
+        ok(exit_code == 0xffffffff || /* Win 9x */
+           exit_code == 0x80 || /* NT4 */
+           exit_code == STATUS_DEBUGGER_INACTIVE, /* Win >= XP */
+           "wrong exit code : %08x\n", exit_code);
+    }
+    else
+        ok(exit_code == STATUS_ACCESS_VIOLATION, "exit code = %08x instead of STATUS_ACCESS_VIOLATION\n", exit_code);
     CloseHandle(info.hProcess);
 
     /* ...before the debugger */
-    if (strcmp(debugger, "dbgnoevent") != 0)
+    if (strstr(dbgtasks, "order"))
         ok(SetEvent(start_event), "SetEvent(start_event) failed\n");
 
     trace("waiting for the debugger...\n");
@@ -206,6 +233,7 @@ static void crash_and_debug(HKEY hkey, const char* argv0, const char* debugger)
     ok(dbg_blackbox.argc == 6, "wrong debugger argument count: %d\n", dbg_blackbox.argc);
     ok(dbg_blackbox.pid == crash_blackbox.pid, "the child and debugged pids don't match: %d != %d\n", crash_blackbox.pid, dbg_blackbox.pid);
     ok(dbg_blackbox.debug_rc, "debugger: SetEvent(debug_event) failed err=%d\n", dbg_blackbox.debug_err);
+    ok(dbg_blackbox.attach_rc, "DebugActiveProcess(%d) failed err=%d\n", dbg_blackbox.pid, dbg_blackbox.attach_err);
 
     assert(DeleteFileA(dbglog) != 0);
     assert(DeleteFileA(childlog) != 0);
@@ -296,8 +324,9 @@ static void test_ExitCode(void)
         strstr((char*)debugger_val, "winedbg --auto"))
         crash_and_winedbg(hkey, test_exe);
 
-    crash_and_debug(hkey, test_exe, "dbgevent");
-    crash_and_debug(hkey, test_exe, "dbgnoevent");
+    crash_and_debug(hkey, test_exe, "dbg,none");
+    crash_and_debug(hkey, test_exe, "dbg,event,order");
+    crash_and_debug(hkey, test_exe, "dbg,attach,event,code2");
 
     if (disposition == REG_CREATED_NEW_KEY)
     {
@@ -333,9 +362,7 @@ START_TEST(debugger)
     {
         doCrash(myARGC, myARGV);
     }
-    else if (myARGC >= 3 &&
-             (strcmp(myARGV[2], "dbgevent") == 0 ||
-              strcmp(myARGV[2], "dbgnoevent") == 0))
+    else if (myARGC >= 3 && strncmp(myARGV[2], "dbg,", 4) == 0)
     {
         doDebugger(myARGC, myARGV);
     }
diff --git a/server/debugger.c b/server/debugger.c
index ee8ef10..4d0ac3d 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -542,7 +542,7 @@ void debug_exit_thread( struct thread *thread )
         if (thread->debug_ctx->kill_on_exit)
         {
             /* kill all debugged processes */
-            kill_debugged_processes( thread, thread->exit_code );
+            kill_debugged_processes( thread, STATUS_DEBUGGER_INACTIVE );
         }
         else
         {




More information about the wine-cvs mailing list