ratrace: various improvements

error handling, serialize exits, close reader filedescriptors,
fix channel types, embedd the string buffer in the Msg struct.
This commit is contained in:
cinap_lenrek 2015-07-29 03:53:11 +02:00
parent d48dcf08aa
commit 059c85dd75

View file

@ -4,7 +4,6 @@
enum { enum {
Stacksize = 8*1024, Stacksize = 8*1024,
Bufsize = 8*1024,
}; };
Channel *out; Channel *out;
@ -14,49 +13,63 @@ int nread = 0;
typedef struct Msg Msg; typedef struct Msg Msg;
struct Msg { struct Msg {
char *buf;
int pid; int pid;
char buf[8*1024];
};
typedef struct Reader Reader;
struct Reader {
int pid;
int tfd;
int cfd;
Msg* msg;
}; };
void void
die(char *s) die(Reader *r)
{ {
fprint(2, "%s\n", s); Msg *s;
exits(s);
s = r->msg;
snprint(s->buf, sizeof(s->buf), " = %r\n");
s->pid = r->pid;
sendp(quit, s);
close(r->tfd);
close(r->cfd);
threadexits(nil);
} }
void void
cwrite(int fd, char *path, char *cmd, int len) cwrite(Reader *r, char *cmd)
{ {
if (write(fd, cmd, len) < len) { if (write(r->cfd, cmd, strlen(cmd)) < 0)
fprint(2, "cwrite: %s: failed %d bytes: %r\n", path, len); die(r);
sendp(quit, nil);
threadexits(nil);
}
} }
void void
reader(void *v) reader(void *v)
{ {
int cfd, tfd, forking = 0, pid, newpid; int forking = 0, newpid;
char *ctl, *truss; Reader r;
Msg *s; Msg *s;
pid = (int)(uintptr)v; r.pid = (int)(uintptr)v;
ctl = smprint("/proc/%d/ctl", pid); r.tfd = r.cfd = -1;
if ((cfd = open(ctl, OWRITE)) < 0)
die(smprint("%s: %r", ctl));
truss = smprint("/proc/%d/syscall", pid);
if ((tfd = open(truss, OREAD)) < 0)
die(smprint("%s: %r", truss));
cwrite(cfd, ctl, "stop", 4); r.msg = s = mallocz(sizeof(Msg), 1);
cwrite(cfd, truss, "startsyscall", 12); snprint(s->buf, sizeof(s->buf), "/proc/%d/ctl", r.pid);
if ((r.cfd = open(s->buf, OWRITE)) < 0)
die(&r);
snprint(s->buf, sizeof(s->buf), "/proc/%d/syscall", r.pid);
if ((r.tfd = open(s->buf, OREAD)) < 0)
die(&r);
s = mallocz(sizeof(Msg) + Bufsize, 1); cwrite(&r, "stop");
s->pid = pid; cwrite(&r, "startsyscall");
s->buf = (char *)&s[1];
while(pread(tfd, s->buf, Bufsize - 1, 0) > 0){ while(pread(r.tfd, s->buf, sizeof(s->buf)-1, 0) > 0){
if (forking && s->buf[1] == '=' && s->buf[3] != '-') { if (forking && s->buf[1] == '=' && s->buf[3] != '-') {
forking = 0; forking = 0;
newpid = strtol(&s->buf[3], 0, 0); newpid = strtol(&s->buf[3], 0, 0);
@ -82,14 +95,13 @@ reader(void *v)
} }
free(rf); free(rf);
} }
s->pid = r.pid;
sendp(out, s); sendp(out, s);
cwrite(cfd, truss, "startsyscall", 12);
s = mallocz(sizeof(Msg) + Bufsize, 1); r.msg = s = mallocz(sizeof(Msg), 1);
s->pid = pid; cwrite(&r, "startsyscall");
s->buf = (char *)&s[1];
} }
sendp(quit, nil); die(&r);
threadexitsall(nil);
} }
void void
@ -103,7 +115,7 @@ writer(void *arg)
a[0].op = CHANRCV; a[0].op = CHANRCV;
a[0].c = quit; a[0].c = quit;
a[0].v = nil; a[0].v = &s;
a[1].op = CHANRCV; a[1].op = CHANRCV;
a[1].c = out; a[1].c = out;
a[1].v = &s; a[1].v = &s;
@ -112,34 +124,30 @@ writer(void *arg)
a[2].v = nil; a[2].v = nil;
a[3].op = CHANEND; a[3].op = CHANEND;
for(;;) while(nread > 0){
switch(alt(a)){ switch(alt(a)){
case 0: case 0:
nread--; nread--;
if(nread <= 0)
goto done;
break;
case 1: case 1:
if(s->pid != lastpid){ if(s->pid != lastpid){
lastpid = s->pid; lastpid = s->pid;
fprint(2, s->buf[1]=='='? "\n%d ...": "\n", lastpid); fprint(2, s->buf[1]=='='? "\n%d ...": "\n", lastpid);
} }
fprint(2, "%s", s->buf); write(2, s->buf, strlen(s->buf));
free(s); free(s);
break; break;
case 2: case 2:
nread++; nread++;
break; break;
} }
done: }
exits(nil);
} }
void void
usage(void) usage(void)
{ {
fprint(2, "Usage: ratrace [-c cmd [arg...]] | [pid]\n"); fprint(2, "Usage: ratrace [-c cmd [arg...]] | [pid]\n");
exits("usage"); threadexits("usage");
} }
void void
@ -185,9 +193,9 @@ threadmain(int argc, char **argv)
pid = atoi(argv[1]); pid = atoi(argv[1]);
} }
out = chancreate(sizeof(char*), 0); out = chancreate(sizeof(Msg*), 0);
quit = chancreate(sizeof(char*), 0); quit = chancreate(sizeof(Msg*), 0);
forkc = chancreate(sizeof(ulong *), 0); forkc = chancreate(sizeof(void*), 0);
nread++; nread++;
procrfork(writer, (void*)pid, Stacksize, 0); procrfork(writer, (void*)pid, Stacksize, 0);
reader((void*)pid); reader((void*)pid);