lib: include thread information in backtraces

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>
diff --git a/lib/log.c b/lib/log.c
index 1058844..04f8fab 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -425,6 +425,40 @@
 			 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
 }
@@ -604,6 +638,16 @@
 
 #undef PLOG_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)
@@ -616,6 +660,7 @@
   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();
 }