Skip to content

Commit

Permalink
[WIP] Fix trace-nix for nix-2.19+ and lix
Browse files Browse the repository at this point in the history
  • Loading branch information
xzfc committed Nov 11, 2024
1 parent 4aff21d commit c94ce00
Showing 1 changed file with 82 additions and 25 deletions.
107 changes: 82 additions & 25 deletions nix-trace/trace-nix.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ static int enable(const char *);
static void hash_dir(char[static LEN * 2 + 1], DIR *);
static void hash_file(char[static LEN * 2 + 1], int);
static void print_log(char, const char *, const char *);
static void print_stat(int result, const char *path, struct stat *sb);
static void print_open(int, const char *, int, int);
static void print_stat(char, int, const char *, mode_t, off64_t);
static int strcmp_qsort(const void *, const void *);

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -140,16 +141,28 @@ static void __attribute__((constructor)) init() {

#endif

WRAPPER(int, stat, (const char *path, struct stat *sb)) {
int result = REAL(stat)(path, sb);
print_stat('s', result, path, sb->st_mode, sb->st_size);
return result;
}

WRAPPER(int, lstat, (const char *path, struct stat *sb)) {
int result = REAL(lstat)(path, sb);
print_stat(result, path, sb);
print_stat('s', result, path, sb->st_mode, sb->st_size);
return result;
}

WRAPPER(int, lstat64, (const char *path, struct stat64 *sb)) {
int result = REAL(lstat64)(path, sb);
print_stat('s', result, path, sb->st_mode, sb->st_size);
return result;
}

#ifdef __linux__
WRAPPER(int, __lxstat, (int ver, const char *path, struct stat *sb)) {
int result = REAL(__lxstat)(ver, path, sb);
print_stat(result, path, sb);
print_stat('s', result, path, sb->st_mode, sb->st_size);
return result;
}
#endif
Expand All @@ -161,17 +174,18 @@ WRAPPER(int, open, (const char *path, int flags, ...)) {
va_end(args);

int fd = REAL(open)(path, flags, mode);
print_open(fd, path, flags, mode);
return fd;
}

if (flags == (O_RDONLY | O_CLOEXEC) && enable(path)) {
if (fd == -1) {
print_log('f', path, "-");
} else {
char digest[LEN * 2 + 1];
hash_file(digest, fd);
print_log('f', path, digest);
}
}
WRAPPER(int, open64, (const char *path, int flags, ...)) {
va_list args;
va_start(args, flags);
int mode = va_arg(args, int);
va_end(args);

int fd = REAL(open64)(path, flags, mode);
print_open(fd, path, flags, mode);
return fd;
}

Expand All @@ -189,6 +203,35 @@ WRAPPER(DIR *, opendir, (const char *path)) {
return dirp;
}

WRAPPER(int, openat, (int dirfd, const char *path, int flags, ...)) {
va_list args;
va_start(args, flags);
int mode = va_arg(args, int);
va_end(args);

int fd = REAL(openat)(dirfd, path, flags, mode);

if (dirfd == AT_FDCWD && flags == (O_RDONLY | O_CLOEXEC | O_DIRECTORY) &&
enable(path)) {
if (fd == -1) {
print_log('d', path, "-");
} else {
char digest[LEN * 2 + 1];
int fd2 = dup(fd);
if (fd2 == -1)
FATAL();
DIR *dirp = fdopendir(fd2);
if (dirp == NULL)
FATAL();
hash_dir(digest, dirp);
print_log('d', path, digest);
closedir(dirp);
}
}

return fd;
}

WRAPPER(int, mkdir, (const char *path, mode_t mode)) {
int result = REAL(mkdir)(path, mode);
if (result == 0 && *tmp_prefix &&
Expand Down Expand Up @@ -245,7 +288,8 @@ WRAPPER(int, unlinkat, (int dirfd, const char *path, int flags)) {
////////////////////////////////////////////////////////////////////////////////

static int enable(const char *path) {
if (log_f == NULL || (*path != '/' && strcmp(path, "shell.nix")))
if (log_f == NULL || (*path != '/' && strcmp(path, "default.nix") &&
strcmp(path, "shell.nix")))
return 0;

static const char *ignored_paths[] = {
Expand All @@ -272,32 +316,45 @@ static int enable(const char *path) {
return 1;
}

static void print_stat(int result, const char *path, struct stat *sb) {
static void print_stat(char op, int result, const char *path, mode_t st_mode,
off64_t st_size) {
static char *buf = NULL;
static off_t buf_len = 0;

if (enable(path)) {
if (result != 0) {
print_log('s', path, "-");
} else if (S_ISLNK(sb->st_mode)) {
print_log(op, path, "-");
} else if (S_ISLNK(st_mode)) {
LOCK(buf_mutex);
if (buf_len < sb->st_size + 2) {
buf_len = sb->st_size + 2;
if (buf_len < st_size + 2) {
buf_len = st_size + 2;
buf = realloc(buf, buf_len);
if (buf == NULL)
FATAL();
}
ssize_t link_len = readlink(path, buf + 1, sb->st_size);
if (link_len < 0 || link_len != sb->st_size)
ssize_t link_len = readlink(path, buf + 1, st_size);
if (link_len < 0 || link_len != st_size)
FATAL();
buf[0] = 'l';
buf[sb->st_size + 1] = 0;
print_log('s', path, buf);
buf[st_size + 1] = 0;
print_log(op, path, buf);
UNLOCK(buf_mutex);
} else if (S_ISDIR(sb->st_mode)) {
print_log('s', path, "d");
} else if (S_ISDIR(st_mode)) {
print_log(op, path, "d");
} else {
print_log(op, path, "+");
}
}
}

static void print_open(int fd, const char *path, int flags, int mode) {
if ((flags & ~O_NOFOLLOW) == (O_RDONLY | O_CLOEXEC) && enable(path)) {
if (fd == -1) {
print_log('f', path, "-");
} else {
print_log('s', path, "+");
char digest[LEN * 2 + 1];
hash_file(digest, fd);
print_log('f', path, digest);
}
}
}
Expand Down

0 comments on commit c94ce00

Please sign in to comment.