diff options
-rw-r--r-- | src/basic/process-util.c | 20 | ||||
-rw-r--r-- | src/basic/process-util.h | 2 | ||||
-rw-r--r-- | src/core/main.c | 9 |
3 files changed, 31 insertions, 0 deletions
diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 4cc54a51fb..4341d0093f 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -33,6 +33,9 @@ #include <sys/wait.h> #include <syslog.h> #include <unistd.h> +#ifdef HAVE_VALGRIND_VALGRIND_H +#include <valgrind/valgrind.h> +#endif #include "alloc-util.h" #include "escape.h" @@ -730,6 +733,23 @@ const char* personality_to_string(unsigned long p) { return NULL; } +void valgrind_summary_hack(void) { +#ifdef HAVE_VALGRIND_VALGRIND_H + if (getpid() == 1 && RUNNING_ON_VALGRIND) { + pid_t pid; + pid = raw_clone(SIGCHLD, NULL); + if (pid < 0) + log_emergency_errno(errno, "Failed to fork off valgrind helper: %m"); + else if (pid == 0) + exit(EXIT_SUCCESS); + else { + log_info("Spawned valgrind helper as PID "PID_FMT".", pid); + (void) wait_for_terminate(pid, NULL); + } + } +#endif +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", diff --git a/src/basic/process-util.h b/src/basic/process-util.h index f4c4437624..ac4d05e65f 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -98,3 +98,5 @@ int sched_policy_from_string(const char *s); #define PTR_TO_PID(p) ((pid_t) ((uintptr_t) p)) #define PID_TO_PTR(p) ((void*) ((uintptr_t) p)) + +void valgrind_summary_hack(void); diff --git a/src/core/main.c b/src/core/main.c index 2f9094f03a..27ba6af031 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1968,6 +1968,15 @@ finish: (void) clearenv(); assert(i <= args_size); + + /* + * We want valgrind to print its memory usage summary before reexecution. + * Valgrind won't do this is on its own on exec(), but it will do it on exit(). + * Hence, to ensure we get a summary here, fork() off a child, let it exit() cleanly, + * so that it prints the summary, and wait() for it in the parent, before proceeding into the exec(). + */ + valgrind_summary_hack(); + (void) execv(args[0], (char* const*) args); } |