diff options
Diffstat (limited to 'src/daemon.h')
-rw-r--r-- | src/daemon.h | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/daemon.h b/src/daemon.h index 567e268..980cd64 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -279,3 +279,50 @@ int remove_job(const char *jobno, int runjob); */ struct job **get_jobs(void); + + +/** + * This block of code allows us to compile with DEBUG=valgrind + * or DEBUG=strace and have all exec:s be wrapped in + * valgrind --leak-check=full --show-leak-kinds=all or + * strace, respectively. Very useful for debugging. However, + * children do not inherit strace, so between forking and + * exec:ing we do not have strace. + */ +#if 1 && defined(DEBUG) +# if ((DEBUG == 2) || (DEBUG == 3)) +# ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" +__attribute__((__used__)) +# endif +# if DEBUG == 2 +# define DEBUGPROG "strace" +# else +# define DEBUGPROG "valgrind" +# endif +# define execl(path, _, ...) (execl)("/usr/bin/" DEBUGPROG, "/usr/bin/" DEBUGPROG, path, __VA_ARGS__) +# define execve(...) execve_(__VA_ARGS__) +static int +execve_(const char *path, char *const argv[], char *const envp[]) +{ + size_t n = 0; + char **new_argv = NULL; + int x = (DEBUG - 2) * 2, saved_errno; + while (argv[n++]); + t (!(new_argv = malloc((n + 1 + (size_t)x) * sizeof(char *)))); + new_argv[x] = "--show-leak-kinds=all"; + new_argv[1] = "--leak-check=full"; + new_argv[0] = "/usr/bin/" DEBUGPROG; + new_argv[1 + x] = path; + memcpy(new_argv + 2 + x, argv + 1, (n - 1) * sizeof(char *)); + (execve)(*new_argv, new_argv, envp); +fail: + return saved_errno = errno, free(new_argv), errno = saved_errno, -1; +} +# ifdef __GNUC__ +# pragma GCC diagnostic pop +# endif +# endif +#endif + |