debugger
This commit is contained in:
parent
a84cbb2a17
commit
84114f0665
15 changed files with 3179 additions and 0 deletions
406
src/cmd/db/print.c
Normal file
406
src/cmd/db/print.c
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
*
|
||||
* debugger
|
||||
*
|
||||
*/
|
||||
#include "defs.h"
|
||||
#include "fns.h"
|
||||
|
||||
extern int infile;
|
||||
extern int outfile;
|
||||
extern int maxpos;
|
||||
|
||||
/* general printing routines ($) */
|
||||
|
||||
char *Ipath = INCDIR;
|
||||
static int tracetype;
|
||||
static void printfp(Map*, int);
|
||||
|
||||
/*
|
||||
* callback on stack trace
|
||||
*/
|
||||
static int
|
||||
ptrace(Map *map, Regs *regs, ulong pc, ulong nextpc, Symbol *sym, int depth)
|
||||
{
|
||||
char buf[512];
|
||||
|
||||
USED(map);
|
||||
if(sym){
|
||||
dprint("%s(", sym->name);
|
||||
printparams(sym, regs);
|
||||
dprint(") ");
|
||||
}else
|
||||
dprint("%#lux ", pc);
|
||||
printsource(pc);
|
||||
|
||||
dprint(" called from ");
|
||||
symoff(buf, 512, nextpc, CTEXT);
|
||||
dprint("%s ", buf);
|
||||
/* printsource(nextpc); */
|
||||
dprint("\n");
|
||||
if(tracetype == 'C' && sym)
|
||||
printlocals(sym, regs);
|
||||
return depth<40;
|
||||
}
|
||||
|
||||
static ulong *adrregvals;
|
||||
|
||||
static int
|
||||
adrrw(Regs *regs, char *name, ulong *val, int isr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if((i = windindex(name)) == -1)
|
||||
return correg->rw(correg, name, val, isr);
|
||||
if(isr){
|
||||
*val = adrregvals[i];
|
||||
return 0;
|
||||
}
|
||||
werrstr("saved registers are immutable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Regs*
|
||||
adrregs(void)
|
||||
{
|
||||
int i;
|
||||
static Regs r;
|
||||
static u32int x;
|
||||
|
||||
if(adrregvals== nil){
|
||||
adrregvals = malloc(mach->nwindreg*sizeof(adrregvals[0]));
|
||||
if(adrregvals == nil)
|
||||
error("%r");
|
||||
}
|
||||
for(i=0; i<mach->nwindreg; i++){
|
||||
if(get4(cormap, adrval+4*i, &x) < 0)
|
||||
error("%r");
|
||||
adrregvals[i] = x;
|
||||
}
|
||||
r.rw = adrrw;
|
||||
return &r;
|
||||
}
|
||||
|
||||
void
|
||||
printdollar(int modif)
|
||||
{
|
||||
int i;
|
||||
u32int u4;
|
||||
BKPT *bk;
|
||||
Symbol s;
|
||||
int stack;
|
||||
char *fname;
|
||||
char buf[512];
|
||||
Regs *r;
|
||||
|
||||
if (cntflg==0)
|
||||
cntval = -1;
|
||||
switch (modif) {
|
||||
|
||||
case '<':
|
||||
if (cntval == 0) {
|
||||
while (readchar() != EOR)
|
||||
;
|
||||
reread();
|
||||
break;
|
||||
}
|
||||
if (rdc() == '<')
|
||||
stack = 1;
|
||||
else {
|
||||
stack = 0;
|
||||
reread();
|
||||
}
|
||||
fname = getfname();
|
||||
redirin(stack, fname);
|
||||
break;
|
||||
|
||||
case '>':
|
||||
fname = getfname();
|
||||
redirout(fname);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
attachprocess();
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
kmsys();
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
case 'Q':
|
||||
done();
|
||||
|
||||
case 'w':
|
||||
maxpos=(adrflg?adrval:MAXPOS);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
printsym();
|
||||
break;
|
||||
|
||||
case 's':
|
||||
maxoff=(adrflg?adrval:MAXOFF);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
printmap("? map", symmap);
|
||||
printmap("/ map", cormap);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
case '?':
|
||||
if (pid)
|
||||
dprint("pid = %d\n",pid);
|
||||
else
|
||||
prints("no process\n");
|
||||
flushbuf();
|
||||
|
||||
case 'r':
|
||||
case 'R':
|
||||
printregs(modif);
|
||||
return;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
printfp(cormap, modif);
|
||||
return;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
tracetype = modif;
|
||||
if (adrflg)
|
||||
r = adrregs();
|
||||
else
|
||||
r = correg;
|
||||
if(stacktrace(cormap, correg, ptrace) <= 0)
|
||||
error("no stack frame");
|
||||
break;
|
||||
|
||||
/*print externals*/
|
||||
case 'e':
|
||||
for (i = 0; indexsym(i, &s)>=0; i++) {
|
||||
if (s.class==CDATA)
|
||||
if (s.loc.type==LADDR)
|
||||
if (get4(cormap, s.loc.addr, &u4) > 0)
|
||||
dprint("%s/%12t%#lux\n", s.name, (ulong)u4);
|
||||
}
|
||||
break;
|
||||
|
||||
/*print breakpoints*/
|
||||
case 'b':
|
||||
case 'B':
|
||||
for (bk=bkpthead; bk; bk=bk->nxtbkpt)
|
||||
if (bk->flag) {
|
||||
symoff(buf, 512, (WORD)bk->loc, CTEXT);
|
||||
dprint(buf);
|
||||
if (bk->count != 1)
|
||||
dprint(",%d", bk->count);
|
||||
dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
fname = getfname();
|
||||
if (machbyname(fname) == 0)
|
||||
dprint("unknown name\n");;
|
||||
break;
|
||||
default:
|
||||
error("bad `$' command");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
char *
|
||||
getfname(void)
|
||||
{
|
||||
static char fname[ARB];
|
||||
char *p;
|
||||
|
||||
if (rdc() == EOR) {
|
||||
reread();
|
||||
return (0);
|
||||
}
|
||||
p = fname;
|
||||
do {
|
||||
*p++ = lastc;
|
||||
if (p >= &fname[ARB-1])
|
||||
error("filename too long");
|
||||
} while (rdc() != EOR);
|
||||
*p = 0;
|
||||
reread();
|
||||
return (fname);
|
||||
}
|
||||
|
||||
static void
|
||||
printfp(Map *map, int modif)
|
||||
{
|
||||
Regdesc *rp;
|
||||
int i;
|
||||
int ret;
|
||||
char buf[512];
|
||||
|
||||
for (i = 0, rp = mach->reglist; rp->name; rp += ret) {
|
||||
ret = 1;
|
||||
if (!(rp->flags&RFLT))
|
||||
continue;
|
||||
ret = fpformat(map, rp, buf, sizeof(buf), modif);
|
||||
if (ret < 0) {
|
||||
werrstr("Register %s: %r", rp->name);
|
||||
error("%r");
|
||||
}
|
||||
/* double column print */
|
||||
if (i&0x01)
|
||||
dprint("%40t%-8s%-12s\n", rp->name, buf);
|
||||
else
|
||||
dprint("\t%-8s%-12s", rp->name, buf);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
redirin(int stack, char *file)
|
||||
{
|
||||
char pfile[ARB];
|
||||
|
||||
if (file == 0) {
|
||||
iclose(-1, 0);
|
||||
return;
|
||||
}
|
||||
iclose(stack, 0);
|
||||
if ((infile = open(file, 0)) < 0) {
|
||||
strcpy(pfile, Ipath);
|
||||
strcat(pfile, "/");
|
||||
strcat(pfile, file);
|
||||
if ((infile = open(pfile, 0)) < 0) {
|
||||
infile = STDIN;
|
||||
error("cannot open");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
printmap(char *s, Map *map)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!map)
|
||||
return;
|
||||
if (map == symmap)
|
||||
dprint("%s%12t`%s'\n", s, symfil==nil ? "-" : symfil);
|
||||
else if (map == cormap)
|
||||
dprint("%s%12t`%s'\n", s, corfil==nil ? "-" : corfil);
|
||||
else
|
||||
dprint("%s\n", s);
|
||||
for (i = 0; i < map->nseg; i++) {
|
||||
dprint("%s%8t%-16#lux %-16#lux %-16#lux %s\n", map->seg[i].name,
|
||||
map->seg[i].base, map->seg[i].base+map->seg[i].size, map->seg[i].offset,
|
||||
map->seg[i].file ? map->seg[i].file : "");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dump the raw symbol table
|
||||
*/
|
||||
void
|
||||
printsym(void)
|
||||
{
|
||||
int i;
|
||||
Symbol *sp, s;
|
||||
|
||||
for (i=0; indexsym(i, &s)>=0; i++){
|
||||
sp = &s;
|
||||
switch(sp->type) {
|
||||
case 't':
|
||||
case 'l':
|
||||
dprint("%8#lux t %s\n", sp->loc.addr, sp->name);
|
||||
break;
|
||||
case 'T':
|
||||
case 'L':
|
||||
dprint("%8#lux T %s\n", sp->loc.addr, sp->name);
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
case 'B':
|
||||
case 'b':
|
||||
case 'a':
|
||||
case 'p':
|
||||
case 'm':
|
||||
dprint("%8#lux %c %s\n", sp->loc.addr, sp->type, sp->name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define STRINGSZ 128
|
||||
|
||||
/*
|
||||
* print the value of dot as file:line
|
||||
*/
|
||||
void
|
||||
printsource(long dot)
|
||||
{
|
||||
char str[STRINGSZ];
|
||||
|
||||
if (fileline(dot, str, STRINGSZ) >= 0)
|
||||
dprint("%s", str);
|
||||
}
|
||||
|
||||
void
|
||||
printpc(void)
|
||||
{
|
||||
char buf[512];
|
||||
ulong u;
|
||||
|
||||
if(rget(correg, mach->pc, &u) < 0)
|
||||
error("%r");
|
||||
dot = u;
|
||||
if(dot){
|
||||
printsource((long)dot);
|
||||
printc(' ');
|
||||
symoff(buf, sizeof(buf), (long)dot, CTEXT);
|
||||
dprint("%s/", buf);
|
||||
if (mach->das(cormap, dot, 'i', buf, sizeof(buf)) < 0)
|
||||
error("%r");
|
||||
dprint("%16t%s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
printlocals(Symbol *fn, Regs *regs)
|
||||
{
|
||||
int i;
|
||||
u32int v;
|
||||
Symbol s;
|
||||
|
||||
for (i = 0; indexlsym(fn, i, &s)>=0; i++) {
|
||||
if (s.class != CAUTO)
|
||||
continue;
|
||||
if(lget4(cormap, correg, s.loc, &v) >= 0)
|
||||
dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, v);
|
||||
else
|
||||
dprint("%8t%s.%s/%10t?\n", fn->name, s.name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
printparams(Symbol *fn, Regs *regs)
|
||||
{
|
||||
int i;
|
||||
Symbol s;
|
||||
u32int v;
|
||||
int first = 0;
|
||||
|
||||
for (i = 0; indexlsym(fn, i, &s)>=0; i++) {
|
||||
if (s.class != CPARAM)
|
||||
continue;
|
||||
if (first++)
|
||||
dprint(", ");
|
||||
if(lget4(cormap, correg, s.loc, &v) >= 0)
|
||||
dprint("%s=%#lux", s.name, v);
|
||||
else
|
||||
dprint("%s=?", s.name);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue