diff options
author | aiju <devnull@localhost> | 2018-11-10 13:46:16 +0000 |
---|---|---|
committer | aiju <devnull@localhost> | 2018-11-10 13:46:16 +0000 |
commit | e6d99771e5c1eef3f69fc847253d4709ffaa84be (patch) | |
tree | 16161401edc25c084ad24533519e094716965635 /sys/src/cmd/dtracy/dtracy.c | |
parent | 8c097ae84a500eae9c8e4ee21b7b3ea8f8d23259 (diff) |
adding dtracy (crude early version)
Diffstat (limited to 'sys/src/cmd/dtracy/dtracy.c')
-rw-r--r-- | sys/src/cmd/dtracy/dtracy.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/sys/src/cmd/dtracy/dtracy.c b/sys/src/cmd/dtracy/dtracy.c new file mode 100644 index 000000000..8585180f2 --- /dev/null +++ b/sys/src/cmd/dtracy/dtracy.c @@ -0,0 +1,224 @@ +#include <u.h> +#include <libc.h> +#include <dtracy.h> +#include <bio.h> +#include "dat.h" +#include "fns.h" + +char *dtracyroot = "#Δ"; +int dtracyno; +int ctlfd, buffd; + +int +min(int a, int b) +{ + return a < b ? a : b; +} + +int +max(int a, int b) +{ + return a < b ? b : a; +} + +void * +emalloc(ulong n) +{ + void *v; + + v = malloc(n); + if(v == nil) sysfatal("malloc: %r"); + memset(v, 0, n); + setmalloctag(v, getcallerpc(&n)); + return v; +} + +void * +erealloc(void *v, ulong n) +{ + v = realloc(v, n); + if(n != 0){ + if(v == nil) sysfatal("realloc: %r"); + setrealloctag(v, getcallerpc(&v)); + } + return v; +} + +void * +dtmalloc(ulong n) +{ + return emalloc(n); +} + +void +dtfree(void *v) +{ + free(v); +} + +void +defvar(char *name, int idx, Type *ty) +{ + Symbol *s; + + s = getsym(name); + s->type = SYMVAR; + s->idx = idx; + s->typ = ty; +} + +void +globvars(void) +{ + defvar("arg0", DTV_ARG0, type(TYPINT, 8, 1)); + defvar("arg1", DTV_ARG1, type(TYPINT, 8, 1)); + defvar("arg2", DTV_ARG2, type(TYPINT, 8, 1)); + defvar("arg3", DTV_ARG3, type(TYPINT, 8, 1)); + defvar("arg4", DTV_ARG4, type(TYPINT, 8, 1)); + defvar("arg5", DTV_ARG5, type(TYPINT, 8, 1)); + defvar("arg6", DTV_ARG6, type(TYPINT, 8, 1)); + defvar("arg7", DTV_ARG7, type(TYPINT, 8, 1)); + defvar("arg8", DTV_ARG8, type(TYPINT, 8, 1)); + defvar("arg9", DTV_ARG9, type(TYPINT, 8, 1)); + defvar("pid", DTV_PID, type(TYPINT, 4, 1)); + defvar("machno", DTV_MACHNO, type(TYPINT, 4, 1)); + defvar("time", DTV_TIME, type(TYPINT, 8, 0)); + defvar("probe", DTV_PROBE, type(TYPSTRING)); +} + +int +setup(void) +{ + char buf[512]; + char *p; + int n; + + snprint(buf, sizeof(buf), "%s/clone", dtracyroot); + ctlfd = open(buf, ORDWR); + if(ctlfd < 0) return -1; + n = read(ctlfd, buf, sizeof(buf) - 1); + if(n < 0) return -1; + buf[n] = 0; + dtracyno = strtol(buf, &p, 10); + if(p == buf || *p != 0){ + werrstr("expected number reading from ctl"); + return -1; + } + snprint(buf, sizeof(buf), "%s/%d/buf", dtracyroot, dtracyno); + buffd = open(buf, OREAD); + if(buffd < 0) return -1; + return 0; +} + +int +progcopy(void) +{ + char buf[512]; + int fd; + char *prog; + Fmt f; + + fmtstrinit(&f); + packclauses(&f); + prog = fmtstrflush(&f); + snprint(buf, sizeof(buf), "%s/%d/prog", dtracyroot, dtracyno); + fd = open(buf, OWRITE); + if(fd < 0) return -1; + if(write(fd, prog, strlen(prog)) < 0){ + close(fd); + return -1; + } + close(fd); + return 0; +} + +int +epidread(void) +{ + char buf[512]; + Biobuf *bp; + char *s; + char *f[5]; + int a, b, c; + + snprint(buf, sizeof(buf), "%s/%d/epid", dtracyroot, dtracyno); + bp = Bopen(buf, OREAD); + if(bp == nil) return -1; + for(; s = Brdstr(bp, '\n', 1), s != nil; free(s)){ + if(tokenize(s, f, nelem(f)) != 4) + goto err; + a = atoi(f[0]); + b = atoi(f[1]); + c = atoi(f[2]); + addepid(a, b, c, f[3]); + } + return 0; +err: + werrstr("epidread: invalid format"); + free(s); + return -1; + +} + +void +bufread(Biobuf *bp) +{ + static uchar buf[65536]; + int n; + + n = read(buffd, buf, sizeof(buf)); + if(n < 0) sysfatal("bufread: %r"); + if(parsebuf(buf, n, bp) < 0) + sysfatal("parsebuf: %r"); + Bflush(bp); +} + +static void +usage(void) +{ + fprint(2, "usage: %s [ -cd ] script\n", argv0); + exits("usage"); +} + +int dflag; + +void +main(int argc, char **argv) +{ + Biobuf *out; + + dflag = 0; + ARGBEGIN { + case 'd': dflag = 1; break; + default: usage(); + } ARGEND; + if(argc != 1) usage(); + + fmtinstall(L'α', nodetfmt); + fmtinstall('t', typetfmt); + fmtinstall(L'I', dtefmt); + fmtinstall(L'τ', typefmt); + fmtinstall(L'ε', nodefmt); + lexinit(); + lexstring(argv[0]); + globvars(); + yyparse(); + if(errors != 0) + exits("errors"); + if(dflag) + dump(); + else{ + if(setup() < 0) + sysfatal("setup: %r"); + if(progcopy() < 0) + sysfatal("progcopy: %r"); + if(epidread() < 0) + sysfatal("epidread: %r"); + fprint(ctlfd, "go"); + out = Bfdopen(1, OWRITE); + if(out == nil) sysfatal("Bfdopen: %r"); + for(;;) + bufread(out); + } + exits(nil); +} |