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:
parent
d48dcf08aa
commit
059c85dd75
1 changed files with 52 additions and 44 deletions
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue