server: Don't debug children when debugger is attached with DebugActiveProcess function.
This commit is contained in:
parent
8c9ca2f704
commit
23191a4355
|
@ -666,6 +666,150 @@ static void test_debug_loop(int argc, char **argv)
|
||||||
ok(ret, "DeleteFileA failed, last error %#x.\n", GetLastError());
|
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)
|
START_TEST(debugger)
|
||||||
{
|
{
|
||||||
HMODULE hdll;
|
HMODULE hdll;
|
||||||
|
@ -691,10 +835,17 @@ START_TEST(debugger)
|
||||||
{
|
{
|
||||||
doChild(myARGC, myARGV);
|
doChild(myARGC, myARGV);
|
||||||
}
|
}
|
||||||
|
else if (myARGC >= 4 && !strcmp(myARGV[2], "children"))
|
||||||
|
{
|
||||||
|
doChildren(myARGC, myARGV);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
test_ExitCode();
|
test_ExitCode();
|
||||||
test_RemoteDebugger();
|
test_RemoteDebugger();
|
||||||
test_debug_loop(myARGC, myARGV);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -947,7 +947,7 @@ DECL_HANDLER(new_process)
|
||||||
|
|
||||||
if (!(thread = create_process( socket_fd, current, req->inherit_all ))) goto done;
|
if (!(thread = create_process( socket_fd, current, req->inherit_all ))) goto done;
|
||||||
process = thread->process;
|
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 );
|
process->startup_info = (struct startup_info *)grab_object( info );
|
||||||
|
|
||||||
/* connect to the window station */
|
/* connect to the window station */
|
||||||
|
|
Loading…
Reference in New Issue