diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
| commit | 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch) | |
| tree | c6e220ba61db3a6ea4052e6841296d829654e664 /utils/acid/rdebug.c | |
| parent | 46439007cf417cbd9ac8049bb4122c890097a0fa (diff) | |
20060303
Diffstat (limited to 'utils/acid/rdebug.c')
| -rw-r--r-- | utils/acid/rdebug.c | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/utils/acid/rdebug.c b/utils/acid/rdebug.c new file mode 100644 index 00000000..8903711e --- /dev/null +++ b/utils/acid/rdebug.c @@ -0,0 +1,274 @@ +#include <lib9.h> +#include <bio.h> +#include <ctype.h> +#include "mach.h" +#define Extern extern +#include "acid.h" +#include "../../include/rdbg.h" + +/* + * remote kernel debugging + */ + +enum { + chatty = 0 +}; + +static long myreadn(int, void*, long); +static int rproto(int, char*, int); + +void +remotemap(Map *m, int i) +{ + setmapio(m, i, remget, remput); +} + +/* + * send a /proc control message to remote pid, + * and await a reply + */ +int +sendremote(int pid, char *msg) +{ + int tag; + char dbg[RDBMSGLEN]; + + if(protodebug) + fprint(2, "sendremote: pid %d: %s\n", pid, msg); + if(strcmp(msg, "startstop") == 0) + tag = Tstartstop; + else if(strcmp(msg, "waitstop") == 0) + tag = Twaitstop; + else if(strcmp(msg, "start") == 0) + tag = Tstart; + else if(strcmp(msg, "stop") == 0) + tag = Tstop; + else if(strcmp(msg, "kill") == 0) + tag = Tkill; + else { + werrstr("invalid sendremote: %s", msg); + return -1; + } + memset(dbg, 0, sizeof(dbg)); + dbg[0] = tag; + dbg[1] = pid>>24; + dbg[2] = pid>>16; + dbg[3] = pid>>8; + dbg[4] = pid; + if(rproto(remfd, dbg, sizeof(dbg)) < 0) + return -1; + return 0; +} + +/* + * read a line from /proc/<pid>/<file> into buf + */ +int +remoteio(int pid, char *file, char *buf, int nb) +{ + char dbg[RDBMSGLEN]; + int tag; + + if(protodebug) + fprint(2, "remoteio %d: %s\n", pid, file); + memset(buf, nb, 0); + if(strcmp(file, "proc") == 0) + tag = Tproc; + else if(strcmp(file, "status") == 0) + tag = Tstatus; + else if(strcmp(file, "note") == 0) + tag = Trnote; + else { + werrstr("invalid remoteio: %s", file); + return -1; + } + memset(dbg, 0, sizeof(dbg)); + dbg[0] = tag; + dbg[1] = pid>>24; + dbg[2] = pid>>16; + dbg[3] = pid>>8; + dbg[4] = pid; + if(rproto(remfd, dbg, sizeof(dbg)) < 0) + return -1; + if(nb > sizeof(dbg)-1) + nb = sizeof(dbg)-1; + memmove(buf, dbg+1, nb); + return strlen(buf); +} + +int +remget(struct segment *s, ulong addr, long off, char *buf, int size) +{ + int n, t; + char dbg[RDBMSGLEN]; + + if (protodebug) + fprint(2, "remget addr %#lux off %#lux\n", addr, off); + for (t = 0; t < size; t += n) { + n = size; + if(n > 9) + n = 9; + memset(dbg, 0, sizeof(dbg)); + dbg[0] = Tmget; + dbg[1] = off>>24; + dbg[2] = off>>16; + dbg[3] = off>>8; + dbg[4] = off; + dbg[5] = n; + if(rproto(s->fd, dbg, sizeof(dbg)) < 0) { + werrstr("can't read address %#lux: %r", addr); + return -1; + } + memmove(buf, dbg+1, n); + buf += n; + } + return t; +} + +int +remput(struct segment *s, ulong addr, long off, char *buf, int size) +{ + int n, i, t; + char dbg[RDBMSGLEN]; + + if (protodebug) + fprint(2, "remput addr %#lux off %#lux\n", addr, off); + for (t = 0; t < size; t += n) { + n = size; + if(n > 4) + n = 4; + memset(dbg, 0, sizeof(dbg)); + dbg[0] = Tmput; + dbg[1] = off>>24; + dbg[2] = off>>16; + dbg[3] = off>>8; + dbg[4] = off; + dbg[5] = n; + for(i=0; i<n; i++) + dbg[6+i] = *buf++; + if(rproto(s->fd, dbg, sizeof(dbg)) < 0) { + werrstr("can't write address %#lux: %r", addr); + return -1; + } + } + return t; +} + +int +remcondset(char op, ulong val) +{ + char dbg[RDBMSGLEN]; + + if (protodebug) + fprint(2, "remcondset op %c val: %#lux\n", op, val); + memset(dbg, 0, sizeof(dbg)); + + dbg[0] = Tcondbreak; + dbg[1] = val>>24; + dbg[2] = val>>16; + dbg[3] = val>>8; + dbg[4] = val; + dbg[5] = op; + if(rproto(remfd, dbg, sizeof(dbg)) < 0) { + werrstr("can't set condbreak: %c %#lux: %r", op, val); + return -1; + } + return 0; +} + +int +remcondstartstop(int pid) +{ + char dbg[RDBMSGLEN]; + + if (protodebug) + fprint(2, "remcondstartstop pid %d\n", pid); + memset(dbg, 0, sizeof(dbg)); + + dbg[0] = Tstartstop; + dbg[1] = pid>>24; + dbg[2] = pid>>16; + dbg[3] = pid>>8; + dbg[4] = pid; + + if(rproto(remfd, dbg, sizeof(dbg)) < 0) { + werrstr("can't send Tstartstop"); + return -1; + } + + return dbg[1]; +} + +static int +rproto(int fd, char *buf, int nb) +{ + int tag; + + if (protodebug) { + int i; + print("rproto remote write fd %d bytes: %d\n", fd, nb); + for (i=0; i < nb; i++) { + print(" %2.2ux", buf[i]&0xFF); + } + print("\n"); + } + tag = buf[0]; + if(remote_write(fd, buf, nb) != nb || + myreadn(fd, buf, nb) != nb){ /* could set alarm */ + werrstr("remote i/o: %r"); + return -1; + } + if(buf[0] == Rerr){ + buf[nb-1] = 0; + werrstr("remote err: %s", buf+1); + return -1; + } + if(buf[0] != tag+1) { + werrstr("remote proto err: %.2ux", buf[0]&0xff); + return -1; + } + if(chatty) { + int i; + fprint(2, "remote [%d]: ", nb); + for(i=0; i<nb; i++) + fprint(2, " %.2ux", buf[i]&0xff); + fprint(2, "\n"); + } + return nb; +} + +/* + * this should probably be in lib9 as readn + */ +static long +myreadn(int f, void *av, long n) +{ + char *a; + long m, t; + + if (protodebug) { + print("remote read fd %d bytes: %ld", f, n); + } + a = av; + t = 0; + while(t < n){ + m = remote_read(f, a+t, n-t); + if(m < 0){ + if(t == 0) + return m; + break; + } + if (protodebug) { + print(" rtn: %ld\n", m); + if (m) { + int i; + + for (i=0; i < m; i++) + print(" %2.2ux", a[i+t]&0xFF); + print("\n"); + } + } + t += m; + } + return t; +} |
