Working on better handling of multithreading in general

and core dumps in particular.  See notes:

new types: register is something that when dereferenced gives you
	the registers.  the Ureg is no longer mapped at 0.
	refconst is something that gives a constant when dereferenced.

new builtin register("AX") creates register values
new builtin refconst(0x123) creates refconst values

new builtin var("foo") is equivalent to the variable foo
	(it returns foo but can also be used as the lhs of an assignment).

new acid function getregs() returns a list of the current values of registers.
new acid function setregs() sets the current registers to those values.
	note that getregs and setregs operate on register locations, not the
		register values themselves.
new acid function resetregs() sets registers to register("AX"), etc.
new acid function clearregs() sets all registers to constant -1.
the default register settings are as in resetregs(), not small numbers.

new acid variables coretext, pids, systype, corefile, cmdline.

new behavior: local variable lookup, stk, etc., use the acid values of registers
	(*PC, *SP, and so on), so the thread support code can change the context
	completely.

unary + is applicable to more data types and prints more often.
This commit is contained in:
rsc 2005-01-23 22:48:19 +00:00
parent a5f9ff62b2
commit 4f2ac1b76b
10 changed files with 523 additions and 171 deletions

View file

@ -20,6 +20,8 @@ map() returns 5-tuples: (name, filename, base, end, offset)
map() expects a 5-tuple too
new acid maps() prints maps nicely.
strace expects a list of register names and values like
{"PC", *PC, "SP", *SP}
@ -41,6 +43,34 @@ new builtin deltextfile(file) removes a file from the set of open text files.
both textfile and deltextfile update symbols.
new types: register is something that when dereferenced gives you
the registers. the Ureg is no longer mapped at 0.
refconst is something that gives a constant when dereferenced.
new builtin register("AX") creates register values
new builtin refconst(0x123) creates refconst values
new builtin var("foo") is equivalent to the variable foo
(it returns foo but can also be used as the lhs of an assignment).
new acid function getregs() returns a list of the current values of registers.
new acid function setregs() sets the current registers to those values.
note that getregs and setregs operate on register locations, not the
register values themselves.
new acid function resetregs() sets registers to register("AX"), etc.
new acid function clearregs() sets all registers to constant -1.
the default register settings are as in resetregs(), not small numbers.
the Ureg is not mapped at 0 anymore.
new acid variables coretext, pids, systype, corefile, cmdline.
new behavior: local variable lookup, stk, etc., use the acid values of registers
(*PC, *SP, and so on), so the thread support code can change the context
completely.
unary + is applicable to more data types and prints more often.
====
yet to be done:

View file

@ -44,6 +44,7 @@ Extern int interactive;
Extern Node* code;
Extern int na;
Extern int wtflag;
Extern Regs* acidregs;
Extern Regs* correg;
Extern Map* cormap;
Extern Map* symmap;
@ -76,6 +77,8 @@ enum
TSTRING,
TLIST,
TCODE,
TREG,
TCON,
NUMT,
};
@ -129,6 +132,8 @@ struct Store
String* string;
List* l;
Node* cc;
char* reg;
Node* con;
} u;
};
@ -182,6 +187,7 @@ struct String
int len;
};
int acidregsrw(Regs*, char*, ulong*, int);
List* addlist(List*, List*);
void addvarsym(Fhdr*);
List* al(int);
@ -212,6 +218,7 @@ void gc(void);
char* getstatus(int);
void* gmalloc(long);
void indir(Map*, ulong, char, Node*);
void indirreg(Regs*, char*, char, Node*);
void initexpr(void);
void initprint(void);
void installbuiltin(void);
@ -257,7 +264,8 @@ void userinit(void);
void varreg(void);
void varsym(void);
void whatis(Lsym*);
void windir(Map*, Node*, Node*, Node*);
void windir(Map*, Node, Node*, Node*);
void windirreg(Regs*, char*, Node*, Node*);
void yyerror(char*, ...);
int yylex(void);
int yyparse(void);
@ -313,5 +321,6 @@ enum
OFMT,
OEVAL,
OWHAT,
OUPLUS,
NUMO,
};

View file

@ -44,6 +44,9 @@ void regexp(Node*, Node*);
void textfile(Node*, Node*);
void deltextfile(Node*, Node*);
void stringn(Node*, Node*);
void xregister(Node*, Node*);
void refconst(Node*, Node*);
void dolook(Node*, Node*);
typedef struct Btab Btab;
struct Btab
@ -52,13 +55,12 @@ struct Btab
void (*fn)(Node*, Node*);
} tab[] =
{
"access", doaccess,
"atof", cvtatof,
"atoi", cvtatoi,
"deltextfile", deltextfile,
"error", doerror,
"file", getfile,
"readfile", readfile,
"access", doaccess,
"filepc", filepc,
"fnbound", funcbound,
"fmt", fmt,
@ -76,8 +78,11 @@ struct Btab
"print", bprint,
"printto", printto,
"rc", rc,
"readfile", readfile,
"reason", reason,
"refconst", refconst,
"regexp", regexp,
"register", xregister,
"setproc", setproc,
"start", start,
"startstop", startstop,
@ -87,6 +92,7 @@ struct Btab
"stringn", stringn,
"sysstop", sysstop,
"textfile", textfile,
"var", dolook,
"waitstop", waitstop,
0
};
@ -316,6 +322,65 @@ xkill(Node *r, Node *args)
deinstall(res.store.u.ival);
}
void
xregister(Node *r, Node *args)
{
Regdesc *rp;
Node res;
if(args == 0)
error("register(string): arg count");
expr(args, &res);
if(res.type != TSTRING)
error("register(string): arg type");
if((rp = regdesc(res.store.u.string->string)) == nil)
error("no such register");
r->op = OCONST;
r->type = TREG;
r->store.fmt = rp->format;
r->store.u.reg = rp->name;
}
void
refconst(Node *r, Node *args)
{
Node *n;
if(args == 0)
error("refconst(expr): arg count");
n = an(OCONST, ZN, ZN);
expr(args, n);
r->op = OCONST;
r->type = TCON;
r->store.u.con = n;
}
void
dolook(Node *r, Node *args)
{
Node res;
Lsym *l;
if(args == 0)
error("var(string): arg count");
expr(args, &res);
if(res.type != TSTRING)
error("var(string): arg type");
r->op = OCONST;
if((l = look(res.store.u.string->string)) == nil || l->v->set == 0){
r->type = TLIST;
r->store.u.l = nil;
}else{
r->type = l->v->type;
r->store = l->v->store;
}
}
void
status(Node *r, Node *args)
{
@ -350,7 +415,7 @@ reason(Node *r, Node *args)
r->op = OCONST;
r->type = TSTRING;
r->store.fmt = 's';
r->store.u.string = strnode((*mach->exc)(cormap, correg));
r->store.u.string = strnode((*mach->exc)(cormap, acidregs));
}
void
@ -367,7 +432,7 @@ follow(Node *r, Node *args)
if(res.type != TINT)
error("follow(addr): arg type");
n = (*mach->foll)(cormap, correg, res.store.u.ival, f);
n = (*mach->foll)(cormap, acidregs, res.store.u.ival, f);
if (n < 0)
error("follow(addr): %r");
tail = &r->store.u.l;
@ -953,7 +1018,7 @@ straceregrw(Regs *regs, char *name, ulong *val, int isr)
*val = sregs[i].val;
return 0;
}
return rget(correg, name, val);
return rget(acidregs, name, val);
}
void
@ -1058,6 +1123,65 @@ patom(char type, Store *res)
int i;
char buf[512];
extern char *typenames[];
Node *n;
switch(type){
case TREG:
Bprint(bout, "register(\"%s\")", res->u.reg);
return;
case TCON:
Bprint(bout, "refconst(");
n = res->u.con;
patom(n->type, &n->store);
Bprint(bout, ")");
return;
}
switch(res->fmt){
case 'c':
case 'C':
case 'r':
case 'B':
case 'b':
case 'X':
case 'x':
case 'W':
case 'D':
case 'd':
case 'u':
case 'U':
case 'Z':
case 'V':
case 'Y':
case 'o':
case 'O':
case 'q':
case 'Q':
case 'a':
case 'A':
case 'I':
case 'i':
if(type != TINT){
badtype:
Bprint(bout, "*%s\\%c*", typenames[(uchar)type], res->fmt);
return;
}
break;
case 'f':
case 'F':
if(type != TFLOAT)
goto badtype;
break;
case 's':
case 'g':
case 'G':
case 'R':
if(type != TSTRING)
goto badtype;
break;
}
switch(res->fmt) {
case 'c':
@ -1129,24 +1253,15 @@ patom(char type, Store *res)
break;
case 'f':
case 'F':
if(type != TFLOAT)
Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
else
Bprint(bout, "%g", res->u.fval);
Bprint(bout, "%g", res->u.fval);
break;
case 's':
case 'g':
case 'G':
if(type != TSTRING)
Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
else
Bwrite(bout, res->u.string->string, res->u.string->len);
Bwrite(bout, res->u.string->string, res->u.string->len);
break;
case 'R':
if(type != TSTRING)
Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
else
Bprint(bout, "%S", (Rune*)res->u.string->string);
Bprint(bout, "%S", (Rune*)res->u.string->string);
break;
case 'a':
case 'A':
@ -1155,14 +1270,10 @@ patom(char type, Store *res)
break;
case 'I':
case 'i':
if(type != TINT)
Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
else {
if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
Bprint(bout, "no instruction");
else
Bprint(bout, "%s", buf);
}
if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
Bprint(bout, "no instruction");
else
Bprint(bout, "%s", buf);
break;
}
}
@ -1406,6 +1517,7 @@ textfile(Node *r, Node *args)
unmapfile(corhdr, cormap);
mapfile(fp, base, cormap, nil);
free(correg);
correg = nil;
mapfile(corhdr, 0, cormap, &correg);
}
if(symopen(fp) < 0)
@ -1476,8 +1588,6 @@ deltextfile(Node *r, Node *args)
error("symbol file %s not open", file);
}
int xget1(Map *m, ulong addr, u8int *a, int n);
void
stringn(Node *r, Node *args)
{
@ -1507,7 +1617,7 @@ stringn(Node *r, Node *args)
r->type = TSTRING;
for(i=0; i<n; i++){
ret = xget1(cormap, addr, (uchar*)&buf[i], 1);
ret = get1(cormap, addr, (uchar*)&buf[i], 1);
if(ret < 0){
free(buf);
error("indir: %r");

View file

@ -282,8 +282,7 @@ monexpr : term
}
| '+' monexpr
{
$$ = con(0);
$$ = an(OADD, $2, $$);
$$ = an(OUPLUS, $2, ZN);
}
| '-' monexpr
{

View file

@ -202,56 +202,6 @@ convflt(Node *r, char *flt)
}
}
static char*
regbyoff(ulong addr)
{
Regdesc *r;
if(mach == nil)
error("no mach, no registers");
for(r=mach->reglist; r->name; r++)
if(r->offset == addr)
return r->name;
error("no register at %#lux", addr);
return nil;
}
int
xget1(Map *m, ulong addr, u8int *a, int n)
{
if(addr < 0x100 && correg)
return lget1(m, correg, locreg(regbyoff(addr)), a, n);
else
return get1(m, addr, a, n);
}
int
xget2(Map *m, ulong addr, u16int *a)
{
if(addr < 0x100 && correg)
return lget2(m, correg, locreg(regbyoff(addr)), a);
else
return get2(m, addr, a);
}
int
xget4(Map *m, ulong addr, u32int *a)
{
if(addr < 0x100 && correg)
return lget4(m, correg, locreg(regbyoff(addr)), a);
else
return get4(m, addr, a);
}
int
xget8(Map *m, ulong addr, u64int *a)
{
if(addr < 0x100 && correg)
return lget8(m, correg, locreg(regbyoff(addr)), a);
else
return get8(m, addr, a);
}
void
indir(Map *m, ulong addr, char fmt, Node *r)
{
@ -272,7 +222,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'C':
case 'b':
r->type = TINT;
ret = xget1(m, addr, &cval, 1);
ret = get1(m, addr, &cval, 1);
if (ret < 0)
error("indir: %r");
r->store.u.ival = cval;
@ -284,7 +234,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'q':
case 'r':
r->type = TINT;
ret = xget2(m, addr, &sval);
ret = get2(m, addr, &sval);
if (ret < 0)
error("indir: %r");
r->store.u.ival = sval;
@ -298,7 +248,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'O':
case 'Q':
r->type = TINT;
ret = xget4(m, addr, &ival);
ret = get4(m, addr, &ival);
if (ret < 0)
error("indir: %r");
r->store.u.ival = ival;
@ -308,7 +258,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'Y':
case 'Z':
r->type = TINT;
ret = xget8(m, addr, &vval);
ret = get8(m, addr, &vval);
if (ret < 0)
error("indir: %r");
r->store.u.ival = vval;
@ -316,7 +266,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 's':
r->type = TSTRING;
for(i = 0; i < sizeof(buf)-1; i++) {
ret = xget1(m, addr, (uchar*)&buf[i], 1);
ret = get1(m, addr, (uchar*)&buf[i], 1);
if (ret < 0)
error("indir: %r");
addr++;
@ -331,7 +281,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'R':
r->type = TSTRING;
for(i = 0; i < sizeof(buf)-2; i += 2) {
ret = xget1(m, addr, (uchar*)&buf[i], 2);
ret = get1(m, addr, (uchar*)&buf[i], 2);
if (ret < 0)
error("indir: %r");
addr += 2;
@ -351,14 +301,14 @@ indir(Map *m, ulong addr, char fmt, Node *r)
r->store.u.string = strnode(buf);
break;
case 'f':
ret = xget1(m, addr, (uchar*)buf, mach->szfloat);
ret = get1(m, addr, (uchar*)buf, mach->szfloat);
if (ret < 0)
error("indir: %r");
mach->ftoa32(buf, sizeof(buf), (void*) buf);
convflt(r, buf);
break;
case 'g':
ret = xget1(m, addr, (uchar*)buf, mach->szfloat);
ret = get1(m, addr, (uchar*)buf, mach->szfloat);
if (ret < 0)
error("indir: %r");
mach->ftoa32(buf, sizeof(buf), (void*) buf);
@ -366,14 +316,14 @@ indir(Map *m, ulong addr, char fmt, Node *r)
r->store.u.string = strnode(buf);
break;
case 'F':
ret = xget1(m, addr, (uchar*)buf, mach->szdouble);
ret = get1(m, addr, (uchar*)buf, mach->szdouble);
if (ret < 0)
error("indir: %r");
mach->ftoa64(buf, sizeof(buf), (void*) buf);
convflt(r, buf);
break;
case '3': /* little endian ieee 80 with hole in bytes 8&9 */
ret = xget1(m, addr, (uchar*)reg, 10);
ret = get1(m, addr, (uchar*)reg, 10);
if (ret < 0)
error("indir: %r");
memmove(reg+10, reg+8, 2); /* open hole */
@ -382,14 +332,14 @@ indir(Map *m, ulong addr, char fmt, Node *r)
convflt(r, buf);
break;
case '8': /* big-endian ieee 80 */
ret = xget1(m, addr, (uchar*)reg, 10);
ret = get1(m, addr, (uchar*)reg, 10);
if (ret < 0)
error("indir: %r");
beieeeftoa80(buf, sizeof(buf), reg);
convflt(r, buf);
break;
case 'G':
ret = xget1(m, addr, (uchar*)buf, mach->szdouble);
ret = get1(m, addr, (uchar*)buf, mach->szdouble);
if (ret < 0)
error("indir: %r");
mach->ftoa64(buf, sizeof(buf), (void*) buf);
@ -400,21 +350,70 @@ indir(Map *m, ulong addr, char fmt, Node *r)
}
void
windir(Map *m, Node *addr, Node *rval, Node *r)
indirreg(Regs *regs, char *name, char fmt, Node *r)
{
ulong val;
if(regs == 0)
error("no register set for *%s=", name);
r->op = OCONST;
r->store.fmt = fmt;
switch(fmt){
default:
error("bad pointer format '%c' for *%s", fmt, name);
case 'c':
case 'C':
case 'b':
case 'x':
case 'd':
case 'u':
case 'o':
case 'q':
case 'r':
case 'a':
case 'A':
case 'B':
case 'X':
case 'D':
case 'U':
case 'O':
case 'Q':
case 'V':
case 'W':
case 'Y':
case 'Z':
if(rget(regs, name, &val) < 0)
error("reading %s: %r", name);
r->type = TINT;
r->store.u.ival = val;
break;
case 'f':
case 'g':
case 'F':
case '3':
case '8':
case 'G':
error("floating point registers not supported");
break;
}
}
void
windir(Map *m, Node aes, Node *rval, Node *r)
{
uchar cval;
ushort sval;
Node res, aes;
Node res;
int ret;
if(m == 0)
error("no map for */@=");
expr(rval, &res);
expr(addr, &aes);
if(aes.type != TINT)
error("bad type lhs of @/*");
error("bad type lhs of */@=");
expr(rval, &res);
if(m != cormap && wtflag == 0)
error("not in write mode");
@ -465,6 +464,58 @@ windir(Map *m, Node *addr, Node *rval, Node *r)
error("windir: %r");
}
void
windirreg(Regs *regs, char *name, Node *rval, Node *r)
{
Node res;
if(regs == 0)
error("no register set for *%s=", name);
expr(rval, &res);
r->type = res.type;
r->store.fmt = res.store.fmt;
r->store = res.store;
switch(res.store.fmt){
default:
error("bad format '%c' for *%s=", res.store.fmt, name);
case 'c':
case 'C':
case 'b':
case 'x':
case 'd':
case 'u':
case 'o':
case 'q':
case 'r':
case 'a':
case 'A':
case 'B':
case 'X':
case 'D':
case 'U':
case 'O':
case 'Q':
case 'V':
case 'W':
case 'Y':
case 'Z':
if(rput(regs, name, res.store.u.ival) < 0)
error("writing %s: %r", name);
break;
case 'f':
case 'g':
case 'F':
case '3':
case '8':
case 'G':
error("floating point registers not supported");
break;
}
}
void
call(char *fn, Node *parameters, Node *local, Node *body, Node *retexp)
{

View file

@ -63,11 +63,29 @@ fmtsize(Value *v)
}
}
void
Lsym*
chklval(Node *lp)
{
if(lp->op != ONAME)
error("need l-value");
Node res;
Lsym *s;
if(lp->op == ONAME)
return lp->sym;
if(lp->op == OCALL){
s = chklval(lp->left);
if(strcmp(s->name, "var") == 0
&& (lp->builtin || s->proc == 0)){
if(lp->right == 0)
error("var(string): arg count");
expr(lp->right, &res);
if(res.type != TSTRING)
error("var(string): arg type");
return mkvar(res.store.u.string->string);
}
}
error("need l-value");
return nil;
}
void
@ -107,12 +125,24 @@ oindm(Node *n, Node *res)
if(m == 0)
m = symmap;
expr(n->left, &l);
if(l.type != TINT)
switch(l.type){
default:
error("bad type for *");
if(m == 0)
error("no map for *");
indir(m, l.store.u.ival, l.store.fmt, res);
res->store.comt = l.store.comt;
case TINT:
if(m == 0)
error("no map for *");
indir(m, l.store.u.ival, l.store.fmt, res);
res->store.comt = l.store.comt;
break;
case TREG:
indirreg(correg, l.store.u.reg, l.store.fmt, res);
res->store.comt = l.store.comt;
break;
case TCON:
*res = *l.store.u.con;
res->store.comt = l.store.comt;
break;
}
}
void
@ -145,7 +175,7 @@ oframe(Node *n, Node *res)
while(*p && *p == '$')
p++;
lp = n->left;
if(localaddr(cormap, correg, p, lp->sym->name, &ival) < 0)
if(localaddr(cormap, acidregs, p, lp->sym->name, &ival) < 0)
error("colon: %r");
res->store.u.ival = ival;
@ -296,19 +326,24 @@ void
oasgn(Node *n, Node *res)
{
Node *lp, r;
Node aes;
Value *v;
lp = n->left;
switch(lp->op) {
case OINDM:
windir(cormap, lp->left, n->right, res);
expr(lp->left, &aes);
if(aes.type == TREG)
windirreg(correg, aes.store.u.reg, n->right, res);
else
windir(cormap, aes, n->right, res);
break;
case OINDC:
windir(symmap, lp->left, n->right, res);
expr(lp->left, &aes);
windir(symmap, aes, n->right, res);
break;
default:
chklval(lp);
v = lp->sym->v;
v = chklval(lp)->v;
expr(n->right, &r);
v->set = 1;
v->type = r.type;
@ -871,8 +906,7 @@ oeinc(Node *n, Node *res)
{
Value *v;
chklval(n->left);
v = n->left->sym->v;
v = chklval(n->left)->v;
res->op = OCONST;
res->type = v->type;
switch(v->type) {
@ -899,8 +933,7 @@ opinc(Node *n, Node *res)
{
Value *v;
chklval(n->left);
v = n->left->sym->v;
v = chklval(n->left)->v;
res->op = OCONST;
res->type = v->type;
res->store = v->store;
@ -932,9 +965,7 @@ ocall(Node *n, Node *res)
res->type = TLIST;
res->store.u.l = 0;
chklval(n->left);
s = n->left->sym;
s = chklval(n->left);
if(n->builtin && !s->builtin){
error("no builtin %s", s->name);
return;
@ -958,6 +989,12 @@ ofmt(Node *n, Node *res)
res->store.fmt = n->right->store.u.ival;
}
void
ouplus(Node *n, Node *res)
{
expr(n->left, res);
}
void
owhat(Node *n, Node *res)
{
@ -1021,6 +1058,7 @@ initexpop(void)
expop[OFMT] = ofmt;
expop[OEVAL] = oeval;
expop[OWHAT] = owhat;
expop[OUPLUS] = ouplus;
}
void
@ -1030,3 +1068,54 @@ initexpr(void)
initexpop();
}
int
acidregsrw(Regs *r, char *name, ulong *u, int isr)
{
Lsym *l;
Value *v;
Node *n;
ulong addr;
u32int u32;
if(!isr){
werrstr("cannot write registers");
return -1;
}
USED(r);
l = look(name);
if(l == nil){
werrstr("register %s not found", name);
return -1;
}
v = l->v;
switch(v->type){
default:
werrstr("*%s: bad type", name);
return -1;
case TREG:
if(correg == nil){
werrstr("*%s: register %s not mapped", name, v->store.u.reg);
return -1;
}
return rget(correg, v->store.u.reg, u);
case TCON:
n = v->store.u.con;
if(n->op != OCONST || n->type != TINT){
werrstr("*%s: bad register constant", name);
return -1;
}
*u = n->store.u.ival;
return 0;
case TINT:
if(cormap == nil){
werrstr("*%s: core not mapped", name);
return -1;
}
addr = v->store.u.ival;
/* XXX should use format to determine size */
if(get4(cormap, addr, &u32) < 0)
return -1;
*u = u32;
return 0;
}
}

View file

@ -106,6 +106,8 @@ main(int argc, char *argv[])
pushfile(0);
loadvars();
installbuiltin();
acidregs = mallocz(sizeof *acidregs, 1);
acidregs->rw = acidregsrw;
if(mtype && machbyname(mtype) == 0)
print("unknown machine %s", mtype);
@ -172,16 +174,29 @@ main(int argc, char *argv[])
*/
}
void
setstring(char *var, char *s)
{
Lsym *l;
Value *v;
l = mkvar(var);
v = l->v;
v->store.fmt = 's';
v->set = 1;
v->store.u.string = strnode(s ? s : "");
v->type = TSTRING;
}
static int
attachfiles(int argc, char **argv)
{
int fd;
volatile int pid;
char *s;
char *s, *t;
int i, omode;
Fhdr *hdr;
Lsym *l;
Value *v;
pid = 0;
interactive = 0;
@ -220,7 +235,6 @@ attachfiles(int argc, char **argv)
}
fprint(2, "%s: %s %s %s\n", argv[i], hdr->aname, hdr->mname, hdr->fname);
if(hdr->ftype == FCORE){
fprint(2, "cmd: %s\n", hdr->cmd);
if(pid){
fprint(2, "already have pid %d; ignoring core %s\n", pid, argv[i]);
uncrackhdr(hdr);
@ -252,12 +266,28 @@ attachfiles(int argc, char **argv)
symfil = s;
}
}
/* XXX pull command from core */
if(corhdr){
/*
* prog gives only the basename of the command,
* so try the command line for a path.
*/
if((s = strdup(corhdr->cmdline)) != nil){
t = strchr(s, ' ');
if(t)
*t = 0;
if((t = searchpath(s)) != nil){
fprint(2, "core: text %s\n", t);
symfil = t;
}
free(s);
}
}
if((symhdr = crackhdr(symfil, omode)) == nil){
fprint(2, "crackhdr %s: %r\n", symfil);
symfil = nil;
}
}else
fprint(2, "%s: %s %s %s\n", symfil, symhdr->aname, symhdr->mname, symhdr->fname);
}
if(symhdr)
@ -281,33 +311,15 @@ attachfiles(int argc, char **argv)
}
Run:
l = mkvar("objtype");
v = l->v;
v->store.fmt = 's';
v->set = 1;
v->store.u.string = strnode(mach->name);
v->type = TSTRING;
setstring("objtype", mach->name);
setstring("textfile", symfil);
setstring("systype", symhdr ? symhdr->aname : "");
setstring("corefile", corfil);
l = mkvar("textfile");
v = l->v;
v->store.fmt = 's';
v->set = 1;
v->store.u.string = strnode(symfil ? symfil : "");
v->type = TSTRING;
l = mkvar("systype");
v = l->v;
v->store.fmt = 's';
v->set = 1;
v->store.u.string = strnode(symhdr ? symhdr->aname : "");
v->type = TSTRING;
l = mkvar("corefile");
v = l->v;
v->store.fmt = 's';
v->set = 1;
v->store.u.string = strnode(corfil ? corfil : "");
v->type = TSTRING;
l = mkvar("pids");
l->v->set = 1;
l->v->type = TLIST;
l->v->store.u.l = nil;
if(pid)
sproc(pid);
@ -320,6 +332,11 @@ Run:
void
setcore(Fhdr *hdr)
{
int i;
Lsym *l;
Value *v;
List **tail, *tl;
unmapproc(cormap);
unmapfile(corhdr, cormap);
free(correg);
@ -331,6 +348,31 @@ setcore(Fhdr *hdr)
error("mapfile %s: %r", hdr->filename);
corhdr = hdr;
corfil = hdr->filename;
l = mkvar("pid");
v = l->v;
v->store.fmt = 'D';
v->set = 1;
v->store.u.ival = hdr->pid;
setstring("corefile", corfil);
setstring("cmdline", hdr->cmdline);
l = mkvar("pids");
l->v->set = 1;
l->v->type = TLIST;
l->v->store.u.l = nil;
tail = &l->v->store.u.l;
for(i=0; i<hdr->nthread; i++){
tl = al(TINT);
tl->store.u.ival = hdr->thread[i].id;
tl->store.fmt = 'X';
*tail = tl;
tail = &tl->next;
}
if(hdr->nthread)
sproc(hdr->thread[0].id);
}
void
@ -338,16 +380,21 @@ die(void)
{
Lsym *s;
List *f;
int first;
Bprint(bout, "\n");
first = 1;
s = look("proclist");
if(s && s->v->type == TLIST) {
for(f = s->v->store.u.l; f; f = f->next){
detachproc((int)f->store.u.ival);
Bprint(bout, "/bin/kill -9 %d\n", (int)f->store.u.ival);
Bprint(bout, "%s %d", first ? "/bin/kill -9" : "", (int)f->store.u.ival);
first = 0;
}
}
if(!first)
Bprint(bout, "\n");
exits(0);
}
@ -545,6 +592,9 @@ gc(void)
case TCODE:
marktree(v->store.u.cc);
break;
case TCON:
marktree(v->store.u.con);
break;
}
}
}

View file

@ -401,6 +401,10 @@ pexpr(Node *n)
if(n->sym)
Bprint(bout, " %s", n->sym->name);
break;
case OUPLUS:
Bprint(bout, "+");
pexpr(l);
break;
}
}

View file

@ -21,30 +21,39 @@ sproc(int xpid)
if(pid == xpid)
return;
if(xpid <= 0)
error("bad pid");
if(corhdr){
free(correg);
correg = nil;
correg = coreregs(corhdr, xpid);
if(correg == nil)
error("no such pid in core dump");
}else{
/* XXX should only change register set here if cormap already mapped */
if(xpid <= 0)
error("bad pid");
unmapproc(cormap);
unmapfile(corhdr, cormap);
free(correg);
correg = nil;
unmapproc(cormap);
unmapfile(corhdr, cormap);
free(correg);
correg = nil;
if(mapproc(xpid, cormap, &correg) < 0)
error("setproc %d: %r", xpid);
if(mapproc(xpid, cormap, &correg) < 0)
error("setproc %d: %r", xpid);
/* XXX check text file here? */
/* XXX check text file here? */
for(i=0; i<cormap->nseg; i++){
if(cormap->seg[i].file == nil){
if(strcmp(cormap->seg[i].name, "data") == 0)
cormap->seg[i].name = "*data";
if(strcmp(cormap->seg[i].name, "text") == 0)
cormap->seg[i].name = "*text";
}
}
}
pid = xpid;
s = look("pid");
s->v->store.u.ival = pid;
for(i=0; i<cormap->nseg; i++)
if(cormap->seg[i].file == nil){
if(strcmp(cormap->seg[i].name, "data") == 0)
cormap->seg[i].name = "*data";
if(strcmp(cormap->seg[i].name, "text") == 0)
cormap->seg[i].name = "*text";
}
install(pid);
}
@ -165,6 +174,7 @@ install(int pid)
s->v->set = 1;
}
/*
static int
installed(int pid)
{
@ -175,6 +185,7 @@ installed(int pid)
return 1;
return 0;
}
*/
void
deinstall(int pid)

View file

@ -61,7 +61,6 @@ varsym(void)
continue;
addvarsym(fp);
}
if(l->v->store.u.l == nil)
print("no debugging symbols\n");
}
@ -217,9 +216,9 @@ varreg(void)
l = mkvar(r->name);
v = l->v;
v->set = 1;
v->store.u.ival = r->offset;
v->store.u.reg = r->name;
v->store.fmt = r->format;
v->type = TINT;
v->type = TREG;
li = al(TSTRING);
li->store.u.string = strnode(r->name);