2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-02 23:35:27 +00:00

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 <fatal_signal_handler+0x49>
  0x00007f7f5e57f4b0 <killpg+0x40>
  0x000000000047daa8 <pmd_thread_main+0x238>
  0x0000000000504edd <ovsthread_wrapper+0x7d>
  0x00007f7f5f0476ba <start_thread+0xca>
  0x00007f7f5e65141d <clone+0x6d>
  0x0000000000000000 <+0x0>

Acked-by: Ben Pfaff <blp@ovn.org>
Signed-off-by: William Tu <u9012063@gmail.com>
This commit is contained in:
William Tu
2020-03-23 07:44:48 -07:00
parent c59922767e
commit ecd4a8fcdf
5 changed files with 37 additions and 2 deletions

View File

@@ -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);

View File

@@ -20,6 +20,7 @@
extern bool detach;
extern char *pidfile;
extern int daemonize_fd;
extern bool monitor;
char *make_pidfile_name(const char *name);

View File

@@ -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. */

View File

@@ -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

View File

@@ -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'. */