mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 20:20:27 +00:00
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> (cherry picked from commit 615f9f18fc025757a255f936748fc1e86e922783)
This commit is contained in:
parent
9c7753e41a
commit
d1265948c3
45
lib/log.c
45
lib/log.c
@ -459,6 +459,40 @@ zlog_signal(int signo, const char *action
|
|||||||
NULL
|
NULL
|
||||||
#endif
|
#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 PRI
|
||||||
#undef LOC
|
#undef LOC
|
||||||
}
|
}
|
||||||
@ -616,6 +650,16 @@ ZLOG_FUNC(zlog_debug, LOG_DEBUG)
|
|||||||
|
|
||||||
#undef ZLOG_FUNC
|
#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
|
void
|
||||||
_zlog_assert_failed (const char *assertion, const char *file,
|
_zlog_assert_failed (const char *assertion, const char *file,
|
||||||
unsigned int line, const char *function)
|
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",
|
zlog(NULL, LOG_CRIT, "Assertion `%s' failed in file %s, line %u, function %s",
|
||||||
assertion,file,line,(function ? function : "?"));
|
assertion,file,line,(function ? function : "?"));
|
||||||
zlog_backtrace(LOG_CRIT);
|
zlog_backtrace(LOG_CRIT);
|
||||||
|
zlog_thread_info(LOG_CRIT);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_notice (const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
|
||||||
extern void zlog_debug (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
|
/* Set logging level for the given destination. If the log_level
|
||||||
argument is ZLOG_DISABLED, then the destination is disabled.
|
argument is ZLOG_DISABLED, then the destination is disabled.
|
||||||
This function should not be used for file logging (use zlog_set_file
|
This function should not be used for file logging (use zlog_set_file
|
||||||
|
@ -1526,6 +1526,8 @@ thread_getrusage (RUSAGE_T *r)
|
|||||||
#endif /* HAVE_CLOCK_MONOTONIC */
|
#endif /* HAVE_CLOCK_MONOTONIC */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct thread *thread_current = NULL;
|
||||||
|
|
||||||
/* We check thread consumed time. If the system has getrusage, we'll
|
/* 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
|
use that to get in-depth stats on the performance of the thread in addition
|
||||||
to wall clock time stats from gettimeofday. */
|
to wall clock time stats from gettimeofday. */
|
||||||
@ -1555,7 +1557,9 @@ thread_call (struct thread *thread)
|
|||||||
GETRUSAGE (&before);
|
GETRUSAGE (&before);
|
||||||
thread->real = before.real;
|
thread->real = before.real;
|
||||||
|
|
||||||
|
thread_current = thread;
|
||||||
(*thread->func) (thread);
|
(*thread->func) (thread);
|
||||||
|
thread_current = NULL;
|
||||||
|
|
||||||
GETRUSAGE (&after);
|
GETRUSAGE (&after);
|
||||||
|
|
||||||
|
@ -265,4 +265,8 @@ extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
|
|||||||
extern struct timeval recent_time;
|
extern struct timeval recent_time;
|
||||||
/* Similar to recent_time, but a monotonically increasing time value */
|
/* Similar to recent_time, but a monotonically increasing time value */
|
||||||
extern struct timeval recent_relative_time (void);
|
extern struct timeval recent_relative_time (void);
|
||||||
|
|
||||||
|
/* only for use in logging functions! */
|
||||||
|
extern struct thread *thread_current;
|
||||||
|
|
||||||
#endif /* _ZEBRA_THREAD_H */
|
#endif /* _ZEBRA_THREAD_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user