[PATCH 02/15] ntdll: Support DBG_REPLY_LATER event continuation.

Rémi Bernon rbernon at codeweavers.com
Mon Jan 27 06:07:05 CST 2020


This flag causes the debug event to be replayed after the target thread
continues. It can be used, after suspending the thread, to resume other
threads and later return to the breaking.

This will help implementing gdb continue/step packets correctly.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/ntdll/signal_arm.c     |  8 ++++++--
 dlls/ntdll/signal_arm64.c   | 15 ++++++++++++---
 dlls/ntdll/signal_i386.c    | 15 ++++++++++++---
 dlls/ntdll/signal_powerpc.c |  8 ++++++--
 dlls/ntdll/signal_x86_64.c  | 12 +++++++++---
 include/ntstatus.h          |  1 +
 include/winnt.h             |  1 +
 7 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c
index 3de6a0c45a5..a819b2a2f28 100644
--- a/dlls/ntdll/signal_arm.c
+++ b/dlls/ntdll/signal_arm.c
@@ -681,7 +681,9 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
                    context->R12, context->Sp, context->Lr, context->Pc, context->Cpsr );
         }
 
-        status = send_debug_event( rec, TRUE, context );
+        do { status = send_debug_event( rec, TRUE, context ); }
+        while (status == DBG_REPLY_LATER);
+
         if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
             return STATUS_SUCCESS;
 
@@ -694,7 +696,9 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
 
     /* last chance exception */
 
-    status = send_debug_event( rec, FALSE, context );
+    do { status = send_debug_event( rec, FALSE, context ); }
+    while (status == DBG_REPLY_LATER);
+
     if (status != DBG_CONTINUE)
     {
         if (rec->ExceptionFlags & EH_STACK_INVALID)
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index 6d72938809c..140ac7552c6 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -957,7 +957,9 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
 
     /* last chance exception */
 
-    status = send_debug_event( rec, FALSE, context );
+    do { status = send_debug_event( rec, FALSE, context ); }
+    while (status == DBG_REPLY_LATER);
+
     if (status != DBG_CONTINUE)
     {
         if (rec->ExceptionFlags & EH_STACK_INVALID)
@@ -1013,7 +1015,10 @@ static void WINAPI raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *cont
  */
 static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *stack )
 {
-    NTSTATUS status = send_debug_event( &stack->rec, TRUE, &stack->context );
+    NTSTATUS status;
+
+    do { status = send_debug_event( &stack->rec, TRUE, &stack->context ); }
+    while (status == DBG_REPLY_LATER);
 
     if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
     {
@@ -1910,7 +1915,11 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
 {
     if (first_chance)
     {
-        NTSTATUS status = send_debug_event( rec, TRUE, context );
+        NTSTATUS status;
+
+        do { status = send_debug_event( rec, TRUE, context ); }
+        while (status == DBG_REPLY_LATER);
+
         if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
             NtSetContextThread( GetCurrentThread(), context );
     }
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index e9dd0de2fc3..e69fb9b9977 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -739,7 +739,9 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
 
     /* last chance exception */
 
-    status = send_debug_event( rec, FALSE, context );
+    do { status = send_debug_event( rec, FALSE, context ); }
+    while (status == DBG_REPLY_LATER);
+
     if (status != DBG_CONTINUE)
     {
         if (rec->ExceptionFlags & EH_STACK_INVALID)
@@ -1872,7 +1874,10 @@ static void WINAPI raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *cont
  */
 static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *stack )
 {
-    NTSTATUS status = send_debug_event( &stack->rec, TRUE, &stack->context );
+    NTSTATUS status;
+
+    do { status = send_debug_event( &stack->rec, TRUE, &stack->context ); }
+    while (status == DBG_REPLY_LATER);
 
     if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
     {
@@ -2508,7 +2513,11 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
 {
     if (first_chance)
     {
-        NTSTATUS status = send_debug_event( rec, TRUE, context );
+        NTSTATUS status;
+
+        do { status = send_debug_event( rec, TRUE, context ); }
+        while (status == DBG_REPLY_LATER);
+
         if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
             NtSetContextThread( GetCurrentThread(), context );
     }
diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c
index f23265445df..d92127e1432 100644
--- a/dlls/ntdll/signal_powerpc.c
+++ b/dlls/ntdll/signal_powerpc.c
@@ -687,7 +687,9 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
             /* FIXME: dump context */
         }
 
-        status = send_debug_event( rec, TRUE, context );
+        do { status = send_debug_event( rec, TRUE, context ); }
+        while (status == DBG_REPLY_LATER);
+
         if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
             return STATUS_SUCCESS;
 
@@ -700,7 +702,9 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
 
     /* last chance exception */
 
-    status = send_debug_event( rec, FALSE, context );
+    do { status = send_debug_event( rec, FALSE, context ); }
+    while (status == DBG_REPLY_LATER);
+
     if (status != DBG_CONTINUE)
     {
         if (rec->ExceptionFlags & EH_STACK_INVALID)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 04f3854388c..c97b8a1d02f 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2567,7 +2567,9 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
 
     /* last chance exception */
 
-    status = send_debug_event( rec, FALSE, context );
+    do { status = send_debug_event( rec, FALSE, context ); }
+    while (status == DBG_REPLY_LATER);
+
     if (status != DBG_CONTINUE)
     {
         if (rec->ExceptionFlags & EH_STACK_INVALID)
@@ -2594,7 +2596,9 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
 
     if (first_chance)
     {
-        status = send_debug_event( rec, TRUE, context );
+        do { status = send_debug_event( rec, TRUE, context ); }
+        while (status == DBG_REPLY_LATER);
+
         if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
             return NtSetContextThread( GetCurrentThread(), context );
     }
@@ -2727,7 +2731,9 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
         stack->context.EFlags &= ~0x100;  /* clear single-step flag */
     }
 
-    status = send_debug_event( &stack->rec, TRUE, &stack->context );
+    do { status = send_debug_event( &stack->rec, TRUE, &stack->context ); }
+    while (status == DBG_REPLY_LATER);
+
     if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
     {
         restore_context( &stack->context, sigcontext );
diff --git a/include/ntstatus.h b/include/ntstatus.h
index 682db7a5660..1e46529262b 100644
--- a/include/ntstatus.h
+++ b/include/ntstatus.h
@@ -1408,6 +1408,7 @@
 
 #define DBG_EXCEPTION_HANDLED       ((NTSTATUS) 0x00010001)
 #define DBG_CONTINUE                ((NTSTATUS) 0x00010002)
+#define DBG_REPLY_LATER             ((NTSTATUS) 0x40010001)
 #define DBG_TERMINATE_THREAD        ((NTSTATUS) 0x40010003)
 #define DBG_TERMINATE_PROCESS       ((NTSTATUS) 0x40010004)
 #define DBG_CONTROL_C               ((NTSTATUS) 0x40010005)
diff --git a/include/winnt.h b/include/winnt.h
index 41fb6a82897..adc5d3d686c 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -651,6 +651,7 @@ typedef DWORD FLONG;
 /* status values for ContinueDebugEvent */
 #define DBG_EXCEPTION_HANDLED       ((DWORD) 0x00010001)
 #define DBG_CONTINUE                ((DWORD) 0x00010002)
+#define DBG_REPLY_LATER             ((DWORD) 0x40010001)
 #define DBG_TERMINATE_THREAD        ((DWORD) 0x40010003)
 #define DBG_TERMINATE_PROCESS       ((DWORD) 0x40010004)
 #define DBG_CONTROL_C               ((DWORD) 0x40010005)
-- 
2.25.0




More information about the wine-devel mailing list