Skip to content

Commit

Permalink
Avoid use of printfs when emitting. DRY.
Browse files Browse the repository at this point in the history
  • Loading branch information
jacereda committed Sep 25, 2015
1 parent 315a6c1 commit eaef8d7
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 94 deletions.
9 changes: 5 additions & 4 deletions unix/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ OS=$(shell uname -s)
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

Expand Down
38 changes: 24 additions & 14 deletions unix/fsatrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -24,8 +25,8 @@ dump(const char *path, char *p)
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);
Expand All @@ -34,11 +35,21 @@ dump(const char *path, char *p)
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
Expand All @@ -52,10 +63,8 @@ main(int argc, char **argv)
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++)
Expand All @@ -66,23 +75,24 @@ main(int argc, char **argv)
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);
Expand Down
130 changes: 54 additions & 76 deletions unix/fsatraceso.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,6 @@ static int s_fd;
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()
Expand All @@ -81,35 +53,63 @@ term()
}

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);
Expand All @@ -121,9 +121,7 @@ fopen64(const char *p, const char *m)
{
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);
Expand All @@ -135,9 +133,7 @@ open(const char *p, int f, mode_t m)
{
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);
Expand All @@ -149,9 +145,7 @@ open64(const char *p, int f, mode_t m)
{
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);
Expand All @@ -164,14 +158,11 @@ openat(int fd, const char *p, int f, mode_t m)
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;
}
Expand All @@ -182,14 +173,11 @@ openat64(int fd, const char *p, int f, mode_t m)
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;
}
Expand All @@ -202,9 +190,7 @@ rename(const char *p1, const char *p2)
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);
Expand All @@ -217,14 +203,11 @@ renameat(int fd1, const char *p1, int fd2, const char *p2)
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;
}
Expand All @@ -236,9 +219,7 @@ unlink(const char *p)
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);
Expand All @@ -251,15 +232,12 @@ unlinkat(int fd, const char *p, int f)
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);
Expand Down

0 comments on commit eaef8d7

Please sign in to comment.