tests: Report all errors when failing to wait for a child process.

Report the line number where the test failed to wait for the child so
one can identify which child process did not behave as expected.
Also wait_child_process() is meant for the general case so report
all non-crash error cases as test failures so they are accounted for.
Omit the "winetest_" prefix to match the other Wine test functions and
so the underlying winetest_wait_child_process() function can be wrapped
with the usual line-capturing macros.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48651
Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Francois Gouget 2020-03-16 23:52:21 +01:00 committed by Alexandre Julliard
parent f0dbd3addc
commit a909baeb4e
30 changed files with 64 additions and 52 deletions

View File

@ -3050,7 +3050,7 @@ static void test_process_security(void)
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
TEST_GRANTED_ACCESS2( info.hThread, THREAD_ALL_ACCESS_NT4,
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
winetest_wait_child_process( info.hProcess );
wait_child_process( info.hProcess );
FreeSid(EveryoneSid);
CloseHandle( info.hProcess );
@ -7189,7 +7189,7 @@ static void test_token_security_descriptor(void)
sprintf(buffer, "%s security test_token_sd", myARGV[0]);
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess failed with error %u\n", GetLastError());
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);

View File

@ -308,7 +308,7 @@ todo_wine
SetEvent(event);
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);
@ -473,7 +473,7 @@ static void test_module_information(void)
ok(hr == S_OK, "Failed to detach, hr %#x.\n", hr);
SetEvent(event);
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);

View File

@ -7268,7 +7268,7 @@ START_TEST(font)
sprintf(path_name, "%s font %s", argv[0], test_names[i]);
ok(CreateProcessA(NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
"CreateProcess failed.\n");
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);
}

View File

@ -2506,7 +2506,7 @@ static void run_child_process(void)
sprintf(cmdline, "\"%s\" %s manifest1", argv[0], argv[1]);
ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "Could not create process: %u\n", GetLastError());
winetest_wait_child_process( pi.hProcess );
wait_child_process( pi.hProcess );
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
DeleteFileA(path);
@ -3470,7 +3470,7 @@ static void run_child_process_two_dll(int run)
ret = CreateProcessA(exe, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "Could not create process: %u\n", GetLastError());
winetest_wait_child_process( pi.hProcess );
wait_child_process( pi.hProcess );
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);

View File

@ -3272,7 +3272,7 @@ static void test_AttachConsole(HANDLE console)
ok(res, "CreateProcess failed: %u\n", GetLastError());
CloseHandle(info.hThread);
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(info.hProcess);
res = ReadConsoleOutputCharacterA(console, buf, 5, c, &len);

View File

@ -1102,7 +1102,7 @@ static void test_debug_heap( const char *argv0, DWORD flags )
ok( ret, "failed to create child process error %u\n", GetLastError() );
if (ret)
{
winetest_wait_child_process( info.hProcess );
wait_child_process( info.hProcess );
CloseHandle( info.hThread );
CloseHandle( info.hProcess );
}

View File

@ -3258,7 +3258,7 @@ static void test_overlapped_transport(BOOL msg_mode, BOOL msg_read_mode)
ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x %u\n", res, GetLastError());
ok(read_bytes == 10, "read_bytes = %u\n", read_bytes);
TerminateProcess(process, 0);
winetest_wait_child_process(process);
wait_child_process(process);
/* after terminating process, there is no pending write and pipe buffer is empty */
overlapped_read_async(server, buf, 10, &overlapped);
overlapped_write_sync(client, buf, 1);
@ -3524,7 +3524,7 @@ static void test_namedpipe_process_id(void)
ok(server != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
process = create_check_id_process("checkpid", GetProcessId(GetCurrentProcess()));
winetest_wait_child_process(process);
wait_child_process(process);
CloseHandle(overlapped.hEvent);
CloseHandle(process);
@ -3667,7 +3667,7 @@ static void test_namedpipe_session_id(void)
ok(server != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
process = create_check_id_process("checksessionid", current);
winetest_wait_child_process(process);
wait_child_process(process);
CloseHandle(overlapped.hEvent);
CloseHandle(process);

View File

@ -343,5 +343,5 @@ START_TEST(toolhelp)
test_module(info.dwProcessId, sub_expected_modules, ARRAY_SIZE(sub_expected_modules));
SetEvent(ev2);
winetest_wait_child_process( info.hProcess );
wait_child_process( info.hProcess );
}

View File

@ -4154,7 +4154,7 @@ static void test_shared_memory(BOOL is_child)
sprintf(cmdline, "\"%s\" virtual sharedmem", argv[0]);
ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
winetest_wait_child_process(pi.hProcess);
wait_child_process(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
@ -4194,7 +4194,7 @@ static void test_shared_memory_ro(BOOL is_child, DWORD child_access)
sprintf(cmdline, "\"%s\" virtual sharedmemro %x", argv[0], child_access);
ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
winetest_wait_child_process(pi.hProcess);
wait_child_process(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);

View File

@ -4434,7 +4434,7 @@ static void test_queue_com(void)
sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
"CreateProcess failed.\n" );
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);
}
@ -4446,7 +4446,7 @@ static void test_queue_com(void)
sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
"CreateProcess failed.\n" );
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);
}

View File

@ -315,7 +315,7 @@ static void run_child_process(const char *dll_source, run_type run)
ret = CreateProcessA(exe, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "Could not create process: %u\n", GetLastError());
winetest_wait_child_process(pi.hProcess);
wait_child_process(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);

View File

@ -217,7 +217,7 @@ static void test___getmainargs_parent(char *name)
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc);
winetest_wait_child_process(proc.hProcess);
wait_child_process(proc.hProcess);
_unlink(filepath);
sprintf(filepath, "%swine_test\\a", tmppath);

View File

@ -1430,7 +1430,7 @@ static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hst
CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
winetest_wait_child_process( proc.hProcess );
wait_child_process( proc.hProcess );
data = read_file( hErrorFile );
if (expect_stdout)
@ -1647,7 +1647,7 @@ static void test_invalid_stdin( const char* selfname )
sprintf(cmdline, "%s file stdin", selfname);
CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc);
winetest_wait_child_process(proc.hProcess);
wait_child_process(proc.hProcess);
ret = RegCloseKey(key);
ok(!ret, "RegCloseKey failed: %x\n", ret);

View File

@ -1182,7 +1182,7 @@ static void test_debugger(void)
} while (de.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT);
winetest_wait_child_process( pi.hProcess );
wait_child_process( pi.hProcess );
ret = CloseHandle(pi.hThread);
ok(ret, "error %u\n", GetLastError());
ret = CloseHandle(pi.hProcess);
@ -3402,7 +3402,7 @@ static void test_suspend_process(void)
SetEvent(event);
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);

View File

@ -3894,7 +3894,7 @@ static void test_local_server(void)
quit_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
SetEvent(quit_event);
winetest_wait_child_process( process );
wait_child_process( process );
CloseHandle(quit_event);
CloseHandle(process);
}

View File

@ -547,7 +547,7 @@ static void test_LresultFromObject(const char *name)
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &proc);
winetest_wait_child_process(proc.hProcess);
wait_child_process(proc.hProcess);
ok(Object_ref == 1, "Object_ref = %d\n", Object_ref);
}

View File

@ -117,7 +117,7 @@ static void run_child(WCHAR *secret)
wsprintfW(cmdline, format, progname, secret);
ok(CreateProcessW(NULL, cmdline, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
ok(CloseHandle(info.hProcess), "CloseHandle\n");
ok(CloseHandle(info.hThread), "CloseHandle\n");
}

View File

@ -1112,7 +1112,7 @@ run_client(const char *test)
make_cmdline(cmdline, test);
ok(CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
winetest_wait_child_process( info.hProcess );
wait_child_process( info.hProcess );
ok(CloseHandle(info.hProcess), "CloseHandle\n");
ok(CloseHandle(info.hThread), "CloseHandle\n");
}
@ -2337,7 +2337,7 @@ static void test_reconnect(void)
stop();
winetest_wait_child_process(server_process);
wait_child_process(server_process);
ok(CloseHandle(server_process), "CloseHandle\n");
/* create new server, rpcrt4 will connect to it once sending to existing connection fails
@ -2346,7 +2346,7 @@ static void test_reconnect(void)
basic_tests();
stop();
winetest_wait_child_process(server_process);
wait_child_process(server_process);
ok(CloseHandle(server_process), "CloseHandle\n");
ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");

View File

@ -1786,7 +1786,7 @@ static void test_NonExistentPath(void)
startup.wShowWindow = SW_SHOWNORMAL;
CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
&startup, &info);
winetest_wait_child_process( info.hProcess );
wait_child_process( info.hProcess );
/* restore original values: */
trace("Restoring CSIDL_FAVORITES to %s\n", originalPath);

View File

@ -481,7 +481,7 @@ static void test_alloc_shared(int argc, char **argv)
ok(ret, "could not create child process error: %u\n", GetLastError());
if (ret)
{
winetest_wait_child_process(pi.hProcess);
wait_child_process(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);

View File

@ -192,7 +192,7 @@ static void run_child_process(void)
ret = CreateProcessA(exe, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "Could not create process: %u\n", GetLastError());
winetest_wait_child_process(pi.hProcess);
wait_child_process(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);

View File

@ -476,7 +476,7 @@ static void test__get_narrow_winmain_command_line(char *path)
CreateProcessA(path, cmd, NULL, NULL, TRUE,
CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,
NULL, NULL, &startup, &proc);
winetest_wait_child_process(proc.hProcess);
wait_child_process(proc.hProcess);
CloseHandle(proc.hProcess);
CloseHandle(proc.hThread);
}

View File

@ -1916,7 +1916,7 @@ static void test_internet_features(void) {
sprintf(cmdline, "\"%s\" %s internet_features", argv[0], argv[1]);
ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "Could not create process: %u\n", GetLastError());
winetest_wait_child_process( pi.hProcess );
wait_child_process( pi.hProcess );
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);

View File

@ -848,7 +848,7 @@ static void run_child_process(void)
sprintf(cmdline, "\"%s\" %s domain_tests", argv[0], argv[1]);
ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "Failed to spawn child process: %u\n", GetLastError());
winetest_wait_child_process(pi.hProcess);
wait_child_process(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}

View File

@ -1280,7 +1280,7 @@ static void test_comctl32_classes(void)
sprintf( path_name, "%s class %s", argv[0], classes[i] );
ok( CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info ),
"CreateProcess failed.\n" );
winetest_wait_child_process( info.hProcess );
wait_child_process( info.hProcess );
CloseHandle( info.hProcess );
CloseHandle( info.hThread );
}

View File

@ -171,7 +171,7 @@ static void run_process( const char *args )
ok( CreateProcessA( NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info ),
"CreateProcess %s failed\n", cmd );
winetest_wait_child_process( info.hProcess );
wait_child_process( info.hProcess );
CloseHandle( info.hProcess );
CloseHandle( info.hThread );
}

View File

@ -446,7 +446,7 @@ static void do_parent(void)
static void finish_child_process(void)
{
SendMessageA(child, WM_CLOSE, 0, 0);
winetest_wait_child_process( child_process );
wait_child_process( child_process );
CloseHandle(child_process);
}

View File

@ -16305,7 +16305,7 @@ static void test_WaitForInputIdle( char *argv0 )
WaitForSingleObject( pi.hProcess, 1000 ); /* give it a chance to exit on its own */
}
TerminateProcess( pi.hProcess, 0 ); /* just in case */
winetest_wait_child_process( pi.hProcess );
wait_child_process( pi.hProcess );
ret = WaitForInputIdle( pi.hProcess, 100 );
ok( ret == WAIT_FAILED, "%u: WaitForInputIdle after exit error %08x\n", i, ret );
CloseHandle( pi.hProcess );

View File

@ -9451,7 +9451,7 @@ static void test_window_from_point(const char *argv0)
ok(win == child, "WindowFromPoint returned %p, expected %p\n", win, child);
SetEvent(end_event);
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(start_event);
CloseHandle(end_event);
CloseHandle(info.hProcess);
@ -10302,7 +10302,7 @@ static void test_winproc_handles(const char *argv0)
startup.cb = sizeof(startup);
ok(CreateProcessA(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL,
&startup, &info), "CreateProcess failed.\n");
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);
}
@ -11825,7 +11825,7 @@ static void test_other_process_window(const char *argv0)
ret = WaitForSingleObject(test_done_event, 5000);
ok(ret == WAIT_OBJECT_0, "Unexpected ret %x.\n", ret);
winetest_wait_child_process(info.hProcess);
wait_child_process(info.hProcess);
CloseHandle(window_ready_event);
CloseHandle(test_done_event);
CloseHandle(info.hProcess);

View File

@ -110,12 +110,14 @@ extern void __winetest_cdecl winetest_trace( const char *msg, ... ) __WINE_PRINT
# define skip_(file, line) (winetest_set_location(file, 0), 0) ? (void)0 : winetest_skip
# define win_skip_(file, line) (winetest_set_location(file, 0), 0) ? (void)0 : winetest_win_skip
# define trace_(file, line) (winetest_set_location(file, 0), 0) ? (void)0 : winetest_trace
# define wait_process_(file, line) (winetest_set_location(file, 0), 0) ? (void)0 : winetest_wait_process
#else
# define subtest_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_subtest
# define ok_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_ok
# define skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_skip
# define win_skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_win_skip
# define trace_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_trace
# define wait_child_process_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_wait_child_process
#endif
#define subtest subtest_(__FILE__, __LINE__)
@ -123,6 +125,7 @@ extern void __winetest_cdecl winetest_trace( const char *msg, ... ) __WINE_PRINT
#define skip skip_(__FILE__, __LINE__)
#define win_skip win_skip_(__FILE__, __LINE__)
#define trace trace_(__FILE__, __LINE__)
#define wait_child_process wait_child_process_(__FILE__, __LINE__)
#define todo_if(is_todo) for (winetest_start_todo(is_todo); \
winetest_loop_todo(); \
@ -477,24 +480,33 @@ void winetest_add_failures( LONG new_failures )
void winetest_wait_child_process( HANDLE process )
{
DWORD exit_code = 1;
DWORD ret;
if (WaitForSingleObject( process, 30000 ))
printf( "%s: child process wait failed\n", current_test->name );
winetest_ok( process != NULL, "No child process handle (CreateProcess failed?)\n" );
if (!process) return;
ret = WaitForSingleObject( process, 30000 );
if (ret == WAIT_TIMEOUT)
winetest_ok( 0, "Timed out waiting for the child process\n" );
else if (ret != WAIT_OBJECT_0)
winetest_ok( 0, "Could not wait for the child process: %d le=%u\n",
ret, GetLastError() );
else
GetExitCodeProcess( process, &exit_code );
if (exit_code)
{
DWORD exit_code;
struct tls_data *data = get_tls_data();
GetExitCodeProcess( process, &exit_code );
if (exit_code > 255)
{
printf( "%s: exception 0x%08x in child process\n", current_test->name, exit_code );
DWORD pid = GetProcessId( process );
printf( "%s:%d: unhandled exception %08x in child process %04x\n",
current_test->name, data->current_line, exit_code, pid );
InterlockedIncrement( &failures );
}
else
else if (exit_code)
{
printf( "%s: %u failures in child process\n",
current_test->name, exit_code );
printf( "%s:%d: %u failures in child process\n",
current_test->name, data->current_line, exit_code );
while (exit_code-- > 0)
InterlockedIncrement(&failures);
}