[sheepdog] [PATCH 4/4] sheep: dump cluster info when exiting unexpectedly

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Wed Feb 27 18:15:38 CET 2013


This introduces sd_dump_variable to dump a variable and call it
against __sys in crash_handler.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 include/logger.h |  6 ++++++
 lib/logger.c     | 45 +++++++++++++++++++++++++++++++++++++++++++++
 sheep/sheep.c    |  1 +
 3 files changed, 52 insertions(+)

diff --git a/include/logger.h b/include/logger.h
index 0591c6f..6721a58 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -37,6 +37,12 @@ void log_write(int prio, const char *func, int line, const char *fmt, ...)
 	__printf(4, 5);
 void set_thread_name(const char *name, int idx);
 void get_thread_name(char *name);
+
+#define sd_dump_variable(var) ({		\
+	register void *current_sp asm("rsp");	\
+	__sd_dump_variable(#var, current_sp);	\
+})
+int __sd_dump_variable(const char *var, const void *base_sp);
 void sd_backtrace(void);
 
 /*
diff --git a/lib/logger.c b/lib/logger.c
index e49afaa..659ae2d 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -642,6 +642,51 @@ static bool check_gdb(void)
 	return system("which gdb > /dev/null") == 0;
 }
 
+__attribute__ ((__noinline__))
+notrace int __sd_dump_variable(const char *var, const void *base_sp)
+{
+	char cmd[ARG_MAX], path[PATH_MAX], info[256];
+	FILE *f = NULL;
+
+	if (!check_gdb()) {
+		sd_eprintf("cannot find gdb");
+		return -1;
+	}
+
+	if (get_my_path(path, sizeof(path)) < 0)
+		return -1;
+
+	snprintf(cmd, sizeof(cmd), "gdb -nw %s %d -batch -ex 'set width 80'"
+		 " -ex 'select-frame %p' -ex 'up 1' -ex 'p %s' 2> /dev/null",
+		 path, getpid(), base_sp, var);
+	f = popen(cmd, "r");
+	if (f == NULL) {
+		sd_eprintf("failed to run gdb");
+		return -1;
+	}
+
+	/*
+	 * The expected outputs of gdb are:
+	 *
+	 *  [some info we don't need]
+	 *  $1 = {
+	 *    <variable info>
+	 *  }
+	 */
+	sd_printf(SDOG_EMERG, "dump %s", var);
+	while (fgets(info, sizeof(info), f) != NULL) {
+		if (info[0] == '$') {
+			sd_printf(SDOG_EMERG, "%s", info);
+			break;
+		}
+	}
+	while (fgets(info, sizeof(info), f) != NULL)
+		sd_printf(SDOG_EMERG, "%s", info);
+
+	pclose(f);
+	return 0;
+}
+
 #define dump_stack_frames() ({			\
 	register void *current_sp asm("rsp");	\
 	__dump_stack_frames(current_sp);	\
diff --git a/sheep/sheep.c b/sheep/sheep.c
index 1572149..e44ef95 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -181,6 +181,7 @@ static void crash_handler(int signo)
 		  strsignal(signo));
 
 	sd_backtrace();
+	sd_dump_variable(__sys);
 }
 
 static struct cluster_info __sys;
-- 
1.8.1.3.566.gaa39828




More information about the sheepdog mailing list