From ce354d6fd9cfbd95ff9e14b9f60334fb2dc3cb13 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Mon, 5 Oct 2015 15:39:36 +0200 Subject: [PATCH] linux: improve diagnosis on exception handling Under some circumstances, the diagnostic message in the exception signal handler was not printed. This could happen due to a dead lock in the console library if the console code itself produces the exception while possessing the mutex, e.g., by exhausting a undersized stack. Now, we directly write to the log session via the stdout_write() hook or use raw_write_str() in core. --- .../base-linux/src/base/thread/thread_env.cc | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/repos/base-linux/src/base/thread/thread_env.cc b/repos/base-linux/src/base/thread/thread_env.cc index 15c87a2ad..d1548c8ad 100644 --- a/repos/base-linux/src/base/thread/thread_env.cc +++ b/repos/base-linux/src/base/thread/thread_env.cc @@ -31,6 +31,19 @@ char **lx_environ; */ int main_thread_futex_counter __attribute__((aligned(sizeof(addr_t)))); +/** + * Genode console hook + */ +extern "C" int stdout_write(char const *); + +/* + * Core lacks the hook, so provide a base-linux specific weak implementation + */ +extern "C" __attribute__((weak)) int stdout_write(char const *s) +{ + return raw_write_str(s); +} + /** * Signal handler for exceptions like segmentation faults */ @@ -46,7 +59,18 @@ static void exception_signal_handler(int signum) default: /* unexpected signal */ return; } - PERR("%s (signum=%d), see Linux kernel log for details", reason, signum); + + /* + * We can't use Genode::printf() as the exception may have occurred in the + * Genode console library itself, which uses a mutex. Therefore, we use + * Genode::snprintf() and call the console hook directly to minimize + * overlaps with other code paths. + */ + static char msg[128]; + snprintf(msg, sizeof(msg), + ESC_ERR "%s (signum=%d), see Linux kernel log for details" ESC_END "\n", + reason, signum); + stdout_write(msg); /* * We reset the signal handler to SIG_DFL and trigger exception again,