/*********************************************************************** * break_check_delayed_bp * * Check is a registered delayed BP is now available. */ void break_check_delayed_bp(void) { struct dbg_lvalue lvalue; int i; struct dbg_delayed_bp* dbp = dbg_curr_process->delayed_bp; char hexbuf[MAX_OFFSET_TO_STR_LEN]; for (i = 0; i < dbg_curr_process->num_delayed_bp; i++) { if (dbp[i].is_symbol) { if (symbol_get_lvalue(dbp[i].u.symbol.name, dbp[i].u.symbol.lineno, &lvalue, TRUE) != sglv_found) continue; if (lvalue.cookie != DLV_TARGET) continue; } else lvalue.addr = dbp[i].u.addr; WINE_TRACE("trying to add delayed %s-bp\n", dbp[i].is_symbol ? "S" : "A"); if (!dbp[i].is_symbol) WINE_TRACE("\t%04x:%s\n", dbp[i].u.addr.Segment, memory_offset_to_string(hexbuf, dbp[i].u.addr.Offset, 0)); else WINE_TRACE("\t'%s' @ %d\n", dbp[i].u.symbol.name, dbp[i].u.symbol.lineno); if (break_add_break(&lvalue.addr, FALSE, dbp[i].software_bp)) memmove(&dbp[i], &dbp[i+1], (--dbg_curr_process->num_delayed_bp - i) * sizeof(*dbp)); } }
void print_bare_address(const ADDRESS64* addr) { char hexbuf[MAX_OFFSET_TO_STR_LEN]; switch (addr->Mode) { case AddrModeFlat: dbg_printf("%s", memory_offset_to_string(hexbuf, addr->Offset, 0)); break; case AddrModeReal: case AddrMode1616: dbg_printf("0x%04x:0x%04x", addr->Segment, (unsigned) addr->Offset); break; case AddrMode1632: dbg_printf("0x%04x:%s", addr->Segment, memory_offset_to_string(hexbuf, addr->Offset, 32)); break; default: dbg_printf("Unknown mode %x\n", addr->Mode); break; } }
void dbg_wait_next_exception(DWORD cont, int count, int mode) { ADDRESS64 addr; char hexbuf[MAX_OFFSET_TO_STR_LEN]; if (cont == DBG_CONTINUE) { dbg_curr_thread->exec_count = count; dbg_curr_thread->exec_mode = mode; } dbg_resume_debuggee(cont); wait_exception(); if (!dbg_curr_process) return; memory_get_current_pc(&addr); WINE_TRACE("Entering debugger PC=%s mode=%d count=%d\n", memory_offset_to_string(hexbuf, addr.Offset, 0), dbg_curr_thread->exec_mode, dbg_curr_thread->exec_count); }
static void dbg_resume_debuggee(DWORD cont) { if (dbg_curr_thread->in_exception) { ADDRESS64 addr; char hexbuf[MAX_OFFSET_TO_STR_LEN]; dbg_exception_epilog(); memory_get_current_pc(&addr); WINE_TRACE("Exiting debugger PC=%s mode=%d count=%d\n", memory_offset_to_string(hexbuf, addr.Offset, 0), dbg_curr_thread->exec_mode, dbg_curr_thread->exec_count); if (dbg_curr_thread) { if (!SetThreadContext(dbg_curr_thread->handle, &dbg_context)) dbg_printf("Cannot set ctx on %04x\n", dbg_curr_tid); } } dbg_interactiveP = FALSE; if (!ContinueDebugEvent(dbg_curr_pid, dbg_curr_tid, cont)) dbg_printf("Cannot continue on %04x (%08x)\n", dbg_curr_tid, cont); }
/*********************************************************************** * dbg_exception_prolog * * Examine exception and decide if interactive mode is entered(return TRUE) * or exception is silently continued(return FALSE) * is_debug means the exception is a breakpoint or single step exception */ static unsigned dbg_exception_prolog(BOOL is_debug, BOOL first_chance, const EXCEPTION_RECORD* rec) { ADDRESS64 addr; BOOL is_break; char hexbuf[MAX_OFFSET_TO_STR_LEN]; memory_get_current_pc(&addr); break_suspend_execution(); dbg_curr_thread->excpt_record = *rec; dbg_curr_thread->in_exception = TRUE; if (!is_debug) { switch (addr.Mode) { case AddrModeFlat: dbg_printf(" in 32-bit code (%s)", memory_offset_to_string(hexbuf, addr.Offset, 0)); break; case AddrModeReal: dbg_printf(" in vm86 code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset); break; case AddrMode1616: dbg_printf(" in 16-bit code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset); break; case AddrMode1632: dbg_printf(" in 32-bit code (%04x:%08lx)", addr.Segment, (unsigned long) addr.Offset); break; default: dbg_printf(" bad address"); } dbg_printf(".\n"); } /* 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, first_chance, &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 && !is_break && break_should_continue(&addr, rec->ExceptionCode)) return FALSE; if (addr.Mode != dbg_curr_thread->addr_mode) { const char* name = NULL; switch (addr.Mode) { case AddrMode1616: name = "16 bit"; break; case AddrMode1632: name = "32 bit"; break; case AddrModeReal: name = "vm86"; break; case AddrModeFlat: name = "32 bit"; break; } dbg_printf("In %s mode.\n", name); dbg_curr_thread->addr_mode = addr.Mode; } display_print(); if (!is_debug) { /* This is a real crash, dump some info */ be_cpu->print_context(dbg_curr_thread->handle, &dbg_context, 0); stack_info(); be_cpu->print_segment_info(dbg_curr_thread->handle, &dbg_context); stack_backtrace(dbg_curr_tid); } else { static char* last_name; static char* last_file; char buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* si = (SYMBOL_INFO*)buffer; void* lin = memory_to_linear_addr(&addr); DWORD64 disp64; IMAGEHLP_LINE il; DWORD disp; si->SizeOfStruct = sizeof(*si); si->MaxNameLen = 256; il.SizeOfStruct = sizeof(il); if (SymFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp64, si) && SymGetLineFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp, &il)) { if ((!last_name || strcmp(last_name, si->Name)) || (!last_file || strcmp(last_file, il.FileName))) { HeapFree(GetProcessHeap(), 0, last_name); HeapFree(GetProcessHeap(), 0, last_file); last_name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(si->Name) + 1), si->Name); last_file = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(il.FileName) + 1), il.FileName); dbg_printf("%s () at %s:%u\n", last_name, last_file, il.LineNumber); } } } if (!is_debug || is_break || dbg_curr_thread->exec_mode == dbg_exec_step_over_insn || dbg_curr_thread->exec_mode == dbg_exec_step_into_insn) { ADDRESS64 tmp = addr; /* Show where we crashed */ memory_disasm_one_insn(&tmp); } source_list_from_addr(&addr, 0); return TRUE; }