]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add valgrind helper for daemon-reexec 2371/head
authorEvgeny Vereshchagin <evvers@ya.ru>
Tue, 19 Jan 2016 15:48:45 +0000 (15:48 +0000)
committerEvgeny Vereshchagin <evvers@ya.ru>
Thu, 21 Jan 2016 01:32:05 +0000 (01:32 +0000)
Inspired by https://github.com/systemd/systemd/issues/2187#issuecomment-165587140

src/basic/process-util.c
src/basic/process-util.h
src/core/main.c

index 4cc54a51fb43eb3a6695c0cd17c4a82364c97a32..4341d0093f93d7e267892dc0a1d3162775ac056a 100644 (file)
@@ -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",
index f4c44376241159f73dd7608f44ddad88cd0d2645..ac4d05e65fefebba857de19147b047d81409ab6c 100644 (file)
@@ -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);
index 2f9094f03a5c4c00c38a9b828c65917f8e5350be..27ba6af031300e11d51363b3df92b9a27e824cdd 100644 (file)
@@ -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);
                 }