boolean_t db_stop_at_pc(boolean_t *is_breakpoint) { db_addr_t pc; db_breakpoint_t bkpt; db_clear_single_step(DDB_REGS); db_clear_breakpoints(); db_clear_watchpoints(); pc = PC_REGS(DDB_REGS); #ifdef FIXUP_PC_AFTER_BREAK if (*is_breakpoint) { /* * Breakpoint trap. Fix up the PC if the * machine requires it. */ FIXUP_PC_AFTER_BREAK pc = PC_REGS(DDB_REGS); } #endif /* * Now check for a breakpoint at this address. */ bkpt = db_find_breakpoint_here(pc); if (bkpt) { if (--bkpt->count == 0) { bkpt->count = bkpt->init_count; *is_breakpoint = TRUE; return (TRUE); /* stop here */ } } else if (*is_breakpoint) { #ifdef __x86_64__ ddb_regs.tf_rip += 1; #endif } *is_breakpoint = FALSE; if (db_run_mode == STEP_INVISIBLE) { db_run_mode = STEP_CONTINUE; return (FALSE); /* continue */ } if (db_run_mode == STEP_COUNT) { return (FALSE); /* continue */ } if (db_run_mode == STEP_ONCE) { if (--db_loop_count > 0) { if (db_sstep_print) { db_printf("\t\t"); db_print_loc_and_inst(pc, DDB_REGS); db_printf("\n"); } return (FALSE); /* continue */ } } if (db_run_mode == STEP_RETURN) { db_expr_t ins = db_get_value(pc, sizeof(int), FALSE); /* continue until matching return */ if (!inst_trap_return(ins) && (!inst_return(ins) || --db_call_depth != 0)) { if (db_sstep_print) { if (inst_call(ins) || inst_return(ins)) { int i; db_printf("[after %6d] ", db_inst_count); for (i = db_call_depth; --i > 0; ) db_printf(" "); db_print_loc_and_inst(pc, DDB_REGS); db_printf("\n"); } } if (inst_call(ins)) db_call_depth++; return (FALSE); /* continue */ } } if (db_run_mode == STEP_CALLT) { db_expr_t ins = db_get_value(pc, sizeof(int), FALSE); /* continue until call or return */ if (!inst_call(ins) && !inst_return(ins) && !inst_trap_return(ins)) { return (FALSE); /* continue */ } } db_run_mode = STEP_NONE; return (TRUE); }
bool db_stop_at_pc(db_regs_t *regs, bool *is_breakpoint) { db_addr_t pc; db_breakpoint_t bkpt; pc = PC_REGS(regs); #ifdef FIXUP_PC_AFTER_BREAK if (*is_breakpoint) { /* * Breakpoint trap. Regardless if we treat this as a * real breakpoint (e.g. software single-step), fix up the PC. */ FIXUP_PC_AFTER_BREAK(regs); pc = PC_REGS(regs); } #endif #ifdef SOFTWARE_SSTEP /* * If we stopped at one of the single-step breakpoints, say it's not * really a breakpoint so that we don't skip over the real instruction. */ if (db_taken_bkpt.address == pc || db_not_taken_bkpt.address == pc) *is_breakpoint = false; #endif /* SOFTWARE_SSTEP */ db_clear_single_step(regs); db_clear_breakpoints(); db_clear_watchpoints(); /* * Now check for a breakpoint at this address. */ bkpt = db_find_breakpoint_here(pc); if (bkpt) { if (--bkpt->count == 0) { bkpt->count = bkpt->init_count; *is_breakpoint = true; return (true); /* stop here */ } } else if (*is_breakpoint) { #ifdef PC_ADVANCE PC_ADVANCE(regs); #else PC_REGS(regs) += BKPT_SIZE; #endif } *is_breakpoint = false; if (db_run_mode == STEP_INVISIBLE) { db_run_mode = STEP_CONTINUE; return (false); /* continue */ } if (db_run_mode == STEP_COUNT) { return (false); /* continue */ } if (db_run_mode == STEP_ONCE) { if (--db_loop_count > 0) { if (db_sstep_print) { db_printf("\t\t"); db_print_loc_and_inst(pc); db_printf("\n"); } return (false); /* continue */ } } if (db_run_mode == STEP_RETURN) { db_expr_t ins = db_get_value(pc, sizeof(int), false); /* continue until matching return */ if (!inst_trap_return(ins) && (!inst_return(ins) || --db_call_depth != 0)) { if (db_sstep_print) { if (inst_call(ins) || inst_return(ins)) { int i; db_printf("[after %6d] ", db_inst_count); for (i = db_call_depth; --i > 0; ) db_printf(" "); db_print_loc_and_inst(pc); db_printf("\n"); } } if (inst_call(ins)) db_call_depth++; return (false); /* continue */ } } if (db_run_mode == STEP_CALLT) { db_expr_t ins = db_get_value(pc, sizeof(int), false); /* continue until call or return */ if (!inst_call(ins) && !inst_return(ins) && !inst_trap_return(ins)) { return (false); /* continue */ } } db_run_mode = STEP_NONE; return (true); }
boolean_t db_stop_at_pc( boolean_t *is_breakpoint, task_t task, task_t space) { register db_thread_breakpoint_t bkpt; db_clear_task_single_step(DDB_REGS, space); db_clear_breakpoints(); db_clear_watchpoints(); db_stop_pc = PC_REGS(DDB_REGS); #ifdef FIXUP_PC_AFTER_BREAK if (*is_breakpoint) { /* * Breakpoint trap. Fix up the PC if the * machine requires it. */ FIXUP_PC_AFTER_BREAK db_stop_pc = PC_REGS(DDB_REGS); } #endif /* * Now check for a breakpoint at this address. */ bkpt = db_find_thread_breakpoint_here(space, db_stop_pc); if (bkpt) { if (db_cond_check(bkpt)) { *is_breakpoint = TRUE; return (TRUE); /* stop here */ } } *is_breakpoint = FALSE; if (db_run_mode == STEP_INVISIBLE) { db_run_mode = STEP_CONTINUE; return (FALSE); /* continue */ } if (db_run_mode == STEP_COUNT) { return (FALSE); /* continue */ } if (db_run_mode == STEP_ONCE) { if (--db_loop_count > 0) { if (db_sstep_print) { db_print_loc_and_inst(db_stop_pc, task); } return (FALSE); /* continue */ } } if (db_run_mode == STEP_RETURN) { jmp_buf_t *prev; jmp_buf_t db_jmpbuf; /* WARNING: the following assumes an instruction fits an int */ db_expr_t ins; ins = db_get_task_value(db_stop_pc, sizeof(int), FALSE, space); /* continue until matching return */ prev = db_recover; if (_setjmp(db_recover = &db_jmpbuf) == 0) { if (!inst_trap_return(ins) && (!inst_return(ins) || --db_call_depth != 0)) { if (db_sstep_print) { if (inst_call(ins) || inst_return(ins)) { register int i; db_printf("[after %6d /%4d] ", db_inst_count, db_inst_count - db_last_inst_count); db_last_inst_count = db_inst_count; for (i = db_call_depth; --i > 0; ) db_printf(" "); db_print_loc_and_inst(db_stop_pc, task); db_printf("\n"); } } if (inst_call(ins)) db_call_depth++; db_recover = prev; if (db_step_again()) return (FALSE); /* continue */ } } db_recover = prev; } if (db_run_mode == STEP_CALLT) { /* WARNING: the following assumes an instruction fits an int */ db_expr_t ins; ins = db_get_task_value(db_stop_pc, sizeof(int), FALSE, space); /* continue until call or return */ if (!inst_call(ins) && !inst_return(ins) && !inst_trap_return(ins)) { if (db_step_again()) return (FALSE); /* continue */ } } if (db_find_breakpoint_here(space, db_stop_pc)) return(FALSE); db_run_mode = STEP_NONE; return (TRUE); }
boolean_t db_stop_at_pc(db_regs_t *regs, boolean_t *is_breakpoint) { db_addr_t pc, old_pc; db_breakpoint_t bkpt; db_clear_breakpoints(); db_clear_watchpoints(); old_pc = pc = PC_REGS(regs); #ifdef FIXUP_PC_AFTER_BREAK if (*is_breakpoint) { /* * Breakpoint trap. Fix up the PC if the * machine requires it. */ FIXUP_PC_AFTER_BREAK(regs); pc = PC_REGS(regs); } #endif /* * Now check for a breakpoint at this address. */ bkpt = db_find_breakpoint_here(pc); if (bkpt) { if (--bkpt->count == 0) { db_clear_single_step(regs); bkpt->count = bkpt->init_count; *is_breakpoint = TRUE; return (TRUE); /* stop here */ } } else if (*is_breakpoint #ifdef SOFTWARE_SSTEP && !((db_taken_bkpt && db_taken_bkpt->address == pc) || (db_not_taken_bkpt && db_not_taken_bkpt->address == pc)) #endif ) { #ifdef PC_ADVANCE PC_ADVANCE(regs); #else # ifdef SET_PC_REGS SET_PC_REGS(regs, old_pc); # else PC_REGS(regs) = old_pc; # endif #endif } db_clear_single_step(regs); *is_breakpoint = FALSE; if (db_run_mode == STEP_INVISIBLE) { db_run_mode = STEP_CONTINUE; return (FALSE); /* continue */ } if (db_run_mode == STEP_COUNT) { return (FALSE); /* continue */ } if (db_run_mode == STEP_ONCE) { if (--db_loop_count > 0) { if (db_sstep_print) { db_printf("\t\t"); db_print_loc_and_inst(pc); db_printf("\n"); } return (FALSE); /* continue */ } } if (db_run_mode == STEP_RETURN) { db_expr_t ins = db_get_value(pc, sizeof(int), FALSE); /* continue until matching return */ if (!inst_trap_return(ins) && (!inst_return(ins) || --db_call_depth != 0)) { if (db_sstep_print) { if (inst_call(ins) || inst_return(ins)) { int i; db_printf("[after %6d] ", db_inst_count); for (i = db_call_depth; --i > 0; ) db_printf(" "); db_print_loc_and_inst(pc); db_printf("\n"); } } if (inst_call(ins)) db_call_depth++; return (FALSE); /* continue */ } } if (db_run_mode == STEP_CALLT) { db_expr_t ins = db_get_value(pc, sizeof(int), FALSE); /* continue until call or return */ if (!inst_call(ins) && !inst_return(ins) && !inst_trap_return(ins)) { return (FALSE); /* continue */ } } db_run_mode = STEP_NONE; return (TRUE); }