/* * kdb_trap - field a TRACE or BPT trap */ int kdb_trap(int type, db_regs_t *regs) { int s; switch (type) { case T_BREAKPOINT: /* breakpoint */ case -1: /* keyboard interrupt */ break; default: if (db_recover != 0) { /* This will longjmp back into db_command_loop() */ db_error("Faulted in DDB; continuing...\n"); /*NOTREACHED*/ } } /* Should switch to kdb`s own stack here. */ ddb_regs = *regs; s = splhigh(); db_active++; cnpollc(TRUE); db_trap(type, 0/*code*/); cnpollc(FALSE); db_active--; splx(s); *regs = ddb_regs; return (1); }
/* * db_ktrap - field a TRACE or BPT trap */ int db_ktrap(int type, int code, db_regs_t *regs) { int s; #if NWSDISPLAY > 0 wsdisplay_switchtoconsole(); #endif switch (type) { case T_BPTFLT: /* breakpoint */ case T_TRCTRAP: /* single_step */ case T_NMI: /* NMI */ case -1: /* keyboard interrupt */ break; default: if (!db_panic) return (0); db_printtrap(type, code); if (db_recover != 0) { db_error("Faulted in DDB; continuing...\n"); /*NOTREACHED*/ } } #ifdef MULTIPROCESSOR mtx_enter(&ddb_mp_mutex); if (ddb_state == DDB_STATE_EXITING) ddb_state = DDB_STATE_NOT_RUNNING; mtx_leave(&ddb_mp_mutex); while (db_enter_ddb()) { #endif ddb_regs = *regs; ddb_regs.tf_cs &= 0xffff; ddb_regs.tf_ss &= 0xffff; s = splhigh(); db_active++; cnpollc(TRUE); db_trap(type, code); cnpollc(FALSE); db_active--; splx(s); *regs = ddb_regs; #ifdef MULTIPROCESSOR if (!db_switch_cpu) ddb_state = DDB_STATE_EXITING; } #endif return (1); }
/* * kdb_trap - field a TRACE or BPT trap * Return non-zero if we "handled" the trap. */ int kdb_trap(int type, db_regs_t *regs) { switch (type) { case T_TRACE: /* single-step */ case T_BREAKPOINT: /* breakpoint */ /* case T_WATCHPOINT:*/ break; case -1: break; default: kdbprinttrap(type, 0); if (db_recover != 0) { /* This will longjmp back to db_command_loop */ db_error("Caught exception in ddb.\n"); /*NOTREACHED*/ } /* * Tell caller "We did NOT handle the trap." * Caller should panic or whatever. */ return 0; } /* * We'd like to be on a separate debug stack here, but * that's easier to do in locore.s before we get here. * See sun3/locore.s:T_TRACE for stack switch code. */ ddb_regs = *regs; db_active++; cnpollc(true); /* set polling mode, unblank video */ db_trap(type, 0); /* where the work happens */ cnpollc(false); /* resume interrupt mode */ db_active--; *regs = ddb_regs; /* * Indicate that single_step is for KDB. * But lock out interrupts to prevent TRACE_KDB from setting the * trace bit in the current SR (and trapping while exiting KDB). */ (void)spl7(); /* * Tell caller "We HAVE handled the trap." * Caller will return to locore and rte. */ return 1; }
int kdb_trap(int type, int code, db_regs_t *regs) { int s; switch (type) { case EXPEVT_TRAPA: /* FALLTHROUGH */ case EXPEVT_BREAK: break; default: if (!db_onpanic && db_recover == NULL) return 0; kdb_printtrap(type, code); if (db_recover != NULL) { db_printf("[pc %x, pr %x]: ", regs->tf_spc, regs->tf_pr); db_error("Faulted in DDB; continuing...\n"); /*NOTREACHED*/ } } /* XXX: Should switch to ddb's own stack here. */ ddb_regs = *regs; s = splhigh(); db_active++; cnpollc(true); db_trap(type, code); cnpollc(false); db_active--; splx(s); *regs = ddb_regs; return 1; }
int kdb_trap(int type, int code, db_regs_t *regs) { extern label_t *db_recover; int s; switch (type) { case EXPEVT_TRAPA: /* trapa instruction */ case EXPEVT_BREAK: /* UBC */ case -1: /* keyboard interrupt */ break; default: if (!db_panic && db_recover == NULL) return 0; kdb_printtrap(type, code); if (db_recover != NULL) { db_error("Faulted in DDB; continuing...\n"); /*NOTREACHED*/ } } /* XXX Should switch to kdb's own stack here. */ ddb_regs = *regs; s = splhigh(); db_active++; cnpollc(TRUE); db_trap(type, code); cnpollc(FALSE); db_active--; splx(s); *regs = ddb_regs; return 1; }
int ddb_trap_glue(struct trapframe *frame) { if (!(frame->srr1 & PSL_PR) && (frame->exc == EXC_TRC || (frame->exc == EXC_PGM && (frame->srr1 & 0x20000)) || frame->exc == EXC_BPT)) { bcopy(frame->fixreg, DDB_REGS->tf.fixreg, 32 * sizeof(u_int32_t)); DDB_REGS->tf.srr0 = frame->srr0; DDB_REGS->tf.srr1 = frame->srr1; cnpollc(TRUE); db_trap(T_BREAKPOINT, 0); cnpollc(FALSE); bcopy(DDB_REGS->tf.fixreg, frame->fixreg, 32 * sizeof(u_int32_t)); return 1; } return 0; }
int kdb_trap(int type, void *v) { struct trapframe *frame = v; #ifdef DDB if (db_recover != 0 && (type != -1 && type != T_BREAKPOINT)) { db_error("Faulted in DDB; continuing...\n"); /* NOTREACHED */ } #endif /* XXX Should switch to kdb's own stack here. */ memcpy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t)); DDB_REGS->iar = frame->srr0; DDB_REGS->msr = frame->srr1; DDB_REGS->lr = frame->lr; DDB_REGS->ctr = frame->ctr; DDB_REGS->cr = frame->cr; DDB_REGS->xer = frame->xer; #ifdef PPC_OEA DDB_REGS->mq = frame->tf_xtra[TF_MQ]; #endif #ifdef PPC_IBM4XX DDB_REGS->dear = frame->dar; DDB_REGS->esr = frame->tf_xtra[TF_ESR]; DDB_REGS->pid = frame->tf_xtra[TF_PID]; #endif #ifdef DDB db_active++; cnpollc(1); db_trap(type, 0); cnpollc(0); db_active--; #elif defined(KGDB) if (!kgdb_trap(type, DDB_REGS)) return 0; #endif /* KGDB isn't smart about advancing PC if we * take a breakpoint trap after kgdb_active is set. * Therefore, we help out here. */ if (IS_BREAKPOINT_TRAP(type, 0)) { int bkpt; db_read_bytes(PC_REGS(DDB_REGS),BKPT_SIZE,(void *)&bkpt); if (bkpt== BKPT_INST) { PC_REGS(DDB_REGS) += BKPT_SIZE; } } memcpy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t)); frame->srr0 = DDB_REGS->iar; frame->srr1 = DDB_REGS->msr; frame->lr = DDB_REGS->lr; frame->ctr = DDB_REGS->ctr; frame->cr = DDB_REGS->cr; frame->xer = DDB_REGS->xer; #ifdef PPC_OEA frame->tf_xtra[TF_MQ] = DDB_REGS->mq; #endif #ifdef PPC_IBM4XX frame->dar = DDB_REGS->dear; frame->tf_xtra[TF_ESR] = DDB_REGS->esr; frame->tf_xtra[TF_PID] = DDB_REGS->pid; #endif return 1; }
/* * kdb_trap - field a TRACE or BPT trap */ int kdb_trap(int type, struct trapframe64 *tf) { int s; extern int trap_trace_dis; extern int doing_shutdown; trap_trace_dis++; doing_shutdown++; #if NFB > 0 fb_unblank(); #endif switch (type) { case T_BREAKPOINT: /* breakpoint */ break; case -1: /* keyboard interrupt */ printf("kdb tf=%p\n", tf); break; default: if (!db_onpanic && db_recover==0) return (0); printf("kernel trap %x: %s\n", type, trap_type[type & 0x1ff]); if (db_recover != 0) { prom_abort(); db_error("Faulted in DDB; continuing...\n"); prom_abort(); /*NOTREACHED*/ } db_recover = (label_t *)1; } /* Should switch to kdb`s own stack here. */ write_all_windows(); #if defined(MULTIPROCESSOR) if (!db_suspend_others()) { ddb_suspend(tf); return 1; } #endif /* Initialise local dbregs storage from trap frame */ fill_ddb_regs_from_tf(tf); s = splhigh(); db_active++; cnpollc(TRUE); /* Need to do spl stuff till cnpollc works */ db_dump_ts(0, 0, 0, 0); db_trap(type, 0/*code*/); ddb_restore_state(); cnpollc(FALSE); db_active--; splx(s); *tf = DDB_REGS->db_tf; curcpu()->ci_ddb_regs = NULL; trap_trace_dis--; doing_shutdown--; #if defined(MULTIPROCESSOR) db_resume_others(); #endif return (1); }
/* * kdb_trap - field a TRACE or BPT trap */ int kdb_trap(int type, int code, struct x86_64_saved_state *regs) { volatile int ddb_mode = !(boothowto & RB_GDB); /* * XXX try to do nothing if the console is in graphics mode. * Handle trace traps (and hardware breakpoints...) by ignoring * them except for forgetting about them. Return 0 for other * traps to say that we haven't done anything. The trap handler * will usually panic. We should handle breakpoint traps for * our breakpoints by disarming our breakpoints and fixing up * %eip. */ if (cons_unavail && ddb_mode) { if (type == T_TRCTRAP) { regs->tf_rflags &= ~PSL_T; return (1); } return (0); } switch (type) { case T_BPTFLT: /* breakpoint */ case T_TRCTRAP: /* debug exception */ break; default: /* * XXX this is almost useless now. In most cases, * trap_fatal() has already printed a much more verbose * message. However, it is dangerous to print things in * trap_fatal() - kprintf() might be reentered and trap. * The debugger should be given control first. */ if (ddb_mode) db_printf("kernel: type %d trap, code=%x\n", type, code); if (db_nofault) { jmp_buf *no_fault = db_nofault; db_nofault = NULL; longjmp(*no_fault, 1); } } /* * This handles unexpected traps in ddb commands, including calls to * non-ddb functions. db_nofault only applies to memory accesses by * internal ddb commands. */ if (db_global_jmpbuf_valid) longjmp(db_global_jmpbuf, 1); /* * XXX We really should switch to a local stack here. */ ddb_regs = *regs; crit_enter(); db_printf("\nCPU%d stopping CPUs: 0x%016jx\n", mycpu->gd_cpuid, (uintmax_t)CPUMASK_LOWMASK(mycpu->gd_other_cpus)); /* We stop all CPUs except ourselves (obviously) */ stop_cpus(mycpu->gd_other_cpus); db_printf(" stopped\n"); setjmp(db_global_jmpbuf); db_global_jmpbuf_valid = TRUE; db_active++; vcons_set_mode(1); if (ddb_mode) { cndbctl(TRUE); db_trap(type, code); cndbctl(FALSE); } else gdb_handle_exception(&ddb_regs, type, code); db_active--; vcons_set_mode(0); db_global_jmpbuf_valid = FALSE; db_printf("\nCPU%d restarting CPUs: 0x%016jx\n", mycpu->gd_cpuid, (uintmax_t)CPUMASK_LOWMASK(stopped_cpus)); /* Restart all the CPUs we previously stopped */ if (CPUMASK_CMPMASKNEQ(stopped_cpus, mycpu->gd_other_cpus)) { db_printf("whoa, other_cpus: 0x%016jx, " "stopped_cpus: 0x%016jx\n", (uintmax_t)CPUMASK_LOWMASK(mycpu->gd_other_cpus), (uintmax_t)CPUMASK_LOWMASK(stopped_cpus)); panic("stop_cpus() failed"); } restart_cpus(stopped_cpus); db_printf(" restarted\n"); crit_exit(); regs->tf_rip = ddb_regs.tf_rip; regs->tf_rflags = ddb_regs.tf_rflags; regs->tf_rax = ddb_regs.tf_rax; regs->tf_rcx = ddb_regs.tf_rcx; regs->tf_rdx = ddb_regs.tf_rdx; regs->tf_rbx = ddb_regs.tf_rbx; regs->tf_rsp = ddb_regs.tf_rsp; regs->tf_ss = ddb_regs.tf_ss & 0xffff; regs->tf_rbp = ddb_regs.tf_rbp; regs->tf_rsi = ddb_regs.tf_rsi; regs->tf_rdi = ddb_regs.tf_rdi; regs->tf_r8 = ddb_regs.tf_r8; regs->tf_r9 = ddb_regs.tf_r9; regs->tf_r10 = ddb_regs.tf_r10; regs->tf_r11 = ddb_regs.tf_r11; regs->tf_r12 = ddb_regs.tf_r12; regs->tf_r13 = ddb_regs.tf_r13; regs->tf_r14 = ddb_regs.tf_r14; regs->tf_r15 = ddb_regs.tf_r15; /* regs->tf_es = ddb_regs.tf_es & 0xffff; */ /* regs->tf_fs = ddb_regs.tf_fs & 0xffff; */ /* regs->tf_gs = ddb_regs.tf_gs & 0xffff; */ regs->tf_cs = ddb_regs.tf_cs & 0xffff; /* regs->tf_ds = ddb_regs.tf_ds & 0xffff; */ return (1); }
/* * kdb_trap - field a TRACE or BPT trap */ int kdb_trap(int type, int code, struct i386_saved_state *regs) { volatile int ddb_mode = !(boothowto & RB_GDB); /* * XXX try to do nothing if the console is in graphics mode. * Handle trace traps (and hardware breakpoints...) by ignoring * them except for forgetting about them. Return 0 for other * traps to say that we haven't done anything. The trap handler * will usually panic. We should handle breakpoint traps for * our breakpoints by disarming our breakpoints and fixing up * %eip. */ if (cons_unavail && ddb_mode) { if (type == T_TRCTRAP) { regs->tf_eflags &= ~PSL_T; return (1); } return (0); } switch (type) { case T_BPTFLT: /* breakpoint */ case T_TRCTRAP: /* debug exception */ break; default: /* * XXX this is almost useless now. In most cases, * trap_fatal() has already printed a much more verbose * message. However, it is dangerous to print things in * trap_fatal() - kprintf() might be reentered and trap. * The debugger should be given control first. */ if (ddb_mode) db_printf("kernel: type %d trap, code=%x\n", type, code); if (db_nofault) { jmp_buf *no_fault = db_nofault; db_nofault = NULL; longjmp(*no_fault, 1); } } /* * This handles unexpected traps in ddb commands, including calls to * non-ddb functions. db_nofault only applies to memory accesses by * internal ddb commands. */ if (db_global_jmpbuf_valid) longjmp(db_global_jmpbuf, 1); /* * XXX We really should switch to a local stack here. */ ddb_regs = *regs; /* * If in kernel mode, esp and ss are not saved, so dummy them up. */ if (ISPL(regs->tf_cs) == 0) { ddb_regs.tf_esp = (int)®s->tf_esp; ddb_regs.tf_ss = rss(); } crit_enter(); #ifdef SMP db_printf("\nCPU%d stopping CPUs: 0x%08x\n", mycpu->gd_cpuid, mycpu->gd_other_cpus); /* We stop all CPUs except ourselves (obviously) */ stop_cpus(mycpu->gd_other_cpus); db_printf(" stopped\n"); #endif /* SMP */ setjmp(db_global_jmpbuf); db_global_jmpbuf_valid = TRUE; db_active++; if (ddb_mode) { cndbctl(TRUE); db_trap(type, code); cndbctl(FALSE); } else gdb_handle_exception(&ddb_regs, type, code); db_active--; db_global_jmpbuf_valid = FALSE; #ifdef SMP db_printf("\nCPU%d restarting CPUs: 0x%08x\n", mycpu->gd_cpuid, stopped_cpus); /* Restart all the CPUs we previously stopped */ if (stopped_cpus != mycpu->gd_other_cpus) { db_printf("whoa, other_cpus: 0x%08x, stopped_cpus: 0x%08x\n", mycpu->gd_other_cpus, stopped_cpus); panic("stop_cpus() failed"); } restart_cpus(stopped_cpus); db_printf(" restarted\n"); #endif /* SMP */ crit_exit(); regs->tf_eip = ddb_regs.tf_eip; regs->tf_eflags = ddb_regs.tf_eflags; regs->tf_eax = ddb_regs.tf_eax; regs->tf_ecx = ddb_regs.tf_ecx; regs->tf_edx = ddb_regs.tf_edx; regs->tf_ebx = ddb_regs.tf_ebx; /* * If in user mode, the saved ESP and SS were valid, restore them. */ if (ISPL(regs->tf_cs)) { regs->tf_esp = ddb_regs.tf_esp; regs->tf_ss = ddb_regs.tf_ss & 0xffff; } regs->tf_ebp = ddb_regs.tf_ebp; regs->tf_esi = ddb_regs.tf_esi; regs->tf_edi = ddb_regs.tf_edi; regs->tf_es = ddb_regs.tf_es & 0xffff; regs->tf_fs = ddb_regs.tf_fs & 0xffff; regs->tf_gs = ddb_regs.tf_gs & 0xffff; regs->tf_cs = ddb_regs.tf_cs & 0xffff; regs->tf_ds = ddb_regs.tf_ds & 0xffff; return (1); }
/* * kdb_trap - field a TRACE or BPT trap */ int kdb_trap(int type, struct trapframe *tf) { db_regs_t dbregs; int s; #if NFB > 0 fb_unblank(); #endif switch (type) { case T_BREAKPOINT: /* breakpoint */ case -1: /* keyboard interrupt */ break; default: if (!db_onpanic && db_recover==0) return (0); printf("kernel: %s trap\n", trap_type[type & 0xff]); if (db_recover != 0) { db_error("Faulted in DDB; continuing...\n"); /*NOTREACHED*/ } } #ifdef MULTIPROCESSOR if (!db_suspend_others()) { ddb_suspend(tf); return 1; } #endif /* Initialise local dbregs storage from trap frame */ dbregs.db_tf = *tf; dbregs.db_fr = *(struct frame *)tf->tf_out[6]; /* Setup current CPU & reg pointers */ ddb_cpuinfo = curcpu(); curcpu()->ci_ddb_regs = ddb_regp = &dbregs; /* Should switch to kdb`s own stack here. */ s = splhigh(); db_active++; cnpollc(true); db_trap(type, 0/*code*/); cnpollc(false); db_active--; splx(s); /* Update trap frame from local dbregs storage */ *(struct frame *)tf->tf_out[6] = dbregs.db_fr; *tf = dbregs.db_tf; curcpu()->ci_ddb_regs = ddb_regp = 0; ddb_cpuinfo = NULL; #ifdef MULTIPROCESSOR db_resume_others(); #endif return (1); }
/* * ddb_trap - field a kernel trap */ int kdb_trap(int vector, struct trapframe *regs) { int ddb_mode = !(boothowto & RB_GDB); register_t s; /* * Don't bother checking for usermode, since a benign entry * by the kernel (call to Debugger() or a breakpoint) has * already checked for usermode. If neither of those * conditions exist, something Bad has happened. */ if (vector != IA64_VEC_BREAK && vector != IA64_VEC_SINGLE_STEP_TRAP) { #if 0 if (ddb_mode) { db_printf("ddbprinttrap from 0x%lx\n", /* XXX */ regs->tf_regs[FRAME_PC]); ddbprinttrap(a0, a1, a2, entry); /* * Tell caller "We did NOT handle the trap." * Caller should panic, or whatever. */ return (0); } #endif if (db_nofault) { jmp_buf *no_fault = db_nofault; db_nofault = 0; longjmp(*no_fault, 1); } } /* * XXX Should switch to DDB's own stack, here. */ s = intr_disable(); #ifdef SMP #ifdef CPUSTOP_ON_DDBBREAK #if defined(VERBOSE_CPUSTOP_ON_DDBBREAK) db_printf("CPU%d stopping CPUs: 0x%08x...", PCPU_GET(cpuid), PCPU_GET(other_cpus)); #endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */ /* We stop all CPUs except ourselves (obviously) */ stop_cpus(PCPU_GET(other_cpus)); #if defined(VERBOSE_CPUSTOP_ON_DDBBREAK) db_printf(" stopped.\n"); #endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */ #endif /* CPUSTOP_ON_DDBBREAK */ #endif /* SMP */ ddb_regs = *regs; /* * XXX pretend that registers outside the current frame don't exist. */ db_eregs = db_regs + DB_MISC_REGS + 8 + 32 + (ddb_regs.tf_cr_ifs & 0x7f); __asm __volatile("flushrs"); /* so we can look at them */ db_active++; if (ddb_mode) { cndbctl(TRUE); /* DDB active, unblank video */ db_trap(vector, 0); /* Where the work happens */ cndbctl(FALSE); /* DDB inactive */ } else gdb_handle_exception(&ddb_regs, vector); db_active--; #ifdef SMP #ifdef CPUSTOP_ON_DDBBREAK #if defined(VERBOSE_CPUSTOP_ON_DDBBREAK) db_printf("CPU%d restarting CPUs: 0x%08x...", PCPU_GET(cpuid), stopped_cpus); #endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */ /* Restart all the CPUs we previously stopped */ if (stopped_cpus != PCPU_GET(other_cpus) && smp_started != 0) { db_printf("whoa, other_cpus: 0x%08x, stopped_cpus: 0x%08x\n", PCPU_GET(other_cpus), stopped_cpus); panic("stop_cpus() failed"); } restart_cpus(stopped_cpus); #if defined(VERBOSE_CPUSTOP_ON_DDBBREAK) db_printf(" restarted.\n"); #endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */ #endif /* CPUSTOP_ON_DDBBREAK */ #endif /* SMP */ *regs = ddb_regs; intr_restore(s); /* * Tell caller "We HAVE handled the trap." */ return (1); }