diff options
-rw-r--r-- | include/openvswitch/vlog.h | 3 | ||||
-rw-r--r-- | lib/daemon-private.h | 1 | ||||
-rw-r--r-- | lib/daemon-unix.c | 2 | ||||
-rw-r--r-- | lib/fatal-signal.c | 27 | ||||
-rw-r--r-- | lib/vlog.c | 6 |
5 files changed, 37 insertions, 2 deletions
diff --git a/include/openvswitch/vlog.h b/include/openvswitch/vlog.h index 19da4ab62..476bf3d6d 100644 --- a/include/openvswitch/vlog.h +++ b/include/openvswitch/vlog.h @@ -143,6 +143,9 @@ void vlog_set_syslog_method(const char *method); /* Configure syslog target. */ void vlog_set_syslog_target(const char *target); +/* Return the log_fd. */ +int vlog_get_fd(void); + /* Initialization. */ void vlog_init(void); void vlog_enable_async(void); diff --git a/lib/daemon-private.h b/lib/daemon-private.h index 4e0667601..2b90e0042 100644 --- a/lib/daemon-private.h +++ b/lib/daemon-private.h @@ -20,6 +20,7 @@ extern bool detach; extern char *pidfile; extern int daemonize_fd; +extern bool monitor; char *make_pidfile_name(const char *name); diff --git a/lib/daemon-unix.c b/lib/daemon-unix.c index 6b2a5b9bd..ae59ecf2c 100644 --- a/lib/daemon-unix.c +++ b/lib/daemon-unix.c @@ -80,7 +80,7 @@ int daemonize_fd = -1; /* --monitor: Should a supervisory process monitor the daemon and restart it if * it dies due to an error signal? */ -static bool monitor; +bool monitor; /* --user: Only root can use this option. Switch to new uid:gid after * initially running as root. */ 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 diff --git a/lib/vlog.c b/lib/vlog.c index 559943d87..502b33fc8 100644 --- a/lib/vlog.c +++ b/lib/vlog.c @@ -612,6 +612,12 @@ vlog_set_syslog_target(const char *target) ovs_rwlock_unlock(&pattern_rwlock); } +int +vlog_get_fd(void) +{ + return log_fd; +} + /* Returns 'false' if 'facility' is not a valid string. If 'facility' * is a valid string, sets 'value' with the integer value of 'facility' * and returns 'true'. */ |