[sheepdog] [PATCH] util: dump ucontext in crash handlers

Hitoshi Mitake mitake.hitoshi at gmail.com
Wed May 1 11:30:56 CEST 2013


Current crash handlers (of sheep, collie, and logger) don't dump
register status when the signal rises. This patch let them dump the
information. I believe especially RIP is useful for debugging.

Example of output:
May 01 18:23:07 [main] dump_mcontext(397) register status:
May 01 18:23:07 [main] dump_mcontext(399) 	RIP: 0x4046ab
May 01 18:23:07 [main] dump_mcontext(400) 	RSP: 0x7fff2ced9120
May 01 18:23:07 [main] dump_mcontext(401) 	RBP: 0x1
May 01 18:23:07 [main] dump_mcontext(402) 	RFLAGS: 0x10246
May 01 18:23:07 [main] dump_mcontext(404) 	RAX: 0x5
May 01 18:23:07 [main] dump_mcontext(405) 	RBX: 0x7fff2ceda348
May 01 18:23:07 [main] dump_mcontext(406) 	RCX: 0x0
May 01 18:23:07 [main] dump_mcontext(407) 	RDX: 0x0
May 01 18:23:07 [main] dump_mcontext(408) 	R8: 0x7fff2ced8fd0
May 01 18:23:07 [main] dump_mcontext(409) 	R9: 0x7f6fa31ef0e0
May 01 18:23:07 [main] dump_mcontext(410) 	R10: 0x8
May 01 18:23:07 [main] dump_mcontext(411) 	R11: 0x202
May 01 18:23:07 [main] dump_mcontext(412) 	R12: 0x404050
May 01 18:23:07 [main] dump_mcontext(413) 	R13: 0x7fff2ceda340
May 01 18:23:07 [main] dump_mcontext(414) 	R14: 0x0
May 01 18:23:07 [main] dump_mcontext(415) 	R15: 0x0
May 01 18:23:07 [main] dump_mcontext(417) 	RDI: 0x42557d
May 01 18:23:07 [main] dump_mcontext(418) 	RSI: 0x7fff2ced8f20

Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
 collie/collie.c |    5 ++++-
 include/util.h  |    7 +++++--
 lib/logger.c    |    4 +++-
 lib/util.c      |   35 ++++++++++++++++++++++++++++++++---
 sheep/sheep.c   |    6 +++++-
 5 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/collie/collie.c b/collie/collie.c
index e798207..49fbf35 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -306,10 +306,13 @@ static const struct sd_option *build_sd_options(const char *opts)
 	return sd_opts;
 }
 
-static void crash_handler(int signo)
+static void crash_handler(int signo, siginfo_t *siginfo, void *ctxp)
 {
+	ucontext_t *uctx = ctxp;
+
 	fprintf(stderr, "collie exits unexpectedly (%s).\n", strsignal(signo));
 
+	dump_mcontext(&uctx->uc_mcontext);
 	sd_backtrace();
 
 	/*
diff --git a/include/util.h b/include/util.h
index 68eface..ea5439c 100644
--- a/include/util.h
+++ b/include/util.h
@@ -9,6 +9,7 @@
 #include <stdint.h>
 #include <unistd.h>
 #include <urcu/uatomic.h>
+#include <signal.h>
 
 #include "bitops.h"
 #include "list.h"
@@ -87,8 +88,10 @@ void pstrcpy(char *buf, int buf_size, const char *str);
 int rmdir_r(char *dir_path);
 int purge_directory(char *dir_path);
 bool is_numeric(const char *p);
-int install_sighandler(int signum, void (*handler)(int), bool once);
-int install_crash_handler(void (*handler)(int));
+void dump_mcontext(mcontext_t *mctx);
+int install_sighandler(int signum, void (*handler)(int, siginfo_t *, void *),
+		bool once);
+int install_crash_handler(void (*handler)(int, siginfo_t *, void *));
 void reraise_crash_signal(int signo, int status);
 pid_t gettid(void);
 bool is_xattr_enabled(const char *path);
diff --git a/lib/logger.c b/lib/logger.c
index d359b4d..d2aaa4c 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -480,14 +480,16 @@ static bool is_sheep_dead(int signo)
 	return signo == SIGHUP;
 }
 
-static notrace void crash_handler(int signo)
+static notrace void crash_handler(int signo, siginfo_t *siginfo, void *ctxp)
 {
 	if (is_sheep_dead(signo))
 		sd_printf(SDOG_ERR, "sheep pid %d exited unexpectedly.",
 			  sheep_pid);
 	else {
+		ucontext_t *uctx = ctxp;
 		sd_printf(SDOG_ERR, "logger pid %d exits unexpectedly (%s).",
 			  getpid(), strsignal(signo));
+		dump_mcontext(&uctx->uc_mcontext);
 		sd_backtrace();
 	}
 
diff --git a/lib/util.c b/lib/util.c
index 61a1cb5..7ebcfd1 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -23,6 +23,7 @@
 #include <signal.h>
 #include <sys/xattr.h>
 #include <fcntl.h>
+#include <ucontext.h>
 
 #include "util.h"
 #include "logger.h"
@@ -391,23 +392,51 @@ bool is_numeric(const char *s)
 	return false;
 }
 
+void dump_mcontext(mcontext_t *mctx)
+{
+	sd_iprintf("register status:");
+
+	sd_iprintf("\tRIP: 0x%lx", mctx->gregs[REG_RIP]);
+	sd_iprintf("\tRSP: 0x%lx", mctx->gregs[REG_RSP]);
+	sd_iprintf("\tRBP: 0x%lx", mctx->gregs[REG_RBP]);
+	sd_iprintf("\tRFLAGS: 0x%lx", mctx->gregs[REG_EFL]);
+
+	sd_iprintf("\tRAX: 0x%lx", mctx->gregs[REG_RAX]);
+	sd_iprintf("\tRBX: 0x%lx", mctx->gregs[REG_RBX]);
+	sd_iprintf("\tRCX: 0x%lx", mctx->gregs[REG_RCX]);
+	sd_iprintf("\tRDX: 0x%lx", mctx->gregs[REG_RDX]);
+	sd_iprintf("\tR8: 0x%lx", mctx->gregs[REG_R8]);
+	sd_iprintf("\tR9: 0x%lx", mctx->gregs[REG_R9]);
+	sd_iprintf("\tR10: 0x%lx", mctx->gregs[REG_R10]);
+	sd_iprintf("\tR11: 0x%lx", mctx->gregs[REG_R11]);
+	sd_iprintf("\tR12: 0x%lx", mctx->gregs[REG_R12]);
+	sd_iprintf("\tR13: 0x%lx", mctx->gregs[REG_R13]);
+	sd_iprintf("\tR14: 0x%lx", mctx->gregs[REG_R14]);
+	sd_iprintf("\tR15: 0x%lx", mctx->gregs[REG_R15]);
+
+	sd_iprintf("\tRDI: 0x%lx", mctx->gregs[REG_RDI]);
+	sd_iprintf("\tRSI: 0x%lx", mctx->gregs[REG_RSI]);
+}
+
 /*
  * If 'once' is true, the signal will be restored to the default state
  * after 'handler' is called.
  */
-int install_sighandler(int signum, void (*handler)(int), bool once)
+int install_sighandler(int signum, void (*handler)(int, siginfo_t *, void *),
+		bool once)
 {
 	struct sigaction sa = {};
 
-	sa.sa_handler = handler;
+	sa.sa_sigaction = handler;
 	if (once)
 		sa.sa_flags = SA_RESETHAND | SA_NODEFER;
+	sa.sa_flags |= SA_SIGINFO;
 	sigemptyset(&sa.sa_mask);
 
 	return sigaction(signum, &sa, NULL);
 }
 
-int install_crash_handler(void (*handler)(int))
+int install_crash_handler(void (*handler)(int, siginfo_t *, void *))
 {
 	return install_sighandler(SIGSEGV, handler, true) ||
 		install_sighandler(SIGABRT, handler, true) ||
diff --git a/sheep/sheep.c b/sheep/sheep.c
index 95bfa9a..e7b47ca 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -175,11 +175,15 @@ static int init_signal(void)
 	return 0;
 }
 
-static void crash_handler(int signo)
+static void crash_handler(int signo, siginfo_t *siginfo, void *ctxp)
 {
+	ucontext_t *uctx = ctxp;
+
 	sd_printf(SDOG_EMERG, "sheep exits unexpectedly (%s).",
 		  strsignal(signo));
 
+	dump_mcontext(&uctx->uc_mcontext);
+
 	sd_backtrace();
 	sd_dump_variable(__sys);
 
-- 
1.7.10.rc0.41.gfa678




More information about the sheepdog mailing list