[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