Jacek Caban : ntdll: Call send_debug_event from debug handler on x86_64.

Alexandre Julliard julliard at winehq.org
Wed Sep 4 16:01:36 CDT 2019


Module: wine
Branch: master
Commit: 649be380b1f0c9d32cea6bfa8ac1e0a070d10543
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=649be380b1f0c9d32cea6bfa8ac1e0a070d10543

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep  4 12:47:11 2019 +0200

ntdll: Call send_debug_event from debug handler on x86_64.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/debugger.c |  2 +-
 dlls/ntdll/signal_x86_64.c     | 41 +++++++++++++++++++++++++++++++----------
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c
index c9da131..6b4e68f 100644
--- a/dlls/kernel32/tests/debugger.c
+++ b/dlls/kernel32/tests/debugger.c
@@ -1357,7 +1357,7 @@ static void test_debugger(const char *argv0)
     }
     else win_skip("call_debug_service_code not supported on this architecture\n");
 
-    if (sizeof(loop_code) > 1 && broken(1) /* FIXME: broken in Wine */)
+    if (sizeof(loop_code) > 1 && (sizeof(void*) == 8 || broken(1) /* FIXME: broken in Wine */))
     {
         memset(buf, OP_BP, sizeof(buf));
         memcpy(proc_code, &loop_code, sizeof(loop_code));
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 3079732..feb2e69 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2577,10 +2577,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
 }
 
 
-/*******************************************************************
- *		NtRaiseException (NTDLL.@)
- */
-NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
+static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
 {
     NTSTATUS status;
 
@@ -2615,8 +2612,6 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
             TRACE(" r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n",
                   context->R12, context->R13, context->R14, context->R15 );
         }
-        status = send_debug_event( rec, TRUE, context );
-        if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) goto done;
 
         /* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
         if (rec->ExceptionCode == EXCEPTION_BREAKPOINT) context->Rip--;
@@ -2647,6 +2642,24 @@ done:
 }
 
 
+/*******************************************************************
+ *		NtRaiseException (NTDLL.@)
+ */
+NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
+{
+    NTSTATUS status;
+
+    if (first_chance)
+    {
+        status = send_debug_event( rec, TRUE, context );
+        if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
+            return NtSetContextThread( GetCurrentThread(), context );
+    }
+
+    return raise_exception( rec, context, first_chance);
+}
+
+
 /**********************************************************************
  *		raise_generic_exception
  *
@@ -2763,6 +2776,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
 {
     struct stack_layout *stack = CONTAINING_RECORD( rec, struct stack_layout, rec );
     ULONG64 *rsp_ptr;
+    NTSTATUS status;
 
     if (rec->ExceptionCode == EXCEPTION_SINGLE_STEP)
     {
@@ -2782,12 +2796,19 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
         stack->context.EFlags &= ~0x100;  /* clear single-step flag */
     }
 
+    status = send_debug_event( rec, TRUE, &stack->context );
+    if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
+    {
+        restore_context( &stack->context, sigcontext );
+        return;
+    }
+
     /* store return address and %rbp without aligning, so that the offset is fixed */
     rsp_ptr = (ULONG64 *)RSP_sig(sigcontext) - 16;
-    *(--rsp_ptr) = RIP_sig(sigcontext);
-    *(--rsp_ptr) = RBP_sig(sigcontext);
-    *(--rsp_ptr) = RDI_sig(sigcontext);
-    *(--rsp_ptr) = RSI_sig(sigcontext);
+    *(--rsp_ptr) = stack->context.Rip;
+    *(--rsp_ptr) = stack->context.Rbp;
+    *(--rsp_ptr) = stack->context.Rdi;
+    *(--rsp_ptr) = stack->context.Rsi;
 
     /* now modify the sigcontext to return to the raise function */
     RIP_sig(sigcontext) = (ULONG_PTR)raise_func_trampoline;




More information about the wine-cvs mailing list