]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Dump the debug buffer to libvirtd.log on fatal signal
authorDaniel Veillard <veillard@redhat.com>
Thu, 3 Mar 2011 09:41:44 +0000 (17:41 +0800)
committerDaniel Veillard <veillard@redhat.com>
Fri, 4 Mar 2011 14:43:55 +0000 (22:43 +0800)
In case of imminent crash or upon request (signal USR2),
dump the logging buffer to the libvirtd.log file for
post-mortem analysis
* daemon/libvirtd.c: create a sig_fatal() handler connected to
  SIGFPE SIGSEGV SIGILL SIGABRT SIGBUS and SIGUSR2, just dumping
  the log buffer using virLogEmergencyDumpAll

daemon/libvirtd.c

index c67fcb5dac140d24d9a17ba5f043323663c69775..a655190f94e2a7d607d1d63cf79ff673f77a162b 100644 (file)
@@ -246,6 +246,26 @@ static void sig_handler(int sig, siginfo_t * siginfo,
     errno = origerrno;
 }
 
+static void sig_fatal(int sig, siginfo_t * siginfo ATTRIBUTE_UNUSED,
+                      void* context ATTRIBUTE_UNUSED) {
+    struct sigaction sig_action;
+    int origerrno;
+
+    origerrno = errno;
+    virLogEmergencyDumpAll(sig);
+
+    /*
+     * If the signal is fatal, avoid looping over this handler
+     * by desactivating it
+     */
+    if (sig != SIGUSR2) {
+        sig_action.sa_flags = SA_SIGINFO;
+        sig_action.sa_handler = SIG_IGN;
+        sigaction(sig, &sig_action, NULL);
+    }
+    errno = origerrno;
+}
+
 static void qemudDispatchClientEvent(int watch, int fd, int events, void *opaque);
 static void qemudDispatchServerEvent(int watch, int fd, int events, void *opaque);
 static int qemudStartWorker(struct qemud_server *server, struct qemud_worker *worker);
@@ -3046,6 +3066,18 @@ daemonSetupSignals(struct qemud_server *server)
     sigaction(SIGQUIT, &sig_action, NULL);
     sigaction(SIGTERM, &sig_action, NULL);
 
+    /*
+     * catch fatal errors to dump a log, also hook to USR2 for dynamic
+     * debugging purposes or testing
+     */
+    sig_action.sa_sigaction = sig_fatal;
+    sigaction(SIGFPE, &sig_action, NULL);
+    sigaction(SIGSEGV, &sig_action, NULL);
+    sigaction(SIGILL, &sig_action, NULL);
+    sigaction(SIGABRT, &sig_action, NULL);
+    sigaction(SIGBUS, &sig_action, NULL);
+    sigaction(SIGUSR2, &sig_action, NULL);
+
     sig_action.sa_handler = SIG_IGN;
     sigaction(SIGPIPE, &sig_action, NULL);