From ecd4a8fcdff2ebf35cdb36355167d34e99df6dd5 Mon Sep 17 00:00:00 2001 From: William Tu Date: Mon, 23 Mar 2020 07:44:48 -0700 Subject: fatal-signal: Log backtrace when no monitor daemon. Currently the backtrace logging is only available when monitor daemon is running. This patch enables backtrace logging when no monitor daemon exists. At signal handling context, it detects whether monitor daemon exists. If not, write directly the backtrace to the vlog fd. Note that using VLOG_* macro doesn't work due to it's buffer I/O, so this patch directly issue write() syscall to the file descriptor. For some system we stop using monitor daemon and use systemd to monitor ovs-vswitchd, thus need this patch. Example of ovs-vswitchd.log (note that there is no timestamp printed): 2020-03-23T14:42:12.949Z|00049|memory|INFO|175332 kB peak resident 2020-03-23T14:42:12.949Z|00050|memory|INFO|handlers:2 ports:3 reva SIGSEGV detected, backtrace: 0x0000000000486969 0x00007f7f5e57f4b0 0x000000000047daa8 0x0000000000504edd 0x00007f7f5f0476ba 0x00007f7f5e65141d 0x0000000000000000 <+0x0> Acked-by: Ben Pfaff Signed-off-by: William Tu --- lib/fatal-signal.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'lib/fatal-signal.c') diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c index ba7f5bfd3..4965c1ae8 100644 --- a/lib/fatal-signal.c +++ b/lib/fatal-signal.c @@ -187,7 +187,32 @@ send_backtrace_to_monitor(void) { dep++; } - ignore(write(daemonize_fd, unw_bt, dep * sizeof(struct unw_backtrace))); + if (monitor) { + ignore(write(daemonize_fd, unw_bt, + dep * sizeof(struct unw_backtrace))); + } else { + /* Since there is no monitor daemon running, write backtrace + * in current process. This is not asyn-signal-safe due to + * use of snprintf(). + */ + char str[] = "SIGSEGV detected, backtrace:\n"; + + if (vlog_get_fd() < 0) { + return; + } + + ignore(write(vlog_get_fd(), str, strlen(str))); + + for (int i = 0; i < dep; i++) { + char line[64]; + + snprintf(line, 64, "0x%016"PRIxPTR" <%s+0x%"PRIxPTR">\n", + unw_bt[i].ip, + unw_bt[i].func, + unw_bt[i].offset); + ignore(write(vlog_get_fd(), line, strlen(line))); + } + } } #else static inline void -- cgit v1.2.1