]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: include thread information in backtraces
authorDavid Lamparter <equinox@opensourcerouting.org>
Mon, 18 Nov 2013 22:52:02 +0000 (23:52 +0100)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 30 May 2016 00:11:42 +0000 (20:11 -0400)
now that we know what thread we're currently executing, let's add that
information to SEGV / assert backtraces.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit 615f9f18fc025757a255f936748fc1e86e922783)

lib/log.c
lib/log.h
lib/thread.c
lib/thread.h

index 92a1a4ddd4c988f5e0d84bb7d2224656c7b18ba9..5354d32c0fc142e018f58ccafa188fbd8a6dcebf 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -459,6 +459,40 @@ zlog_signal(int signo, const char *action
                         NULL
 #endif
                        );
+
+  s = buf;
+  if (!thread_current)
+    s = str_append (LOC, "no thread information available\n");
+  else
+    {
+      s = str_append (LOC, "in thread ");
+      s = str_append (LOC, thread_current->funcname);
+      s = str_append (LOC, " scheduled from ");
+      s = str_append (LOC, thread_current->schedfrom);
+      s = str_append (LOC, ":");
+      s = num_append (LOC, thread_current->schedfrom_line);
+      s = str_append (LOC, "\n");
+    }
+
+#define DUMP(FD) write(FD, buf, s-buf);
+  /* If no file logging configured, try to write to fallback log file. */
+  if (logfile_fd >= 0)
+    DUMP(logfile_fd)
+  if (!zlog_default)
+    DUMP(STDERR_FILENO)
+  else
+    {
+      if (PRI <= zlog_default->maxlvl[ZLOG_DEST_STDOUT])
+        DUMP(STDOUT_FILENO)
+      /* Remove trailing '\n' for monitor and syslog */
+      *--s = '\0';
+      if (PRI <= zlog_default->maxlvl[ZLOG_DEST_MONITOR])
+        vty_log_fixed(buf,s-buf);
+      if (PRI <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG])
+       syslog_sigsafe(PRI|zlog_default->facility,msgstart,s-msgstart);
+    }
+#undef DUMP
+
 #undef PRI
 #undef LOC
 }
@@ -616,6 +650,16 @@ ZLOG_FUNC(zlog_debug, LOG_DEBUG)
 
 #undef ZLOG_FUNC
 
+void zlog_thread_info (int log_level)
+{
+  if (thread_current)
+    zlog(NULL, log_level, "Current thread function %s, scheduled from "
+        "file %s, line %u", thread_current->funcname,
+        thread_current->schedfrom, thread_current->schedfrom_line);
+  else
+    zlog(NULL, log_level, "Current thread not known/applicable");
+}
+
 void
 _zlog_assert_failed (const char *assertion, const char *file,
                     unsigned int line, const char *function)
@@ -628,6 +672,7 @@ _zlog_assert_failed (const char *assertion, const char *file,
   zlog(NULL, LOG_CRIT, "Assertion `%s' failed in file %s, line %u, function %s",
        assertion,file,line,(function ? function : "?"));
   zlog_backtrace(LOG_CRIT);
+  zlog_thread_info(LOG_CRIT);
   abort();
 }
 
index 61370f7b82766e30325927e9f46fc334dc701a65..882080760d1d950f3b86585c814e8a7b0911bc95 100644 (file)
--- a/lib/log.h
+++ b/lib/log.h
@@ -121,6 +121,8 @@ extern void zlog_info (const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
 extern void zlog_notice (const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
 extern void zlog_debug (const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
 
+extern void zlog_thread_info (int log_level);
+
 /* Set logging level for the given destination.  If the log_level
    argument is ZLOG_DISABLED, then the destination is disabled.
    This function should not be used for file logging (use zlog_set_file
index b666219cebb08b2a5dd8289a22f13d0f3b93d76f..21fb2b95630357ca9aa0eb2a7bb4c8ad688b3a12 100644 (file)
@@ -1526,6 +1526,8 @@ thread_getrusage (RUSAGE_T *r)
 #endif /* HAVE_CLOCK_MONOTONIC */
 }
 
+struct thread *thread_current = NULL;
+
 /* We check thread consumed time. If the system has getrusage, we'll
    use that to get in-depth stats on the performance of the thread in addition
    to wall clock time stats from gettimeofday. */
@@ -1555,7 +1557,9 @@ thread_call (struct thread *thread)
   GETRUSAGE (&before);
   thread->real = before.real;
 
+  thread_current = thread;
   (*thread->func) (thread);
+  thread_current = NULL;
 
   GETRUSAGE (&after);
 
index 66dd9cf7889a0e2dea7d7406f6b7241053e392d7..8b42ffe58a201cd19df832eb107a0ca33616473e 100644 (file)
@@ -265,4 +265,8 @@ extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
 extern struct timeval recent_time;
 /* Similar to recent_time, but a monotonically increasing time value */
 extern struct timeval recent_relative_time (void);
+
+/* only for use in logging functions! */
+extern struct thread *thread_current;
+
 #endif /* _ZEBRA_THREAD_H */