From fef203e6174f9d1af1cba57c4450876f2de259a6 Mon Sep 17 00:00:00 2001 From: saleha-muzammil Date: Sun, 28 Jul 2024 03:01:22 +0500 Subject: [PATCH 1/2] some percentage of never ending errord --- .vscode/settings.json | 3 + probe_src/libprobe/generated/libc_hooks.c | 8 +++ probe_src/libprobe/generated/libc_hooks.h | 18 ++--- probe_src/libprobe/src/fd_table.c | 88 +++++++++++++++++++---- probe_src/libprobe/src/global_state.c | 5 ++ probe_src/libprobe/src/lib.c | 6 -- probe_src/libprobe/src/lookup_on_path.c | 3 + probe_src/libprobe/src/prov_buffer.c | 23 ++++++ probe_src/libprobe/src/prov_enable.c | 1 + probe_src/libprobe/src/prov_ops.c | 9 +++ probe_src/libprobe/src/util.c | 17 +++++ 11 files changed, 150 insertions(+), 31 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..fc4c15b8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "C_Cpp.errorSquiggles": "enabled" +} \ No newline at end of file diff --git a/probe_src/libprobe/generated/libc_hooks.c b/probe_src/libprobe/generated/libc_hooks.c index 417e8b9c..549c0b00 100644 --- a/probe_src/libprobe/generated/libc_hooks.c +++ b/probe_src/libprobe/generated/libc_hooks.c @@ -1,4 +1,12 @@ +#define _GNU_SOURCE +#include "libc_hooks.h" #include +#include +#include +#include +#include +#define __type_mode_t mode_t + void init_function_pointers() { unwrapped_fopen = dlsym(RTLD_NEXT, "fopen"); diff --git a/probe_src/libprobe/generated/libc_hooks.h b/probe_src/libprobe/generated/libc_hooks.h index 57a7f6ab..90929d50 100644 --- a/probe_src/libprobe/generated/libc_hooks.h +++ b/probe_src/libprobe/generated/libc_hooks.h @@ -2,12 +2,8 @@ #include #include #include -#include -#include -#include #include -#define LIBC_HOOKS_H -#define _GNU_SOURCE +#include static FILE * (*unwrapped_fopen)(const char *filename, const char *opentype); static FILE * (*unwrapped_freopen)(const char *filename, const char *opentype, FILE *stream); @@ -20,8 +16,8 @@ static int (*unwrapped_close)(int filedes); static int (*unwrapped_close_range)(unsigned int lowfd, unsigned int maxfd, int flags); static void (*unwrapped_closefrom)(int lowfd); static int (*unwrapped_dup)(int old); -static int (*unwrapped_dup2)(int old, int new); -static int (*unwrapped_dup3)(int old, int new, int flags); +static int (*unwrapped_dup2)(int old, int new_); +static int (*unwrapped_dup3)(int old, int new_, int flags); static int (*unwrapped_fcntl)(int filedes, int command, ...); static int (*unwrapped_chdir)(const char *filename); static int (*unwrapped_fchdir)(int filedes); @@ -89,9 +85,9 @@ static FILE * (*unwrapped_tmpfile64)(); static char * (*unwrapped_tmpnam)(char *result); static char * (*unwrapped_tmpnam_r)(char *result); static char * (*unwrapped_tempnam)(const char *dir, const char *prefix); -static char * (*unwrapped_mktemp)(char *template); -static int (*unwrapped_mkstemp)(char *template); -static char * (*unwrapped_mkdtemp)(char *template); +static char * (*unwrapped_mktemp)(char *template_); +static int (*unwrapped_mkstemp)(char *template_); +static char * (*unwrapped_mkdtemp)(char *template_); static int (*unwrapped_execv)(const char *filename, char * const argv[]); static int (*unwrapped_execl)(const char *filename, const char *arg0, ...); static int (*unwrapped_execve)(const char *filename, char * const argv[], char * const env[]); @@ -117,4 +113,4 @@ static FILE * (*unwrapped_fopen64)(const char *filename, const char *opentype); static FILE * (*unwrapped_freopen64)(const char *filename, const char *opentype, FILE *stream); static int (*unwrapped_openat64)(int dirfd, const char *filename, int flags, ...); static int (*unwrapped_open64)(const char *filename, int flags, ...); -static int (*unwrapped_create64)(const char *filename, mode_t mode); +static int (*unwrapped_create64)(const char *filename, mode_t mode); \ No newline at end of file diff --git a/probe_src/libprobe/src/fd_table.c b/probe_src/libprobe/src/fd_table.c index 0118ae63..6e40c15f 100644 --- a/probe_src/libprobe/src/fd_table.c +++ b/probe_src/libprobe/src/fd_table.c @@ -1,3 +1,53 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define BORROWED +#define OWNED + +#ifndef likely +#define likely(x) __builtin_expect((x), 1) +#endif + +#ifndef unlikely +#define unlikely(x) __builtin_expect((x), 0) +#endif + +#define EXPECT(expected_value, expr) \ + do { \ + if ((expr) != (expected_value)) { \ + fprintf(stderr, "Error: Expected %d but got %d at %s:%d\n", (expected_value), (expr), __FILE__, __LINE__); \ + abort(); \ + } \ + } while (0) + +#define EXPECT_NONNULL(ptr) \ + do { \ + if ((ptr) == NULL) { \ + fprintf(stderr, "Error: NULL pointer encountered at %s:%d\n", __FILE__, __LINE__); \ + abort(); \ + } \ + } while (0) + +#define DEBUG(fmt, ...) \ + do { \ + fprintf(stderr, "DEBUG: %s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +typedef struct { + int inode; + int device; + int file_type; +} InodeTriple; /* * This file is responsible for tracking the process-global mapping between * file-descriptors and file paths. @@ -40,7 +90,13 @@ static void __fd_table_ensure_capacity(int mapped_fd) { * * Note that this has to be zero-initialized, otherwise we won't know which __fd_table entries are populated. * */ - __fd_table = EXPECT_NONNULL(realloc(__fd_table, new_fd_table_capacity * sizeof(*__fd_table))); + void* new_fd_table = realloc(__fd_table, new_fd_table_capacity * sizeof(*__fd_table)); + + // Check if allocation was successful + EXPECT_NONNULL(new_fd_table); + + __fd_table = new_fd_table; + // __fd_table = EXPECT_NONNULL(realloc(__fd_table, new_fd_table_capacity * sizeof(*__fd_table))); memset(__fd_table + __fd_table_capacity, 0, new_fd_table_capacity - __fd_table_capacity); /* Special case going from 0 to n. Must initialize process-global AT_FDCWD */ @@ -101,11 +157,11 @@ static void __fd_table_ensure_capacity(int mapped_fd) { * This is borrowed because the lifetime of normalized path will be bound by the lifetime of Op in the Op buffer * But the lifetime of our copy of it is bound by the lifetime of fd_table * */ -static void fd_table_associate(int fd, int dirfd, BORROWED const char* path, struct InodeTriple inode_triple) { +static void fd_table_associate(int fd, int dirfd, BORROWED const char* path, InodeTriple inode_triple) { DEBUG("fd_table: %d = openat(%d, \"%s\")", fd, dirfd, path); fd = __map_fd(fd); dirfd = __map_fd(dirfd); - EXPECT(== 0, pthread_rwlock_wrlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_wrlock(&__fd_table_lock)); __fd_table_ensure_capacity(fd); /* * Somehow, __fd_table[fd].path assertion does not always pass. @@ -117,7 +173,9 @@ static void fd_table_associate(int fd, int dirfd, BORROWED const char* path, str /* assert(!__fd_table[fd].path); */ /* This allocation is freed by fd_table_close if the tracee properly closes this file or never freed otherwise. * The tracee would likely run out of FDs if they didn't close their files. */ - __fd_table[fd].path = EXPECT_NONNULL(strndup(path, PATH_MAX)); + __fd_table[fd].path = strndup(path, PATH_MAX); + EXPECT_NONNULL(__fd_table[fd].path); // Check for NULL pointer + // __fd_table[fd].path = EXPECT_NONNULL(strndup(path, PATH_MAX)); __fd_table[fd].dirfd = __unmap_fd(dirfd); /* Capture dirfd version before doing version++ * Just in case fd == dirfd, as in chdir("foo") */ @@ -125,32 +183,32 @@ static void fd_table_associate(int fd, int dirfd, BORROWED const char* path, str __fd_table[fd].fd = __unmap_fd(fd); /* __fd_table[fd].inode_triple = inode_triple; */ __fd_table[fd].version++; - EXPECT(== 0, pthread_rwlock_unlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_unlock(&__fd_table_lock)); } static void fd_table_close(int fd) { DEBUG("fd_table: close(%d /* = openat(%d, \"%s\") */)", fd, __fd_table[__map_fd(fd)].dirfd, __fd_table[__map_fd(fd)].path); fd = __map_fd(fd); - EXPECT(== 0, pthread_rwlock_wrlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_wrlock(&__fd_table_lock)); assert(0 <= fd && fd < __fd_table_capacity && __fd_table[fd].path); free((char*) __fd_table[fd].path); __fd_table[fd].path = NULL; - EXPECT(== 0, pthread_rwlock_unlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_unlock(&__fd_table_lock)); } static size_t fd_table_size() { - EXPECT(== 0, pthread_rwlock_rdlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_rdlock(&__fd_table_lock)); int ret = __fd_table_capacity; - EXPECT(== 0, pthread_rwlock_unlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_unlock(&__fd_table_lock)); return (ret == 0) ? 0 : __unmap_fd(ret); } static bool fd_table_is_used(int fd) { fd = __map_fd(fd); - EXPECT(== 0, pthread_rwlock_rdlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_rdlock(&__fd_table_lock)); assert(0 <= fd && fd < __fd_table_capacity && __fd_table[fd].fd == __unmap_fd(fd)); bool ret = (bool) __fd_table[fd].path; - EXPECT(== 0, pthread_rwlock_unlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_unlock(&__fd_table_lock)); return ret; } @@ -158,16 +216,18 @@ void fd_table_dup(int oldfd, int newfd) { DEBUG("fd_table: dup2(%d, %d)", oldfd, newfd); oldfd = __map_fd(oldfd); newfd = __map_fd(newfd); - EXPECT(== 0, pthread_rwlock_wrlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_wrlock(&__fd_table_lock)); assert(0 <= oldfd && oldfd < __fd_table_capacity && __fd_table[oldfd].path && __fd_table[oldfd].fd == __unmap_fd(oldfd)); assert(0 <= newfd && !__fd_table[newfd].path); __fd_table_ensure_capacity(newfd); /* This allocation is freed by fd_table_close if the tracee properly closes this file or never freed otherwise. * The tracee would likely run out of FDs if they didn't close their files. */ - __fd_table[newfd].path = EXPECT_NONNULL(strndup(__fd_table[oldfd].path, PATH_MAX)); + __fd_table[newfd].path = strndup(__fd_table[oldfd].path, PATH_MAX); + EXPECT_NONNULL(__fd_table[newfd].path); + // __fd_table[newfd].path = EXPECT_NONNULL(strndup(__fd_table[oldfd].path, PATH_MAX)); __fd_table[newfd].dirfd = __fd_table[oldfd].dirfd; __fd_table[newfd].dirfd_version = __fd_table[oldfd].dirfd_version; __fd_table[newfd].fd = __unmap_fd(newfd); /* __fd_table[newfd].inode_triple = __fd_table[oldfd].inode_triple; */ - EXPECT(== 0, pthread_rwlock_unlock(&__fd_table_lock)); + EXPECT(0, pthread_rwlock_unlock(&__fd_table_lock)); } diff --git a/probe_src/libprobe/src/global_state.c b/probe_src/libprobe/src/global_state.c index 2a7ebe1b..b6750c55 100644 --- a/probe_src/libprobe/src/global_state.c +++ b/probe_src/libprobe/src/global_state.c @@ -1,3 +1,8 @@ +#include +#include +#include +#include +#include /* * For each member of global state $X of type $T, we have * diff --git a/probe_src/libprobe/src/lib.c b/probe_src/libprobe/src/lib.c index 4c702c05..a245e74b 100644 --- a/probe_src/libprobe/src/lib.c +++ b/probe_src/libprobe/src/lib.c @@ -1,14 +1,9 @@ #define _GNU_SOURCE #include #include -#include #include -#include -#include #include -#include #include -#include #include #include #include @@ -22,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/probe_src/libprobe/src/lookup_on_path.c b/probe_src/libprobe/src/lookup_on_path.c index 66e53526..c7be83db 100644 --- a/probe_src/libprobe/src/lookup_on_path.c +++ b/probe_src/libprobe/src/lookup_on_path.c @@ -5,6 +5,9 @@ #include #include #include +#include +#define BORROWED + static bool lookup_on_path(BORROWED const char* bin_name, BORROWED char* bin_path) { const char* path_segment_start = getenv("PATH"); diff --git a/probe_src/libprobe/src/prov_buffer.c b/probe_src/libprobe/src/prov_buffer.c index d6189813..034e0f6c 100644 --- a/probe_src/libprobe/src/prov_buffer.c +++ b/probe_src/libprobe/src/prov_buffer.c @@ -1,3 +1,26 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CLONE_VFORK +#define CLONE_VFORK 0x00004000 +#endif + +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif + +#define clone_op_code 1 +#define exec_op_code 2 + static void prov_log_save() { /* * Before I was using mmap-arena, I needed to explicitly save stuff. diff --git a/probe_src/libprobe/src/prov_enable.c b/probe_src/libprobe/src/prov_enable.c index c08dcef7..34085778 100644 --- a/probe_src/libprobe/src/prov_enable.c +++ b/probe_src/libprobe/src/prov_enable.c @@ -1,3 +1,4 @@ +#include /* * TODO: Do I really need prov_log_disable? * diff --git a/probe_src/libprobe/src/prov_ops.c b/probe_src/libprobe/src/prov_ops.c index 60c26259..54a6c31e 100644 --- a/probe_src/libprobe/src/prov_ops.c +++ b/probe_src/libprobe/src/prov_ops.c @@ -8,6 +8,15 @@ #include #include #include +#define BORROWED +#ifndef likely +#define likely(x) __builtin_expect((x), 1) +#endif + +#ifndef unlikely +#define unlikely(x) __builtin_expect((x), 0) +#endif + static struct Path create_path_lazy(int dirfd, BORROWED const char* path, int flags) { if (likely(prov_log_is_enabled())) { diff --git a/probe_src/libprobe/src/util.c b/probe_src/libprobe/src/util.c index fb207b39..443bdeef 100644 --- a/probe_src/libprobe/src/util.c +++ b/probe_src/libprobe/src/util.c @@ -1,3 +1,20 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define BORROWED + /* * OWNED/BORROWED determins who is responsible for freeing a pointer received or returned by a function-call. * Obviously, this is inspired by Rust. From ecbb6e8ea2433c165586298c196b4613b1f9141f Mon Sep 17 00:00:00 2001 From: Saleha Muzammil <84681153+saleha-muzammil@users.noreply.github.com> Date: Sat, 3 Aug 2024 20:59:53 +0500 Subject: [PATCH 2/2] Update prov_buffer.c --- probe_src/libprobe/src/prov_buffer.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/probe_src/libprobe/src/prov_buffer.c b/probe_src/libprobe/src/prov_buffer.c index 034e0f6c..ced514f2 100644 --- a/probe_src/libprobe/src/prov_buffer.c +++ b/probe_src/libprobe/src/prov_buffer.c @@ -10,17 +10,10 @@ #include #include -#ifndef CLONE_VFORK -#define CLONE_VFORK 0x00004000 -#endif - #ifndef likely #define likely(x) __builtin_expect(!!(x), 1) #endif -#define clone_op_code 1 -#define exec_op_code 2 - static void prov_log_save() { /* * Before I was using mmap-arena, I needed to explicitly save stuff.