[PATCH 5/5] winedbg: Recompute signal from debug event as needed.

Rémi Bernon rbernon at codeweavers.com
Sat Apr 4 04:30:17 CDT 2020


No real need for a context member for that as well, the mapping is
quite straightforward. It also simplifies handle_exception.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 programs/winedbg/gdbproxy.c | 69 +++++++++++++++++++------------------
 1 file changed, 36 insertions(+), 33 deletions(-)

diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index 3d605e4fd076..3903f113470e 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -101,7 +101,6 @@ struct gdb_context
     /* current Win32 trap env */
     DEBUG_EVENT                 de;
     DWORD                       de_reply;
-    unsigned                    last_sig;
     /* Win32 information */
     struct dbg_process*         process;
     /* Unix environment */
@@ -309,26 +308,28 @@ static void dbg_thread_set_single_step(struct dbg_thread *thread, BOOL enable)
         ERR("set_context failed for thread %04x:%04x\n", thread->process->pid, thread->tid);
 }
 
-static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* exc)
+static unsigned char signal_from_debug_event(DEBUG_EVENT* de)
 {
-    EXCEPTION_RECORD* rec = &exc->ExceptionRecord;
+    DWORD ec;
 
-    switch (rec->ExceptionCode)
+    if (de->dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
+        return SIGTERM;
+    if (de->dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
+        return SIGTRAP;
+
+    ec = de->u.Exception.ExceptionRecord.ExceptionCode;
+    switch (ec)
     {
     case EXCEPTION_ACCESS_VIOLATION:
     case EXCEPTION_PRIV_INSTRUCTION:
     case EXCEPTION_STACK_OVERFLOW:
     case EXCEPTION_GUARD_PAGE:
-        gdbctx->last_sig = SIGSEGV;
-        return FALSE;
+        return SIGSEGV;
     case EXCEPTION_DATATYPE_MISALIGNMENT:
-        gdbctx->last_sig = SIGBUS;
-        return FALSE;
+        return SIGBUS;
     case EXCEPTION_SINGLE_STEP:
-        /* fall through */
     case EXCEPTION_BREAKPOINT:
-        gdbctx->last_sig = SIGTRAP;
-        return FALSE;
+        return SIGTRAP;
     case EXCEPTION_FLT_DENORMAL_OPERAND:
     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
     case EXCEPTION_FLT_INEXACT_RESULT:
@@ -336,22 +337,32 @@ static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* e
     case EXCEPTION_FLT_OVERFLOW:
     case EXCEPTION_FLT_STACK_CHECK:
     case EXCEPTION_FLT_UNDERFLOW:
-        gdbctx->last_sig = SIGFPE;
-        return FALSE;
+        return SIGFPE;
     case EXCEPTION_INT_DIVIDE_BY_ZERO:
     case EXCEPTION_INT_OVERFLOW:
-        gdbctx->last_sig = SIGFPE;
-        return FALSE;
+        return SIGFPE;
     case EXCEPTION_ILLEGAL_INSTRUCTION:
-        gdbctx->last_sig = SIGILL;
-        return FALSE;
+        return SIGILL;
     case CONTROL_C_EXIT:
-        gdbctx->last_sig = SIGINT;
-        return FALSE;
+        return SIGINT;
     case STATUS_POSSIBLE_DEADLOCK:
-        /* FIXME: we could also add here a O packet with additional information */
-        gdbctx->last_sig = SIGALRM;
-        return FALSE;
+        return SIGALRM;
+    /* should not be here */
+    case EXCEPTION_INVALID_HANDLE:
+    case EXCEPTION_NAME_THREAD:
+        return SIGTRAP;
+    default:
+        ERR("Unknown exception code 0x%08x\n", ec);
+        return SIGABRT;
+    }
+}
+
+static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* exc)
+{
+    EXCEPTION_RECORD* rec = &exc->ExceptionRecord;
+
+    switch (rec->ExceptionCode)
+    {
     case EXCEPTION_NAME_THREAD:
     {
         const THREADNAME_INFO *threadname = (const THREADNAME_INFO *)rec->ExceptionInformation;
@@ -379,8 +390,6 @@ static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* e
     case EXCEPTION_INVALID_HANDLE:
         return TRUE;
     default:
-        fprintf(stderr, "Unhandled exception code 0x%08x\n", rec->ExceptionCode);
-        gdbctx->last_sig = SIGABRT;
         return FALSE;
     }
 }
@@ -486,8 +495,6 @@ static BOOL handle_debug_event(struct gdb_context* gdbctx)
 
         dbg_del_process(gdbctx->process);
         gdbctx->process = NULL;
-        /* now signal gdb that we're done */
-        gdbctx->last_sig = SIGTERM;
         return FALSE;
 
     case OUTPUT_DEBUG_STRING_EVENT:
@@ -869,8 +876,6 @@ static enum packet_return packet_reply_status(struct gdb_context* gdbctx)
 
     if (process != NULL)
     {
-        unsigned char           sig;
-
         if (!(backend = process->be_cpu)) return packet_error;
 
         if (!(thread = dbg_get_thread(process, gdbctx->de.dwThreadId)) ||
@@ -879,8 +884,7 @@ static enum packet_return packet_reply_status(struct gdb_context* gdbctx)
 
         packet_reply_open(gdbctx);
         packet_reply_add(gdbctx, "T");
-        sig = gdbctx->last_sig;
-        packet_reply_val(gdbctx, sig, 1);
+        packet_reply_val(gdbctx, signal_from_debug_event(&gdbctx->de), 1);
         packet_reply_add(gdbctx, "thread:");
         packet_reply_val(gdbctx, gdbctx->de.dwThreadId, 4);
         packet_reply_add(gdbctx, ";");
@@ -957,7 +961,7 @@ static enum packet_return packet_verbose_cont(struct gdb_context* gdbctx)
         case 'C':
         case 'S':
             if (sscanf(buf, ";%*c%2x", &sig) <= 0 ||
-                sig != gdbctx->last_sig)
+                sig != signal_from_debug_event(&gdbctx->de))
                 return packet_error;
             buf += 4;
             break;
@@ -997,7 +1001,7 @@ static enum packet_return packet_continue_signal(struct gdb_context* gdbctx)
         FIXME("Continue at address %p not supported\n", addr);
     if (n < 1) return packet_error;
 
-    if (sig != gdbctx->last_sig)
+    if (sig != signal_from_debug_event(&gdbctx->de))
     {
         ERR("Changing signals is not supported.\n");
         return packet_error;
@@ -2231,7 +2235,6 @@ static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags, unsigne
     gdbctx->exec_tid = -1;
     gdbctx->other_tid = -1;
     list_init(&gdbctx->xpoint_list);
-    gdbctx->last_sig = 0;
     gdbctx->process = NULL;
     gdbctx->no_ack_mode = FALSE;
     for (i = 0; i < ARRAY_SIZE(gdbctx->wine_segs); i++)
-- 
2.26.0




More information about the wine-devel mailing list