From 615f9f18fc025757a255f936748fc1e86e922783 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 18 Nov 2013 23:52:02 +0100 Subject: 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 --- lib/log.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ lib/log.h | 2 ++ lib/thread.c | 4 ++++ lib/thread.h | 4 ++++ 4 files changed, 55 insertions(+) diff --git a/lib/log.c b/lib/log.c index 1058844b..04f8fab6 100644 --- a/lib/log.c +++ b/lib/log.c @@ -425,6 +425,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 } @@ -604,6 +638,16 @@ PLOG_FUNC(plog_debug, LOG_DEBUG) #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_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(); } diff --git a/lib/log.h b/lib/log.h index cf247a83..f3b43ad1 100644 --- a/lib/log.h +++ b/lib/log.h @@ -132,6 +132,8 @@ extern void plog_notice (struct zlog *, const char *format, ...) extern void plog_debug (struct zlog *, const char *format, ...) PRINTF_ATTRIBUTE(2, 3); +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 diff --git a/lib/thread.c b/lib/thread.c index 9de5f94f..9c3ee823 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -1217,6 +1217,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. */ @@ -1246,7 +1248,9 @@ thread_call (struct thread *thread) GETRUSAGE (&before); thread->real = before.real; + thread_current = thread; (*thread->func) (thread); + thread_current = NULL; GETRUSAGE (&after); diff --git a/lib/thread.h b/lib/thread.h index a088b472..9743a22d 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -234,4 +234,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 */ -- cgit v1.2.3