Avoid use of printfs when emitting. DRY.
diff --git a/unix/Makefile b/unix/Makefile index 920e767..801a801 100644 --- a/unix/Makefile +++ b/unix/Makefile
@@ -2,12 +2,13 @@ ifeq ($(OS),Linux) PRGLIBS=-lrt SOLIBS=-ldl -lrt -else -LIBS= +endif +ifeq ($(OS),Darwin) +PRGLIBS= SOLIBS= -endif +endif -CC=cc -D_GNU_SOURCE -D_BSD_SOURCE=1 -std=c99 -Wall -O3 +CC=cc -D_GNU_SOURCE -D_BSD_SOURCE=1 -std=c99 -Wall -O2 -fomit-frame-pointer -fno-stack-protector -Wno-incompatible-pointer-types all: fsatrace fsatrace.so
diff --git a/unix/fsatrace.c b/unix/fsatrace.c index 2ad695c..fe90f1d 100644 --- a/unix/fsatrace.c +++ b/unix/fsatrace.c
@@ -6,6 +6,7 @@ #include <string.h> #include <stdlib.h> #include <unistd.h> +#include <stdarg.h> #include <fcntl.h> #include <limits.h> #include "fsatrace.h" @@ -24,8 +25,8 @@ fd = 1; if (fd < 0) fprintf(stderr, "Unable to open output file '%s'\n", path); - sz = *(size_t *) p; - r = write(fd, p + sizeof(size_t), sz); + sz = (size_t) * (unsigned *)p; + r = write(fd, p + sizeof(unsigned), sz); assert(r == sz); if (fd != 1) close(fd); @@ -34,11 +35,21 @@ unsigned long hash(unsigned char *str) { - unsigned long h = 5381; - int c; - while ((c = *str++)) - h = ((h << 5) + h) + c; - return h; + unsigned long h = 5381; + int c; + while ((c = *str++)) + h = ((h << 5) + h) + c; + return h; +} + +static void +fatal(const char *fmt,...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(EXIT_FAILURE); } int @@ -52,10 +63,8 @@ int rc = EXIT_FAILURE; int child; const char *out; - if (argc < 4 || strcmp(argv[2], "--")) { - fprintf(stderr, "Usage: %s <output> -- <cmdline>\n", argv[0]); - return rc; - } + if (argc < 4 || strcmp(argv[2], "--")) + fatal("Usage: %s <output> -- <cmdline>\n", argv[0]); out = argv[1]; snprintf(shname, sizeof(shname), "/%ld", hash((unsigned char *)out)); for (size_t i = 0, l = strlen(shname); i < l; i++) @@ -66,23 +75,24 @@ r = ftruncate(fd, LOGSZ); assert(!r); buf = mmap(0, LOGSZ, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - snprintf(so, sizeof(so), "%s.so", argv[0]); #ifdef __APPLE__ + snprintf(so, sizeof(so), "%s.dylib", argv[0]); setenv("DYLD_INSERT_LIBRARIES", so, 1); setenv("DYLD_FORCE_FLAT_NAMESPACE", "1", 1); #else + snprintf(so, sizeof(so), "%s.so", argv[0]); setenv("LD_PRELOAD", so, 1); #endif setenv(ENVOUT, shname, 1); child = fork(); if (!child) { execvp(argv[3], argv + 3); - assert(0); + fatal("Unable to execute command '%s'\n", argv[3]); } r = wait(&rc); assert(r >= 0); rc = WEXITSTATUS(rc); - if (!rc) + if (!rc || *out == '-') dump(out, buf); munmap(buf, LOGSZ); close(fd);
diff --git a/unix/fsatraceso.c b/unix/fsatraceso.c index 94cf27a..abb4edd 100644 --- a/unix/fsatraceso.c +++ b/unix/fsatraceso.c
@@ -34,34 +34,6 @@ static char *s_buf; static const int wmode = O_RDWR | O_WRONLY | O_APPEND | O_CREAT | O_TRUNC; -static int -good(const char *s, int sz) -{ - int i; - int bad = 0; - - for (i = 0; i < sz; i++) - bad += s[i] == 0; - return !bad; -} - -static void -swrite(const char *p, int sz) -{ - int g; - char *dst = s_buf + sizeof(size_t); - size_t *psofar = (size_t *) s_buf; - size_t sofar; - if (!s_buf) - return; - sofar = __sync_fetch_and_add(psofar, sz); - memcpy(dst + sofar, p, sz); - g = good(p, sz); - if (!g) - fprintf(stderr, "BAD: %s\n", p); - assert(g); -} - static void __attribute((constructor(101))) init() @@ -81,35 +53,63 @@ } static inline void +__attribute((noinline)) iemit(int c, const char *p1, const char *p2) { - char buf [10000]; - int sz = 0; - - sz += snprintf(buf, sizeof(buf) - 1 - sz, "%c|%s", c, p1); - if (p2) - sz += snprintf(buf + sz, sizeof(buf) - 1 - sz, "|%s", p2); - sz += snprintf(buf + sz, sizeof(buf) - 1 - sz, "\n"); - assert(sz < sizeof(buf) - 1); - buf[sz] = 0; - swrite(buf, sz); + char *dst = s_buf + sizeof(unsigned); + unsigned *psofar = (unsigned *)s_buf; + unsigned sofar; + unsigned sz; + unsigned s1; + unsigned s2; + char *p; + if (!s_buf) + return; + s1 = strlen(p1); + sz = s1 + 3; + if (p2) { + s2 = strlen(p2); + sz += s2 + 1; + } + sofar = __sync_fetch_and_add(psofar, sz); + p = dst + sofar; + *p++ = c; + *p++ = '|'; + memcpy(p, p1, s1); + p += s1; + if (p2) { + *p++ = '|'; + memcpy(p, p2, s2); + p += s2; + } + *p++ = '\n'; } static void +__attribute((noinline)) emit(int c, const char *p1) { char ap [PATH_MAX]; iemit(c, realpath(p1, ap), 0); } +static void +__attribute((noinline)) +resolv(void ** p, const char * n) { + if (!*p) + *p = dlsym(RTLD_NEXT, n); + assert(*p); +} + +#define R(f) resolv((void**)&o##f, #f) + FILE * fopen(const char *p, const char *m) { FILE *r; static FILE *(*ofopen) (const char *, const char *)= 0; - if (!ofopen) - ofopen = dlsym(RTLD_NEXT, "fopen"); - assert(ofopen); + // resolv(&ofopen, "fopen"); + R(fopen); r = ofopen(p, m); if (r) emit(strchr(m, 'r') ? 'r' : 'w', p); @@ -121,9 +121,7 @@ { FILE *r; static FILE *(*ofopen64) (const char *, const char *)= 0; - if (!ofopen64) - ofopen64 = dlsym(RTLD_NEXT, "fopen64"); - assert(ofopen64); + R(fopen64); r = ofopen64(p, m); if (r) emit(strchr(m, 'r') ? 'r' : 'w', p); @@ -135,9 +133,7 @@ { int r; static int (*oopen) (const char *, int, mode_t)= 0; - if (!oopen) - oopen = dlsym(RTLD_NEXT, "open"); - assert(oopen); + R(open); r = oopen(p, f, m); if (r >= 0) emit(f & wmode ? 'w' : 'r', p); @@ -149,9 +145,7 @@ { int r; static int (*oopen64) (const char *, int, mode_t)= 0; - if (!oopen64) - oopen64 = dlsym(RTLD_NEXT, "open64"); - assert(oopen64); + R(open64); r = oopen64(p, f, m); if (r >= 0) emit(f & wmode ? 'w' : 'r', p); @@ -164,14 +158,11 @@ int r; if (fd != AT_FDCWD) { static int (*oopenat) (int, const char *, int, mode_t)= 0; - if (!oopenat) - oopenat = dlsym(RTLD_NEXT, "openat"); - assert(oopenat); + R(openat); r = oopenat(fd, p, f, m); if (r >= 0) iemit(f & wmode ? 'W' : 'R', p, 0); - } - else + } else r = open(p, f, m); return r; } @@ -182,14 +173,11 @@ int r; if (fd != AT_FDCWD) { static int (*oopenat64) (int, const char *, int, mode_t)= 0; - if (!oopenat64) - oopenat64 = dlsym(RTLD_NEXT, "openat64"); - assert(oopenat64); + R(openat64); r = oopenat64(fd, p, f, m); if (r >= 0) iemit(f & wmode ? 'W' : 'R', p, 0); - } - else + } else r = open64(p, f, m); return r; } @@ -202,9 +190,7 @@ char b2 [PATH_MAX]; char *rp1 = realpath(p1, b1); static int (*orename) (const char *, const char *)= 0; - if (!orename) - orename = dlsym(RTLD_NEXT, "rename"); - assert(orename); + R(rename); r = orename(p1, p2); if (!r) iemit('m', realpath(p2, b2), rp1); @@ -217,14 +203,11 @@ int r; if (fd1 != AT_FDCWD || fd2 != AT_FDCWD) { static int (*orenameat) (const char *, const char *)= 0; - if (!orenameat) - orenameat = dlsym(RTLD_NEXT, "renameat"); - assert(orenameat); + R(renameat); r = orenameat(p1, p2); if (!r) iemit('R', p2, p1); - } - else + } else r = rename(p1, p2); return r; } @@ -236,9 +219,7 @@ char b [PATH_MAX]; char *rp = realpath(p, b); static int (*ounlink) (const char *)= 0; - if (!ounlink) - ounlink = dlsym(RTLD_NEXT, "unlink"); - assert(ounlink); + R(unlink); r = ounlink(p); if (!r) iemit('d', rp, 0); @@ -251,15 +232,12 @@ int r; if (fd != AT_FDCWD) { static int (*ounlinkat) (int fd, const char *p, int f); - if (!ounlinkat) - ounlinkat = dlsym(RTLD_NEXT, "unlinkat"); - assert(ounlinkat); + R(unlinkat); r = ounlinkat(fd, p, f); if (!r) iemit('D', p, 0); assert(0); - } - else if (f & AT_REMOVEDIR) + } else if (f & AT_REMOVEDIR) r = rmdir(p); else r = unlink(p);