cxxrt guard: stop using cassert, check futex_wake result (#404)
diff --git a/compile_flags.txt b/compile_flags.txt index ae0cf0a..0ed75a0 100644 --- a/compile_flags.txt +++ b/compile_flags.txt
@@ -22,6 +22,7 @@ -DDEBUG_LOADER=true -DDEBUG_ALLOCATOR=true -DDEBUG_SCHEDULER=true +-DDEBUG_CXXRT=true -DSAIL -DCPU_TIMER_HZ=2000 -DTICK_RATE_HZ=10
diff --git a/sdk/lib/cxxrt/guard.cc b/sdk/lib/cxxrt/guard.cc index 04d7319..629a535 100644 --- a/sdk/lib/cxxrt/guard.cc +++ b/sdk/lib/cxxrt/guard.cc
@@ -1,12 +1,14 @@ // Copyright Microsoft and CHERIoT Contributors. // SPDX-License-Identifier: MIT -#include <cassert> #include <cdefs.h> +#include <debug.hh> #include <futex.h> #include <limits> #include <stdint.h> +using Debug = ConditionalDebug<DEBUG_CXXRT, "cxxrt">; + /** * The helper functions need to expose an unmangled name because the compiler * inserts calls to them. Declare them using the asm label extension. @@ -54,6 +56,8 @@ /** * Acquire the lock. + * + * This is safe only in IRQ-deferred context. */ void lock() { @@ -62,7 +66,7 @@ { futex_wait(&high, LockBit); } - assert(high == 0); + Debug::Assert(high == 0, "Corrupt guard word at {}", this); high = LockBit; } @@ -71,9 +75,12 @@ */ void unlock() { - assert(high == LockBit); - high = 0; - futex_wake(&high, std::numeric_limits<uint32_t>::max()); + Debug::Assert(high == LockBit, "Corrupt guard word at {}", this); + high = 0; + int res = futex_wake(&high, std::numeric_limits<uint32_t>::max()); + Debug::Assert(res >= 0, + "futex_wake failed for guard {}; possible deadlock", + this); } /** @@ -109,8 +116,8 @@ void __cxa_guard_release(uint64_t *guard) { auto *g = reinterpret_cast<GuardWord *>(guard); - assert(!g->is_initialised()); - assert(g->is_locked()); + Debug::Assert(!g->is_initialised(), "Releasing uninitialized guard {}", g); + Debug::Assert(g->is_locked(), "Releasing unlocked guard {}", g); g->set_initialised(); g->unlock(); }