mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 12:54:13 +00:00
kernel32/tests: Filter spurious thread creation debug events.
On windows, we get some test failures as un-expected thread create debug events are sent. Try to filter them out in a couple of places. Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
This commit is contained in:
parent
982472d895
commit
8aeca16ca5
1 changed files with 45 additions and 15 deletions
|
@ -452,15 +452,20 @@ static void process_attach_events(struct debugger_context *ctx, BOOL pass_except
|
||||||
/* Win11 doesn't generate it at this point (Win <= 10 do) */
|
/* Win11 doesn't generate it at this point (Win <= 10 do) */
|
||||||
if (ctx->ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT)
|
if (ctx->ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT)
|
||||||
{
|
{
|
||||||
DWORD last_thread;
|
DWORD last_threads[5];
|
||||||
|
unsigned thd_idx = 0, i;
|
||||||
|
|
||||||
/* sometimes (at least Win10) several thread creations are reported here */
|
/* sometimes (at least Win10) several thread creations are reported here */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
last_thread = ctx->ev.dwThreadId;
|
if (thd_idx < ARRAY_SIZE(last_threads))
|
||||||
|
last_threads[thd_idx++] = ctx->ev.dwThreadId;
|
||||||
next_event(ctx, WAIT_EVENT_TIMEOUT);
|
next_event(ctx, WAIT_EVENT_TIMEOUT);
|
||||||
} while (ctx->ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT);
|
} while (ctx->ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT);
|
||||||
ok(ctx->ev.dwThreadId == last_thread, "unexpected thread\n");
|
ok(thd_idx <= ARRAY_SIZE(last_threads), "too many threads created\n");
|
||||||
|
for (i = 0; i < thd_idx; i++)
|
||||||
|
if (last_threads[i] == ctx->ev.dwThreadId) break;
|
||||||
|
ok(i < thd_idx, "unexpected thread\n");
|
||||||
|
|
||||||
ok(ctx->ev.dwDebugEventCode == EXCEPTION_DEBUG_EVENT, "dwDebugEventCode = %ld\n", ctx->ev.dwDebugEventCode);
|
ok(ctx->ev.dwDebugEventCode == EXCEPTION_DEBUG_EVENT, "dwDebugEventCode = %ld\n", ctx->ev.dwDebugEventCode);
|
||||||
ok(ctx->ev.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT, "ExceptionCode = %lx\n",
|
ok(ctx->ev.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT, "ExceptionCode = %lx\n",
|
||||||
|
@ -1303,11 +1308,10 @@ static void expect_exception_(unsigned line, struct debugger_context *ctx, DWORD
|
||||||
ctx->ev.u.Exception.ExceptionRecord.ExceptionCode, exception_code);
|
ctx->ev.u.Exception.ExceptionRecord.ExceptionCode, exception_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define expect_breakpoint_exception(a,b) expect_breakpoint_exception_(__LINE__,a,b)
|
#define check_breakpoint_exception(a,b) expect_breakpoint_exception_(__LINE__,a,b)
|
||||||
static void expect_breakpoint_exception_(unsigned line, struct debugger_context *ctx, const void *expect_addr)
|
static void check_breakpoint_exception_(unsigned line, struct debugger_context *ctx, const void *expect_addr)
|
||||||
{
|
{
|
||||||
struct debuggee_thread *thread;
|
struct debuggee_thread *thread;
|
||||||
expect_exception_(line, ctx, EXCEPTION_BREAKPOINT);
|
|
||||||
if (!expect_addr) return;
|
if (!expect_addr) return;
|
||||||
ok_(__FILE__,line)(ctx->ev.u.Exception.ExceptionRecord.ExceptionAddress == expect_addr,
|
ok_(__FILE__,line)(ctx->ev.u.Exception.ExceptionRecord.ExceptionAddress == expect_addr,
|
||||||
"ExceptionAddress = %p expected %p\n", ctx->ev.u.Exception.ExceptionRecord.ExceptionAddress, expect_addr);
|
"ExceptionAddress = %p expected %p\n", ctx->ev.u.Exception.ExceptionRecord.ExceptionAddress, expect_addr);
|
||||||
|
@ -1317,6 +1321,13 @@ static void expect_breakpoint_exception_(unsigned line, struct debugger_context
|
||||||
get_ip(&thread->ctx), expect_addr);
|
get_ip(&thread->ctx), expect_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define expect_breakpoint_exception(a,b) expect_breakpoint_exception_(__LINE__,a,b)
|
||||||
|
static void expect_breakpoint_exception_(unsigned line, struct debugger_context *ctx, const void *expect_addr)
|
||||||
|
{
|
||||||
|
expect_exception_(line, ctx, EXCEPTION_BREAKPOINT);
|
||||||
|
check_breakpoint_exception_(line, ctx, expect_addr);
|
||||||
|
}
|
||||||
|
|
||||||
#define single_step(a,b,c) single_step_(__LINE__,a,b,c)
|
#define single_step(a,b,c) single_step_(__LINE__,a,b,c)
|
||||||
static void single_step_(unsigned line, struct debugger_context *ctx, struct debuggee_thread *thread, void *expect_addr)
|
static void single_step_(unsigned line, struct debugger_context *ctx, struct debuggee_thread *thread, void *expect_addr)
|
||||||
{
|
{
|
||||||
|
@ -1599,15 +1610,31 @@ static void test_debugger(const char *argv0)
|
||||||
ok(pNtResumeProcess != NULL, "pNtResumeProcess not found\n");
|
ok(pNtResumeProcess != NULL, "pNtResumeProcess not found\n");
|
||||||
if (pNtSuspendProcess && pNtResumeProcess)
|
if (pNtSuspendProcess && pNtResumeProcess)
|
||||||
{
|
{
|
||||||
|
DWORD action = DBG_REPLY_LATER;
|
||||||
status = pNtSuspendProcess(pi.hProcess);
|
status = pNtSuspendProcess(pi.hProcess);
|
||||||
ok(!status, "NtSuspendProcess failed, last error:%lu\n", GetLastError());
|
ok(!status, "NtSuspendProcess failed, last error:%lu\n", GetLastError());
|
||||||
ret = ContinueDebugEvent(ctx.ev.dwProcessId, ctx.ev.dwThreadId, DBG_REPLY_LATER);
|
do
|
||||||
|
{
|
||||||
|
ret = ContinueDebugEvent(ctx.ev.dwProcessId, ctx.ev.dwThreadId, action);
|
||||||
ok(ret, "ContinueDebugEvent failed, last error:%lu\n", GetLastError());
|
ok(ret, "ContinueDebugEvent failed, last error:%lu\n", GetLastError());
|
||||||
ok(!WaitForDebugEvent(&ctx.ev, POLL_EVENT_TIMEOUT), "WaitForDebugEvent succeeded.\n");
|
ret = WaitForDebugEvent(&ctx.ev, POLL_EVENT_TIMEOUT);
|
||||||
|
ok(!ret || ctx.ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT, "WaitForDebugEvent succeeded.\n");
|
||||||
|
if (ret) add_thread(&ctx, ctx.ev.dwThreadId);
|
||||||
|
action = DBG_CONTINUE;
|
||||||
|
} while (ret);
|
||||||
|
|
||||||
status = NtResumeThread(thread_b, NULL);
|
status = NtResumeThread(thread_b, NULL);
|
||||||
ok(!status, "NtResumeThread failed, last error:%lu\n", GetLastError());
|
ok(!status, "NtResumeThread failed, last error:%lu\n", GetLastError());
|
||||||
ok(!WaitForDebugEvent(&ctx.ev, POLL_EVENT_TIMEOUT), "WaitForDebugEvent succeeded.\n");
|
while (WaitForDebugEvent(&ctx.ev, POLL_EVENT_TIMEOUT))
|
||||||
|
{
|
||||||
|
ok(ctx.ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT, "Unexpected debug event %lx\n", ctx.ev.dwDebugEventCode);
|
||||||
|
if (ctx.ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT)
|
||||||
|
{
|
||||||
|
add_thread(&ctx, ctx.ev.dwThreadId);
|
||||||
|
ret = ContinueDebugEvent(ctx.ev.dwProcessId, ctx.ev.dwThreadId, DBG_CONTINUE);
|
||||||
|
ok(ret, "ContinueDebugEvent failed, last error:%lu\n", GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
status = pNtResumeProcess(pi.hProcess);
|
status = pNtResumeProcess(pi.hProcess);
|
||||||
ok(!status, "pNtResumeProcess failed, last error:%lu\n", GetLastError());
|
ok(!status, "pNtResumeProcess failed, last error:%lu\n", GetLastError());
|
||||||
|
@ -1739,9 +1766,11 @@ static void test_debugger(const char *argv0)
|
||||||
thread = CreateRemoteThread(pi.hProcess, NULL, 0, (void*)thread_proc, NULL, 0, &tid);
|
thread = CreateRemoteThread(pi.hProcess, NULL, 0, (void*)thread_proc, NULL, 0, &tid);
|
||||||
ok(thread != NULL, "CreateRemoteThread failed: %lu\n", GetLastError());
|
ok(thread != NULL, "CreateRemoteThread failed: %lu\n", GetLastError());
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
next_event(&ctx, WAIT_EVENT_TIMEOUT);
|
next_event(&ctx, WAIT_EVENT_TIMEOUT);
|
||||||
ok(ctx.ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT, "dwDebugEventCode = %ld\n", ctx.ev.dwDebugEventCode);
|
ok(ctx.ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT, "dwDebugEventCode = %ld\n", ctx.ev.dwDebugEventCode);
|
||||||
ok(ctx.ev.dwThreadId == tid, "Unexpected thread id\n");
|
} while (ctx.ev.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT && ctx.ev.dwThreadId != tid);
|
||||||
ok(ctx.ev.u.CreateThread.lpStartAddress == (void*)thread_proc, "Unexpected thread's start address\n");
|
ok(ctx.ev.u.CreateThread.lpStartAddress == (void*)thread_proc, "Unexpected thread's start address\n");
|
||||||
|
|
||||||
ret = CloseHandle(thread);
|
ret = CloseHandle(thread);
|
||||||
|
@ -1752,7 +1781,8 @@ static void test_debugger(const char *argv0)
|
||||||
ret = WriteProcessMemory(pi.hProcess, thread_proc + 1, &byte, 1, NULL);
|
ret = WriteProcessMemory(pi.hProcess, thread_proc + 1, &byte, 1, NULL);
|
||||||
ok(ret, "WriteProcessMemory failed: %lu\n", GetLastError());
|
ok(ret, "WriteProcessMemory failed: %lu\n", GetLastError());
|
||||||
|
|
||||||
expect_breakpoint_exception(&ctx, thread_proc + 1);
|
wait_for_breakpoint(&ctx);
|
||||||
|
check_breakpoint_exception(&ctx, thread_proc + 1);
|
||||||
exception_cnt = 1;
|
exception_cnt = 1;
|
||||||
|
|
||||||
byte = 0xc3; /* ret */
|
byte = 0xc3; /* ret */
|
||||||
|
@ -1874,7 +1904,7 @@ static void test_debugger(const char *argv0)
|
||||||
SetEvent(event);
|
SetEvent(event);
|
||||||
ResumeThread(ctx.main_thread->handle);
|
ResumeThread(ctx.main_thread->handle);
|
||||||
|
|
||||||
next_event(&ctx, 2000);
|
next_event_filter(&ctx, 2000, event_mask(CREATE_THREAD_DEBUG_EVENT));
|
||||||
ok(ctx.ev.dwDebugEventCode == EXCEPTION_DEBUG_EVENT, "dwDebugEventCode = %ld\n", ctx.ev.dwDebugEventCode);
|
ok(ctx.ev.dwDebugEventCode == EXCEPTION_DEBUG_EVENT, "dwDebugEventCode = %ld\n", ctx.ev.dwDebugEventCode);
|
||||||
ok(ctx.ev.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT, "ExceptionCode = %lx\n",
|
ok(ctx.ev.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT, "ExceptionCode = %lx\n",
|
||||||
ctx.ev.u.Exception.ExceptionRecord.ExceptionCode);
|
ctx.ev.u.Exception.ExceptionRecord.ExceptionCode);
|
||||||
|
|
Loading…
Reference in a new issue