summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/openvswitch/vlog.h3
-rw-r--r--lib/daemon-private.h1
-rw-r--r--lib/daemon-unix.c2
-rw-r--r--lib/fatal-signal.c27
-rw-r--r--lib/vlog.c6
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'. */