From a9f35c4863623fa07563f8ab3a25a20ea9f79fba Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Thu, 3 Mar 2011 17:41:44 +0800 Subject: [PATCH] Dump the debug buffer to libvirtd.log on fatal signal 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 | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index c67fcb5dac..a655190f94 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -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);