Piotr Caban : server: Don' t debug children when debugger is attached with DebugActiveProcess function .
Alexandre Julliard
julliard at winehq.org
Fri Apr 5 14:02:16 CDT 2013
Module: wine
Branch: master
Commit: 23191a4355c16febe4d26722de27d7a14f11872a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=23191a4355c16febe4d26722de27d7a14f11872a
Author: Piotr Caban <piotr at codeweavers.com>
Date: Fri Apr 5 14:08:02 2013 +0200
server: Don't debug children when debugger is attached with DebugActiveProcess function.
---
dlls/kernel32/tests/debugger.c | 151 ++++++++++++++++++++++++++++++++++++++++
server/process.c | 2 +-
2 files changed, 152 insertions(+), 1 deletions(-)
diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c
index 22f7190..e578cdd 100644
--- a/dlls/kernel32/tests/debugger.c
+++ b/dlls/kernel32/tests/debugger.c
@@ -666,6 +666,150 @@ static void test_debug_loop(int argc, char **argv)
ok(ret, "DeleteFileA failed, last error %#x.\n", GetLastError());
}
+static void doChildren(int argc, char **argv)
+{
+ const char *arguments = "debugger children last";
+ struct child_blackbox blackbox;
+ const char *blackbox_file, *p;
+ char event_name[MAX_PATH];
+ PROCESS_INFORMATION pi;
+ STARTUPINFOA si;
+ HANDLE event;
+ char *cmd;
+ BOOL ret;
+
+ if (!strcmp(argv[3], "last")) return;
+
+ blackbox_file = argv[3];
+
+ p = strrchr(blackbox_file, '\\');
+ p = p ? p+1 : blackbox_file;
+ strcpy(event_name, p);
+ strcat(event_name, "_init");
+ event = OpenEvent(EVENT_ALL_ACCESS, FALSE, event_name);
+ child_ok(event != NULL, "OpenEvent failed, last error %d.\n", GetLastError());
+ SetEvent(event);
+ CloseHandle(event);
+
+ p = strrchr(blackbox_file, '\\');
+ p = p ? p+1 : blackbox_file;
+ strcpy(event_name, p);
+ strcat(event_name, "_attach");
+ event = OpenEvent(EVENT_ALL_ACCESS, FALSE, event_name);
+ child_ok(event != NULL, "OpenEvent failed, last error %d.\n", GetLastError());
+ WaitForSingleObject(event, INFINITE);
+ CloseHandle(event);
+
+ cmd = HeapAlloc(GetProcessHeap(), 0, strlen(argv[0]) + strlen(arguments) + 2);
+ sprintf(cmd, "%s %s", argv[0], arguments);
+
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ ret = CreateProcessA(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+ child_ok(ret, "CreateProcess failed, last error %d.\n", GetLastError());
+
+ child_ok(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0,
+ "Timed out waiting for the child to exit\n");
+
+ ret = CloseHandle(pi.hThread);
+ child_ok(ret, "CloseHandle failed, last error %d.\n", GetLastError());
+ ret = CloseHandle(pi.hProcess);
+ child_ok(ret, "CloseHandle failed, last error %d.\n", GetLastError());
+
+ blackbox.failures = child_failures;
+ save_blackbox(blackbox_file, &blackbox, sizeof(blackbox));
+}
+
+static void test_debug_children(char *name, DWORD flag, BOOL debug_child)
+{
+ const char *arguments = "debugger children";
+ struct child_blackbox blackbox;
+ char blackbox_file[MAX_PATH], *p;
+ char event_name[MAX_PATH];
+ PROCESS_INFORMATION pi;
+ STARTUPINFOA si;
+ HANDLE event_init, event_attach;
+ char *cmd;
+ BOOL debug, ret;
+ BOOL got_child_event = FALSE;
+
+ if (!pDebugActiveProcessStop || !pCheckRemoteDebuggerPresent)
+ {
+ win_skip("DebugActiveProcessStop or CheckRemoteDebuggerPresent not available, skipping test.\n");
+ return;
+ }
+
+ get_file_name(blackbox_file);
+ cmd = HeapAlloc(GetProcessHeap(), 0, strlen(name) + strlen(arguments) + strlen(blackbox_file) + 5);
+ sprintf(cmd, "%s %s \"%s\"", name, arguments, blackbox_file);
+
+ p = strrchr(blackbox_file, '\\');
+ p = p ? p+1 : blackbox_file;
+ strcpy(event_name, p);
+ strcat(event_name, "_init");
+ event_init = CreateEvent(NULL, FALSE, FALSE, event_name);
+ ok(event_init != NULL, "OpenEvent failed, last error %d.\n", GetLastError());
+
+ p = strrchr(blackbox_file, '\\');
+ p = p ? p+1 : blackbox_file;
+ strcpy(event_name, p);
+ strcat(event_name, "_attach");
+ event_attach = CreateEvent(NULL, FALSE, flag!=0, event_name);
+ ok(event_attach != NULL, "CreateEvent failed, last error %d.\n", GetLastError());
+
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+
+ ret = CreateProcessA(NULL, cmd, NULL, NULL, FALSE, flag, NULL, NULL, &si, &pi);
+ ok(ret, "CreateProcess failed, last error %d.\n", GetLastError());
+ HeapFree(GetProcessHeap(), 0, cmd);
+ if (!flag)
+ {
+ WaitForSingleObject(event_init, INFINITE);
+ ret = DebugActiveProcess(pi.dwProcessId);
+ ok(ret, "DebugActiveProcess failed, last error %d.\n", GetLastError());
+ ret = SetEvent(event_attach);
+ ok(ret, "SetEvent failed, last error %d.\n", GetLastError());
+ }
+
+ ret = pCheckRemoteDebuggerPresent(pi.hProcess, &debug);
+ ok(ret, "CheckRemoteDebuggerPresent failed, last error %d.\n", GetLastError());
+ ok(debug, "Expected debug != 0, got %x.\n", debug);
+
+ for (;;)
+ {
+ DEBUG_EVENT ev;
+
+ ret = WaitForDebugEvent(&ev, INFINITE);
+ ok(ret, "WaitForDebugEvent failed, last error %d.\n", GetLastError());
+ if (!ret) break;
+
+ if (ev.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT && ev.dwProcessId==pi.dwProcessId) break;
+ else if (ev.dwProcessId != pi.dwProcessId) got_child_event = TRUE;
+
+ ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
+ ok(ret, "ContinueDebugEvent failed, last error %d.\n", GetLastError());
+ if (!ret) break;
+ }
+ if(debug_child)
+ ok(got_child_event, "didn't get any child events (flag: %x).\n", flag);
+ else
+ ok(!got_child_event, "got child event (flag: %x).\n", flag);
+ CloseHandle(event_init);
+ CloseHandle(event_attach);
+
+ ret = CloseHandle(pi.hThread);
+ ok(ret, "CloseHandle failed, last error %d.\n", GetLastError());
+ ret = CloseHandle(pi.hProcess);
+ ok(ret, "CloseHandle failed, last error %d.\n", GetLastError());
+
+ load_blackbox(blackbox_file, &blackbox, sizeof(blackbox));
+ ok(!blackbox.failures, "Got %d failures from child process.\n", blackbox.failures);
+
+ ret = DeleteFileA(blackbox_file);
+ ok(ret, "DeleteFileA failed, last error %d.\n", GetLastError());
+}
+
START_TEST(debugger)
{
HMODULE hdll;
@@ -691,10 +835,17 @@ START_TEST(debugger)
{
doChild(myARGC, myARGV);
}
+ else if (myARGC >= 4 && !strcmp(myARGV[2], "children"))
+ {
+ doChildren(myARGC, myARGV);
+ }
else
{
test_ExitCode();
test_RemoteDebugger();
test_debug_loop(myARGC, myARGV);
+ test_debug_children(myARGV[0], DEBUG_PROCESS, TRUE);
+ test_debug_children(myARGV[0], DEBUG_ONLY_THIS_PROCESS, FALSE);
+ test_debug_children(myARGV[0], 0, FALSE);
}
}
diff --git a/server/process.c b/server/process.c
index 058538f..4f04a23 100644
--- a/server/process.c
+++ b/server/process.c
@@ -947,7 +947,7 @@ DECL_HANDLER(new_process)
if (!(thread = create_process( socket_fd, current, req->inherit_all ))) goto done;
process = thread->process;
- process->debug_children = !(req->create_flags & DEBUG_ONLY_THIS_PROCESS);
+ process->debug_children = !!(req->create_flags & DEBUG_PROCESS);
process->startup_info = (struct startup_info *)grab_object( info );
/* connect to the window station */
More information about the wine-cvs
mailing list