int kdb_bt(int argc, const char **argv) { int diag; int argcount = 5; int btaprompt = 1; int nextarg; unsigned long addr; long offset; kdbgetintenv("BTARGS", &argcount); /* Arguments to print */ kdbgetintenv("BTAPROMPT", &btaprompt); /* Prompt after each proc in bta */ if (strcmp(argv[0], "bta") == 0) { struct task_struct *g, *p; unsigned long cpu; unsigned long mask = kdb_task_state_string(argc ? argv[1] : NULL); if (argc == 0) kdb_ps_suppressed(); /* Run the active tasks first */ for (cpu = 0; cpu < NR_CPUS; ++cpu) { if (!cpu_online(cpu)) continue; p = kdb_curr_task(cpu); if (kdb_bt1(p, mask, argcount, btaprompt)) return 0; } /* Now the inactive tasks */ kdb_do_each_thread(g, p) { if (task_curr(p)) continue; if (kdb_bt1(p, mask, argcount, btaprompt)) return 0; } kdb_while_each_thread(g, p); } else if (strcmp(argv[0], "btp") == 0) {
int kdb_md(int argc, const char **argv, const char **envp, struct pt_regs *regs) { char fmtchar; char fmtstr[64]; int radix, count, width; unsigned long addr; unsigned long word; long offset = 0; int diag; int nextarg; static unsigned long lastaddr = 0; static unsigned long lastcount = 0; static unsigned long lastradix = 0; char lastbuf[50]; int symbolic = 0; /* * Defaults in case the relevent environment variables are unset */ radix = 16; count = 8; width = 4; if (argc == 0) { if (lastaddr == 0) return KDB_ARGCOUNT; sprintf(lastbuf, "0x%lx", lastaddr); argv[1] = lastbuf; argc = 1; count = lastcount; radix = lastradix; } else { unsigned long val; if (argc >= 2) { diag = kdbgetularg(argv[2], &val); if (!diag) count = (int) val; } else { diag = kdbgetintenv("MDCOUNT", &count); } if (argc >= 3) { diag = kdbgetularg(argv[3], &val); if (!diag) radix = (int) val; } else { diag = kdbgetintenv("RADIX",&radix); } } switch (radix) { case 10: fmtchar = 'd'; break; case 16: fmtchar = 'x'; break; case 8: fmtchar = 'o'; break; default: return KDB_BADRADIX; } diag = kdbgetintenv("BYTESPERWORD", &width); if (strcmp(argv[0], "mds") == 0) { symbolic = 1; width = 4; } switch (width) { case 4: sprintf(fmtstr, "%%8.8%c ", fmtchar); break; case 2: sprintf(fmtstr, "%%4.4%c ", fmtchar); break; case 1: sprintf(fmtstr, "%%2.2%c ", fmtchar); break; default: return KDB_BADWIDTH; } nextarg = 1; diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs); if (diag) return diag; /* Round address down modulo BYTESPERWORD */ addr &= ~(width-1); /* * Remember count and radix for next 'md' */ lastcount = count; lastradix = radix; while (count--) { int num = (symbolic?1 :(16 / width)); char cbuf[32]; char *c = cbuf; char t; int i; for(i=0; i<sizeof(cbuf); i++) { cbuf[i] = '\0'; } kdb_printf("%8.8x: ", addr); for(i=0; i<num; i++) { char *name = NULL; word = kdbgetword(addr, width); if (kdb_flags & KDB_FLAG_SUPRESS) { kdb_flags &= ~KDB_FLAG_SUPRESS; return 0; /* Error message already printed */ } kdb_printf(fmtstr, word); if (symbolic) { name = kdbnearsym(word); } if (name) { unsigned long offset; offset = word - kdbgetsymval(name); kdb_printf("%s+0x%x", name, offset); addr += 4; } else { switch (width) { case 4: *c++ = isprint(t=kdbgetword(addr++, 1)) ?t:'.'; *c++ = isprint(t=kdbgetword(addr++, 1)) ?t:'.'; case 2: *c++ = isprint(t=kdbgetword(addr++, 1)) ?t:'.'; case 1: *c++ = isprint(t=kdbgetword(addr++, 1)) ?t:'.'; break; } } } kdb_printf(" %s\n", cbuf); } lastaddr = addr; return 0; }
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; }
int kdb_bt(int argc, const char **argv, const char **envp, struct pt_regs *regs) { int done = 0; #if !defined(CONFIG_KDB_FRAMEPTR) unsigned long sp; #endif unsigned long base, limit, esp, ebp, eip; unsigned long start = 0; /* Start address of current function */ unsigned long addr; long offset = 0; int nextarg; int argcount=5; char *name; int diag; struct pt_regs taskregs; struct frame { unsigned long ebp; unsigned long eip; } old; unsigned long stackbase = (unsigned long)current; /* * Determine how many possible arguments to print. */ diag = kdbgetintenv("BTARGS", &argcount); if (strcmp(argv[0], "btp") == 0){ struct task_struct *p; int pid; diag = kdbgetularg((char *)argv[1], (unsigned long*)&pid); if (diag) return diag; taskregs.eax = 1; for_each_task(p) { if (p->pid == pid) { taskregs.eip = p->tss.eip; taskregs.esp = p->tss.esp; taskregs.ebp = p->tss.ebp; /* * Since we don't really use the TSS * to store register between task switches, * attempt to locate real ebp (should be * top of stack if task is in schedule) */ if (taskregs.ebp == 0) { taskregs.ebp = *(unsigned long *)(taskregs.esp); } taskregs.eax = 0; stackbase = (unsigned long)p; break; } } if (taskregs.eax == 1) { kdb_printf("No process with pid == %d found\n", pid); return 0; } regs = &taskregs; } else { if (argc) {