[PATCH v3 1/2] kernel32/tests: Add tests for ContinueDebugEvent with DBG_REPLY_LATER.
Rémi Bernon
rbernon at codeweavers.com
Fri Feb 21 02:25:15 CST 2020
On 2/20/20 6:06 PM, Rémi Bernon wrote:
> Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
> ---
> dlls/kernel32/tests/debugger.c | 62 +++++++++++++++++++++++++++++++++-
> 1 file changed, 61 insertions(+), 1 deletion(-)
>
> diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c
> index a2b5d1f410e..7fe4f872282 100644
> --- a/dlls/kernel32/tests/debugger.c
> +++ b/dlls/kernel32/tests/debugger.c
> @@ -309,6 +309,56 @@ static void fetch_process_context(struct debugger_context *ctx)
> #define WAIT_EVENT_TIMEOUT 20000
> #define POLL_EVENT_TIMEOUT 200
>
> +#define test_reply_later(a) test_reply_later_(__LINE__,a)
> +static void test_reply_later_(unsigned int line, struct debugger_context *ctx)
> +{
> + DEBUG_EVENT de0, de1;
> + HANDLE thread;
> + NTSTATUS status;
> +
> + if (!ContinueDebugEvent(ctx->ev.dwProcessId, ctx->ev.dwThreadId, DBG_REPLY_LATER))
> + todo_wine win_skip("Skipping unsupported DBG_REPLY_LATER tests\n");
> + else
> + {
> + ok_(__FILE__,line)(WaitForDebugEvent(&de0, 50), "WaitForDebugEvent failed, last error:%u\n", GetLastError());
> + ok_(__FILE__,line)(ctx->ev.dwDebugEventCode == de0.dwDebugEventCode,
> + "delayed event differ, code:%x was:%x\n", de0.dwDebugEventCode, ctx->ev.dwDebugEventCode);
> + ok_(__FILE__,line)(ctx->ev.dwProcessId == de0.dwProcessId,
> + "delayed event differ, pid:%x was:%x\n", de0.dwProcessId, ctx->ev.dwProcessId);
> + ok_(__FILE__,line)(ctx->ev.dwThreadId == de0.dwThreadId,
> + "delayed event differ, tid:%x was:%x\n", de0.dwThreadId, ctx->ev.dwThreadId);
> +
> + if (ctx->ev.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT &&
> + ctx->ev.dwDebugEventCode != CREATE_THREAD_DEBUG_EVENT &&
> + ctx->ev.dwDebugEventCode != EXIT_THREAD_DEBUG_EVENT &&
> + ctx->ev.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT)
> + {
> + thread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, ctx->ev.dwThreadId);
> + ok_(__FILE__,line)(thread != INVALID_HANDLE_VALUE, "OpenThread failed, last error:%u\n", GetLastError());
> +
> + status = NtSuspendThread(thread, NULL);
> + ok_(__FILE__,line)(!status, "NtSuspendThread failed, last error:%u\n", GetLastError());
> +
> + ok_(__FILE__,line)(ContinueDebugEvent(ctx->ev.dwProcessId, ctx->ev.dwThreadId, DBG_REPLY_LATER),
> + "ContinueDebugEvent failed, last error:%u\n", GetLastError());
> +
> + ok_(__FILE__,line)(!WaitForDebugEvent(&de1, 50), "WaitForDebugEvent succeeded.\n");
> + status = NtResumeThread(thread, NULL);
> +
> + ok_(__FILE__,line)(!status, "NtResumeThread failed, last error:%u\n", GetLastError());
> + CloseHandle(thread);
> +
> + ok_(__FILE__,line)(WaitForDebugEvent(&de1, 50), "WaitForDebugEvent failed, last error:%u\n", GetLastError());
> + ok_(__FILE__,line)(ctx->ev.dwDebugEventCode == de1.dwDebugEventCode,
> + "delayed event differ, code:%x was:%x\n", de1.dwDebugEventCode, ctx->ev.dwDebugEventCode);
> + ok_(__FILE__,line)(ctx->ev.dwProcessId == de1.dwProcessId,
> + "delayed event differ, pid:%x was:%x\n", de1.dwProcessId, ctx->ev.dwProcessId);
> + ok_(__FILE__,line)(ctx->ev.dwThreadId == de1.dwThreadId,
> + "delayed event differ, tid:%x was:%x\n", de1.dwThreadId, ctx->ev.dwThreadId);
> + }
> + }
> +}
> +
> #define next_event(a,b) next_event_(__LINE__,a,b)
> static void next_event_(unsigned line, struct debugger_context *ctx, unsigned timeout)
> {
> @@ -1273,7 +1323,11 @@ static void test_debugger(const char *argv0)
> next_event(&ctx, WAIT_EVENT_TIMEOUT);
> ok(ctx.ev.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT, "dwDebugEventCode = %d\n", ctx.ev.dwDebugEventCode);
> wait_for_breakpoint(&ctx);
> - do next_event(&ctx, POLL_EVENT_TIMEOUT);
> + do
> + {
> + test_reply_later(&ctx);
> + next_event(&ctx, POLL_EVENT_TIMEOUT);
> + }
> while(ctx.ev.dwDebugEventCode != -1);
>
> mem = VirtualAllocEx(pi.hProcess, NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
> @@ -1297,6 +1351,7 @@ static void test_debugger(const char *argv0)
> debuggee_thread = get_debuggee_thread(&ctx, ctx.ev.dwThreadId);
>
> wait_for_breakpoint(&ctx);
> + test_reply_later(&ctx);
> fetch_thread_context(debuggee_thread);
> ok(ctx.ev.u.Exception.ExceptionRecord.ExceptionAddress == thread_proc,
> "ExceptionAddress = %p\n", ctx.ev.u.Exception.ExceptionRecord.ExceptionAddress);
> @@ -1304,8 +1359,11 @@ static void test_debugger(const char *argv0)
> get_ip(&debuggee_thread->ctx));
>
> single_step(&ctx, debuggee_thread, thread_proc + 2);
> + test_reply_later(&ctx);
> single_step(&ctx, debuggee_thread, thread_proc + 3);
> + test_reply_later(&ctx);
> single_step(&ctx, debuggee_thread, thread_proc);
> + test_reply_later(&ctx);
>
> byte = 0xc3; /* ret */
> ret = WriteProcessMemory(pi.hProcess, thread_proc, &byte, 1, NULL);
> @@ -1328,6 +1386,7 @@ static void test_debugger(const char *argv0)
> ok(thread != NULL, "CreateRemoteThread failed: %u\n", GetLastError());
> expect_event(&ctx, CREATE_THREAD_DEBUG_EVENT);
> expect_breakpoint_exception(&ctx, NULL);
> + test_reply_later(&ctx);
> expect_event(&ctx, EXIT_THREAD_DEBUG_EVENT);
>
> /* BREAKPOINT_PROMPT */
> @@ -1422,6 +1481,7 @@ static void test_debugger(const char *argv0)
>
> do
> {
> + test_reply_later(&ctx);
> next_event(&ctx, WAIT_EVENT_TIMEOUT);
> ok (ctx.ev.dwDebugEventCode != EXCEPTION_DEBUG_EVENT, "got exception\n");
> }
>
I wanted to avoid the multithread scenario where another thread may
raise an exception when they are resumed, but it looks like I may have
missed some Windows quirks that occur on w1064 tests... The other
failures are preexisting afaics.
--
Rémi Bernon <rbernon at codeweavers.com>
More information about the wine-devel
mailing list