From 6ebb582e84d873e62bb93f3fd04eac3ef33ead08 Mon Sep 17 00:00:00 2001 From: Guy Zana <guy@cloudius-systems.com> Date: Sun, 26 May 2013 19:46:50 +0300 Subject: [PATCH] debug: introduce debug_ll() and use it in abort() the debug() console function is taking a lock before it access the console driver, it does that by acquiring a mutex which may sleep. since we want to be able to debug (and abort) in contexts where it's not possible sleep, such as in page_fault, a lockless debug print method is introduced. previousely to this patch, any abort on page_fault would cause an "endless" recursive abort() loop which hanged the system in a peculiar state. --- core/debug.cc | 6 ++++++ drivers/console.cc | 5 +++++ drivers/console.hh | 1 + drivers/debug-console.cc | 7 +++++++ drivers/debug-console.hh | 2 ++ include/osv/debug.h | 4 ++++ runtime.cc | 2 +- 7 files changed, 26 insertions(+), 1 deletion(-) diff --git a/core/debug.cc b/core/debug.cc index d903b028a..690ecbc7e 100644 --- a/core/debug.cc +++ b/core/debug.cc @@ -170,4 +170,10 @@ extern "C" { console::write(msg, len, false); } + // lockless version + void debug_ll(const char *msg) + { + console::write_ll(msg, strlen(msg)); + } + } diff --git a/drivers/console.cc b/drivers/console.cc index f1968e8f9..84a6a9e93 100755 --- a/drivers/console.cc +++ b/drivers/console.cc @@ -24,6 +24,11 @@ void write(const char *msg, size_t len, bool lf) console.newline(); } +// lockless version +void write_ll(const char *msg, size_t len) +{ + console.write_ll(msg, len); +} mutex console_mutex; // characters available to be returned on read() from the console diff --git a/drivers/console.hh b/drivers/console.hh index a709feee6..d8caf6fbf 100644 --- a/drivers/console.hh +++ b/drivers/console.hh @@ -15,6 +15,7 @@ public: namespace console { void write(const char *msg, size_t len, bool lf); +void write_ll(const char *msg, size_t len); } diff --git a/drivers/debug-console.cc b/drivers/debug-console.cc index 97dbfa616..5f0d7818e 100644 --- a/drivers/debug-console.cc +++ b/drivers/debug-console.cc @@ -10,6 +10,13 @@ void debug_console::write(const char* str, size_t len) with_lock(_lock, [=] { if (_impl) { _impl->write(str, len); }}); } +void debug_console::write_ll(const char *str, size_t len) +{ + if (_impl) { + _impl->write(str, len); + } +} + void debug_console::newline() { with_lock(_lock, [=] { if (_impl) { _impl->newline(); }}); diff --git a/drivers/debug-console.hh b/drivers/debug-console.hh index 9c7e6cd9a..2aa3ced9c 100644 --- a/drivers/debug-console.hh +++ b/drivers/debug-console.hh @@ -11,6 +11,8 @@ class debug_console : public Console { public: void set_impl(Console* impl); virtual void write(const char *str, size_t len); + // write without taking any locks + void write_ll(const char *str, size_t len); virtual void newline(); virtual bool input_ready() override; virtual char readch(); diff --git a/include/osv/debug.h b/include/osv/debug.h index 0b417b35a..084719fb0 100644 --- a/include/osv/debug.h +++ b/include/osv/debug.h @@ -18,6 +18,10 @@ __BEGIN_DECLS void debug(const char *msg); void debug_write(const char *msg, size_t len); +/* a lockless version that doesn't take any locks before printing, + should be used only to debug faults */ +void debug_ll(const char *msg); + int vkprintf(const char *__restrict fmt, va_list ap) __attribute__((format(printf, 1, 0))); int kprintf(const char *__restrict fmt, ...) diff --git a/runtime.cc b/runtime.cc index e040cfab6..e043ad792 100644 --- a/runtime.cc +++ b/runtime.cc @@ -86,7 +86,7 @@ void abort() already_aborted = true; // Since the debug() code is complex and might cause an additional // abort, we need to prevent endless abort() nesting. - debug("Aborted\n"); + debug_ll("Aborted\n"); } osv::halt(); } -- GitLab