[PATCH 6/7] [WineDbg]: instruction pointer and frame

Eric Pouech eric.pouech at wanadoo.fr
Sat Dec 2 10:43:27 CST 2006


- now that local variable computation depends on
  instruction pointer value, be sure to have the
  relevant insn ptr value when fetching the stack
  frames
  (spotted by Peter Oberndorfer)

A+
---

 programs/winedbg/break.c      |  113 +++++++++++++++++++++--------------------
 programs/winedbg/debugger.h   |    3 +
 programs/winedbg/tgt_active.c |    5 +-
 3 files changed, 63 insertions(+), 58 deletions(-)

diff --git a/programs/winedbg/break.c b/programs/winedbg/break.c
index 3a4c1e5..c99454c 100644
--- a/programs/winedbg/break.c
+++ b/programs/winedbg/break.c
@@ -723,59 +723,31 @@ static	BOOL should_stop(int bpnum)
  * Determine if we should continue execution after a SIGTRAP signal when
  * executing in the given mode.
  */
-BOOL break_should_continue(ADDRESS64* addr, DWORD code, int* count, BOOL* is_break)
+BOOL break_should_continue(ADDRESS64* addr, DWORD code)
 {
     DWORD	        oldval = 0;
     enum dbg_exec_mode  mode = dbg_curr_thread->exec_mode;
 
-    *is_break = FALSE;
-    /* If not single-stepping, back up to the break instruction */
-    if (code == EXCEPTION_BREAKPOINT)
-        addr->Offset += be_cpu->adjust_pc_for_break(&dbg_context, TRUE);
-
-    dbg_curr_thread->stopped_xpoint = find_xpoint(addr, be_xpoint_break);
-    dbg_curr_process->bp[0].enabled = FALSE;  /* disable the step-over breakpoint */
-
-    if (dbg_curr_thread->stopped_xpoint > 0)
-    {
-        if (!should_stop(dbg_curr_thread->stopped_xpoint)) return TRUE;
-
-        dbg_printf("Stopped on breakpoint %d at ", dbg_curr_thread->stopped_xpoint);
-        print_address(&dbg_curr_process->bp[dbg_curr_thread->stopped_xpoint].addr, TRUE);
-        dbg_printf("\n");
-        return FALSE;
-    }
 
-    if(dbg_curr_thread->stopped_xpoint < 0)
-        dbg_curr_thread->stopped_xpoint = find_xpoint(addr, be_xpoint_watch_exec);
     if (dbg_curr_thread->stopped_xpoint > 0)
     {
-        /* If not single-stepping, do not back up over the break instruction */
-        if (code == EXCEPTION_BREAKPOINT)
-            addr->Offset += be_cpu->adjust_pc_for_break(&dbg_context, FALSE);
-
         if (!should_stop(dbg_curr_thread->stopped_xpoint)) return TRUE;
 
-        dbg_printf("Stopped on breakpoint %d at ", dbg_curr_thread->stopped_xpoint);
-        print_address(&dbg_curr_process->bp[dbg_curr_thread->stopped_xpoint].addr, TRUE);
-        dbg_printf("\n");
-        return FALSE;
-    }
-
-    if(dbg_curr_thread->stopped_xpoint < 0)
-        dbg_curr_thread->stopped_xpoint = find_triggered_watch(&oldval);
-    if (dbg_curr_thread->stopped_xpoint > 0)
-    {
-        /* If not single-stepping, do not back up over the break instruction */
-        if (code == EXCEPTION_BREAKPOINT)
-            addr->Offset += be_cpu->adjust_pc_for_break(&dbg_context, FALSE);
-
-        if (!should_stop(dbg_curr_thread->stopped_xpoint)) return TRUE;
-
-        dbg_printf("Stopped on watchpoint %d at ", dbg_curr_thread->stopped_xpoint);
-        print_address(addr, TRUE);
-        dbg_printf(" values: old=%lu new=%lu\n",
-                   oldval, dbg_curr_process->bp[dbg_curr_thread->stopped_xpoint].w.oldval);
+        switch (dbg_curr_process->bp[dbg_curr_thread->stopped_xpoint].xpoint_type)
+        {
+        case be_xpoint_break:
+        case be_xpoint_watch_exec:
+            dbg_printf("Stopped on breakpoint %d at ", dbg_curr_thread->stopped_xpoint);
+            print_address(&dbg_curr_process->bp[dbg_curr_thread->stopped_xpoint].addr, TRUE);
+            dbg_printf("\n");
+            break;
+        case be_xpoint_watch_read:
+        case be_xpoint_watch_write:
+            dbg_printf("Stopped on watchpoint %d at ", dbg_curr_thread->stopped_xpoint);
+            print_address(addr, TRUE);
+            dbg_printf(" values: old=%lu new=%lu\n",
+                       oldval, dbg_curr_process->bp[dbg_curr_thread->stopped_xpoint].w.oldval);
+        }
         return FALSE;
     }
 
@@ -787,16 +759,12 @@ BOOL break_should_continue(ADDRESS64* ad
     if (mode == dbg_exec_step_over_line || mode == dbg_exec_step_into_line)
     {
 	if (symbol_get_function_line_status(addr) == dbg_on_a_line_number)
-	{
-	    (*count)--;
-	}
+            dbg_curr_thread->exec_count--;
     }
     else if (mode == dbg_exec_step_over_insn || mode == dbg_exec_step_into_insn)
-    {
-	(*count)--;
-    }
+        dbg_curr_thread->exec_count--;
 
-    if (*count > 0 || mode == dbg_exec_finish)
+    if (dbg_curr_thread->exec_count > 0 || mode == dbg_exec_finish)
     {
 	/*
 	 * We still need to execute more instructions.
@@ -804,6 +772,45 @@ BOOL break_should_continue(ADDRESS64* ad
 	return TRUE;
     }
 
+    /* no breakpoint, continue if in continuous mode */
+    return mode == dbg_exec_cont || mode == dbg_exec_finish;
+}
+
+/***********************************************************************
+ *           break_ajust_pc
+ *
+ * Adjust PC to the address where the trap (if any) actually occured
+ * Also sets dbg_curr_thread->stopped_xpoint
+ */
+void break_adjust_pc(ADDRESS64* addr, DWORD code, BOOL* is_break)
+{
+    DWORD	        oldval = 0;
+
+    *is_break = FALSE;
+
+    /* If not single-stepping, back up to the break instruction */
+    if (code == EXCEPTION_BREAKPOINT)
+        addr->Offset += be_cpu->adjust_pc_for_break(&dbg_context, TRUE);
+
+    dbg_curr_thread->stopped_xpoint = find_xpoint(addr, be_xpoint_break);
+    dbg_curr_process->bp[0].enabled = FALSE;  /* disable the step-over breakpoint */
+
+    if (dbg_curr_thread->stopped_xpoint > 0) return;
+
+    if (dbg_curr_thread->stopped_xpoint < 0)
+    {
+        dbg_curr_thread->stopped_xpoint = find_xpoint(addr, be_xpoint_watch_exec);
+        if (dbg_curr_thread->stopped_xpoint < 0)
+            dbg_curr_thread->stopped_xpoint = find_triggered_watch(&oldval);
+        if (dbg_curr_thread->stopped_xpoint > 0)
+        {
+            /* If not single-stepping, do not back up over the break instruction */
+            if (code == EXCEPTION_BREAKPOINT)
+                addr->Offset += be_cpu->adjust_pc_for_break(&dbg_context, FALSE);
+            return;
+        }
+    }
+
     /* If there's no breakpoint and we are not single-stepping, then
      * either we must have encountered a break insn in the Windows program
      * or someone is trying to stop us
@@ -812,11 +819,7 @@ BOOL break_should_continue(ADDRESS64* ad
     {
         *is_break = TRUE;
         addr->Offset += be_cpu->adjust_pc_for_break(&dbg_context, FALSE);
-        return FALSE;
     }
-
-    /* no breakpoint, continue if in continuous mode */
-    return mode == dbg_exec_cont || mode == dbg_exec_finish;
 }
 
 /***********************************************************************
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 43abb60..6e4c010 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -279,7 +279,8 @@ extern void             break_delete_xpo
 extern void             break_delete_xpoints_from_module(unsigned long base);
 extern void             break_enable_xpoint(int num, BOOL enable);
 extern void             break_info(void);
-extern BOOL             break_should_continue(ADDRESS64* addr, DWORD code, int* count, BOOL* is_break);
+extern void             break_adjust_pc(ADDRESS64* addr, DWORD code, BOOL* is_break);
+extern BOOL             break_should_continue(ADDRESS64* addr, DWORD code);
 extern void             break_suspend_execution(void);
 extern void             break_restart_execution(int count);
 extern int              break_add_condition(int bpnum, struct expr* exp);
diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c
index d87f4c2..b88f6ff 100644
--- a/programs/winedbg/tgt_active.c
+++ b/programs/winedbg/tgt_active.c
@@ -143,13 +143,14 @@ static unsigned dbg_exception_prolog(BOO
     /* this will resynchronize builtin dbghelp's internal ELF module list */
     SymLoadModule(dbg_curr_process->handle, 0, 0, 0, 0, 0);
 
+    if (is_debug) break_adjust_pc(&addr, rec->ExceptionCode, &is_break);
     /*
      * Do a quiet backtrace so that we have an idea of what the situation
      * is WRT the source files.
      */
     stack_fetch_frames();
-    if (is_debug &&
-	break_should_continue(&addr, rec->ExceptionCode, &dbg_curr_thread->exec_count, &is_break))
+
+    if (is_debug && !is_break && break_should_continue(&addr, rec->ExceptionCode))
 	return FALSE;
 
     if (addr.Mode != dbg_curr_thread->addr_mode)



More information about the wine-patches mailing list