static int kdb_bt1(struct task_struct *p, unsigned long mask, int argcount, int btaprompt) { int diag; char buffer[2]; if (kdb_getarea(buffer[0], (unsigned long)p) || kdb_getarea(buffer[0], (unsigned long)(p+1)-1)) return KDB_BADADDR; if (!kdb_task_state(p, mask)) return 0; kdb_printf("Stack traceback for pid %d\n", p->pid); kdb_ps1(p); diag = kdb_show_stack(p, NULL, argcount); if (btaprompt) { kdb_getstr(buffer, sizeof(buffer), "Enter <q> to end, <cr> to continue:"); if (buffer[0] == 'q') { kdb_printf("\n"); return 1; } } touch_nmi_watchdog(); return 0; }
static int kdbm_sigset(int argc, const char **argv) { sigset_t *sp = NULL; unsigned long addr; long offset=0; int nextarg; int e = 0; int i; char fmt[32]; if (argc != 1) return KDB_ARGCOUNT; #ifndef _NSIG_WORDS kdb_printf("unavailable on this platform, _NSIG_WORDS not defined.\n"); #else nextarg = 1; if ((e = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL)) != 0) return(e); if (!(sp = kmalloc(sizeof(*sp), GFP_ATOMIC))) { kdb_printf("%s: cannot kmalloc sp\n", __FUNCTION__); goto out; } if ((e = kdb_getarea(*sp, addr))) { kdb_printf("%s: invalid sigset address\n", __FUNCTION__); goto out; } sprintf(fmt, "[%%d]=0x%%0%dlx ", (int)sizeof(sp->sig[0])*2); kdb_printf("sigset at 0x%p : ", sp); for (i=_NSIG_WORDS-1; i >= 0; i--) { if (i == 0 || sp->sig[i]) { kdb_printf(fmt, i, sp->sig[i]); } } kdb_printf("\n"); #endif /* _NSIG_WORDS */ out: if (sp) kfree(sp); return e; }
int kdb_id(int argc, const char **argv) { kdb_machreg_t pc; int icount; int diag; int i; char *mode; int nextarg; long offset = 0; static kdb_machreg_t lastpc; struct disassemble_info *dip = &kdb_di; char lastbuf[50]; unsigned long word; kdb_di.fprintf_func = kdb_dis_fprintf; kdba_id_init(&kdb_di); if (argc != 1) { if (lastpc == 0) { return KDB_ARGCOUNT; } else { sprintf(lastbuf, "0x%lx", lastpc); argv[1] = lastbuf; argc = 1; } } /* * Fetch PC. First, check to see if it is a symbol, if not, * try address. */ nextarg = 1; diag = kdbgetaddrarg(argc, argv, &nextarg, &pc, &offset, NULL); if (diag) return diag; kdba_check_pc(&pc); if (kdb_getarea(word, pc)) return(0); /* * Number of lines to display */ diag = kdbgetintenv("IDCOUNT", &icount); if (diag) return diag; mode = kdbgetenv("IDMODE"); diag = kdba_id_parsemode(mode, dip); if (diag) { return diag; } for(i=0; i<icount; i++) { pc += kdba_id_printinsn(pc, &kdb_di); kdb_printf("\n"); } lastpc = pc; return 0; }
static int kdbm_task(int argc, const char **argv) { unsigned long addr; long offset=0; int nextarg; int e = 0; struct task_struct *tp = NULL, *tp1; if (argc != 1) return KDB_ARGCOUNT; nextarg = 1; if ((e = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL)) != 0) return(e); if (!(tp = kmalloc(sizeof(*tp), GFP_ATOMIC))) { kdb_printf("%s: cannot kmalloc tp\n", __FUNCTION__); goto out; } if ((e = kdb_getarea(*tp, addr))) { kdb_printf("%s: invalid task address\n", __FUNCTION__); goto out; } tp1 = (struct task_struct *)addr; kdb_printf( "struct task at 0x%lx, pid=%d flags=0x%x state=%ld comm=\"%s\"\n", addr, tp->pid, tp->flags, tp->state, tp->comm); kdb_printf(" cpu=%d policy=%u ", kdb_process_cpu(tp), tp->policy); kdb_printf( "prio=%d static_prio=%d cpus_allowed=", tp->prio, tp->static_prio); { /* The cpus allowed string may be longer than kdb_printf() can * handle. Print it in chunks. */ char c, *p; p = kdb_cpus_allowed_string(tp); while (1) { if (strlen(p) < 100) { kdb_printf("%s", p); break; } c = p[100]; p[100] = '\0'; kdb_printf("%s", p); p[100] = c; p += 100; } } kdb_printf(" &thread=0x%p\n", &tp1->thread); kdb_printf(" need_resched=%d ", test_tsk_thread_flag(tp, TIF_NEED_RESCHED)); kdb_printf( "timestamp=%llu time_slice=%u", tp->timestamp, tp->time_slice); kdb_printf(" lock_depth=%d\n", tp->lock_depth); kdb_printf( " fs=0x%p files=0x%p mm=0x%p\n", tp->fs, tp->files, tp->mm); kdb_printf( " uid=%d euid=%d suid=%d fsuid=%d gid=%d egid=%d sgid=%d fsgid=%d\n", tp->uid, tp->euid, tp->suid, tp->fsuid, tp->gid, tp->egid, tp->sgid, tp->fsgid); kdb_printf( " user=0x%p\n", tp->user); if (tp->sysvsem.undo_list) kdb_printf( " sysvsem.sem_undo refcnt %d proc_list=0x%p\n", atomic_read(&tp->sysvsem.undo_list->refcnt), tp->sysvsem.undo_list->proc_list); kdb_printf( " signal=0x%p &blocked=0x%p &pending=0x%p\n", tp->signal, &tp1->blocked, &tp1->pending); kdb_printf( " utime=%ld stime=%ld cutime=%ld cstime=%ld\n", tp->utime, tp->stime, tp->signal ? tp->signal->cutime : 0L, tp->signal ? tp->signal->cstime : 0L); kdb_printf(" thread_info=0x%p\n", task_thread_info(tp)); kdb_printf(" ti flags=0x%lx\n", (unsigned long)task_thread_info(tp)->flags); out: if (tp) kfree(tp); return e; }
kdb_dbtrap_t kdba_db_trap(struct pt_regs *regs, int error_unused) { kdb_machreg_t dr6; kdb_machreg_t dr7; int rw, reg; int i; kdb_dbtrap_t rv = KDB_DB_BPT; kdb_bp_t *bp; if (KDB_NULL_REGS(regs)) return KDB_DB_NOBPT; dr6 = kdba_getdr6(); dr7 = kdba_getdr7(); if (KDB_DEBUG(BP)) kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7); if (dr6 & DR6_BS) { if (KDB_STATE(SSBPT)) { if (KDB_DEBUG(BP)) kdb_printf("ssbpt\n"); KDB_STATE_CLEAR(SSBPT); for(i=0,bp=kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { if (KDB_DEBUG(BP)) kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n", bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu); if (!bp->bp_enabled) continue; if (!bp->bp_global && bp->bp_cpu != smp_processor_id()) continue; if (KDB_DEBUG(BP)) kdb_printf("bp for this cpu\n"); if (bp->bp_delayed) { bp->bp_delayed = 0; if (KDB_DEBUG(BP)) kdb_printf("kdba_installbp\n"); kdba_installbp(regs, bp); if (!KDB_STATE(DOING_SS)) { regs->eflags &= ~EF_TF; return(KDB_DB_SSBPT); } break; } } if (i == KDB_MAXBPT) { kdb_printf("kdb: Unable to find delayed breakpoint\n"); } if (!KDB_STATE(DOING_SS)) { regs->eflags &= ~EF_TF; return(KDB_DB_NOBPT); } /* FALLTHROUGH */ } /* * KDB_STATE_DOING_SS is set when the kernel debugger is using * the processor trap flag to single-step a processor. If a * single step trap occurs and this flag is clear, the SS trap * will be ignored by KDB and the kernel will be allowed to deal * with it as necessary (e.g. for ptrace). */ if (!KDB_STATE(DOING_SS)) goto unknown; /* single step */ rv = KDB_DB_SS; /* Indicate single step */ if (KDB_STATE(DOING_SSB)) { unsigned char instruction[2]; kdb_id1(regs->rip); if (kdb_getarea(instruction, regs->rip) || (instruction[0]&0xf0) == 0xe0 || /* short disp jumps */ (instruction[0]&0xf0) == 0x70 || /* Misc. jumps */ instruction[0] == 0xc2 || /* ret */ instruction[0] == 0x9a || /* call */ (instruction[0]&0xf8) == 0xc8 || /* enter, leave, iret, int, */ ((instruction[0] == 0x0f) && ((instruction[1]&0xf0)== 0x80)) ) { /* * End the ssb command here. */ KDB_STATE_CLEAR(DOING_SSB); KDB_STATE_CLEAR(DOING_SS); } else { rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */ } } else { /* * Print current insn */ kdb_printf("SS trap at "); kdb_symbol_print(regs->rip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE); kdb_id1(regs->rip); KDB_STATE_CLEAR(DOING_SS); } if (rv != KDB_DB_SSB) regs->eflags &= ~EF_TF; } if (dr6 & DR6_B0) { rw = DR7_RW0(dr7); reg = 0; goto handle; } if (dr6 & DR6_B1) { rw = DR7_RW1(dr7); reg = 1; goto handle; } if (dr6 & DR6_B2) { rw = DR7_RW2(dr7); reg = 2; goto handle; } if (dr6 & DR6_B3) { rw = DR7_RW3(dr7); reg = 3; goto handle; } if (rv > 0) goto handled; goto unknown; /* dismiss */ handle: /* * Set Resume Flag */ regs->eflags |= EF_RF; /* * Determine which breakpoint was encountered. */ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) { if (!(bp->bp_free) && (bp->bp_global || bp->bp_cpu == smp_processor_id()) && (bp->bp_hard) && (bp->bp_hard->bph_reg == reg)) { /* * Hit this breakpoint. */ kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n", kdba_rwtypes[rw], i, bp->bp_addr); /* * For an instruction breakpoint, disassemble * the current instruction. */ if (rw == 0) { kdb_id1(regs->rip); } goto handled; } } unknown: regs->eflags |= EF_RF; /* Supress further faults */ rv = KDB_DB_NOBPT; /* Cause kdb() to return */ handled: /* * Clear the pending exceptions. */ kdba_putdr6(0); return rv; }