diff --git a/programs/winedbg/break.c b/programs/winedbg/break.c index 3a4c1e57056..c99454c06b2 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* addr, DWORD code, int* count, BOOL* is_bre 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* addr, DWORD code, int* count, BOOL* is_bre 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* addr, DWORD code, int* count, BOOL* is_bre { *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 43abb6020d4..6e4c010f260 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -279,7 +279,8 @@ extern void break_delete_xpoint(int num); 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 d87f4c20552..b88f6ff2ef0 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -143,13 +143,14 @@ static unsigned dbg_exception_prolog(BOOL is_debug, const EXCEPTION_RECORD* rec) /* 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)