diff --git a/repos/base-linux/lib/mk/lx_hybrid.mk b/repos/base-linux/lib/mk/lx_hybrid.mk index f76f4256a1..9aca799091 100644 --- a/repos/base-linux/lib/mk/lx_hybrid.mk +++ b/repos/base-linux/lib/mk/lx_hybrid.mk @@ -1,11 +1,12 @@ SRC_CC += lx_hybrid.cc new_delete.cc capability_space.cc -SRC_CC += signal_transmitter.cc signal.cc +SRC_CC += signal_transmitter.cc signal.cc raise.cc SRC_C += libgcc.c # new_delete.cc uses libsupc++ which means we need to access # its include directory. STDINC := yes +vpath raise.cc $(BASE_DIR)/src/lib/cxx vpath new_delete.cc $(BASE_DIR)/src/lib/cxx vpath lx_hybrid.cc $(REP_DIR)/src/lib/lx_hybrid vpath libgcc.c $(REP_DIR)/src/lib/lx_hybrid diff --git a/repos/base/include/base/allocator.h b/repos/base/include/base/allocator.h index 0ea1434e88..17a47b66fb 100644 --- a/repos/base/include/base/allocator.h +++ b/repos/base/include/base/allocator.h @@ -95,15 +95,13 @@ struct Genode::Allocator : Deallocator /** * Raise exception according to the 'error' value + * + * \deprecated use 'raise()' instead + * \noapi */ - static void throw_alloc_error(Alloc_error error) __attribute__((noreturn)) + static void throw_alloc_error(Alloc_error e) __attribute__((noreturn)) { - switch (error) { - case Alloc_error::OUT_OF_RAM: throw Out_of_ram(); - case Alloc_error::OUT_OF_CAPS: throw Out_of_caps(); - case Alloc_error::DENIED: break; - } - throw Denied(); + raise(e); } /** @@ -121,8 +119,7 @@ struct Genode::Allocator : Deallocator { return try_alloc(size).convert( [&] (void *ptr) { return ptr; }, - [&] (Alloc_error error) -> void * { - throw_alloc_error(error); }); + [&] (Alloc_error e) -> void * { raise(e); }); } }; diff --git a/repos/base/include/base/error.h b/repos/base/include/base/error.h index 4c42cc3ee4..09a8aaea04 100644 --- a/repos/base/include/base/error.h +++ b/repos/base/include/base/error.h @@ -1,5 +1,5 @@ /* - * \brief Error types + * \brief Error types and last-resort error handling * \author Norman Feske * \date 2025-03-05 */ @@ -31,6 +31,19 @@ namespace Genode { * the caller fail gracefully or consciously panic at the caller side. */ enum class Alloc_error { OUT_OF_RAM, OUT_OF_CAPS, DENIED }; + + /** + * Raise an error without return + * + * This function should never be called except in panic situations where + * no other way of reflecting an error condition exists. + * + * When using the C++ runtime, errors are reflected by the exceptions + * defined at 'base/exception.h'. If the component has no reference to + * 'raise()' C++ exceptions are disabled, the component is known to + * contain no unhandled error conditions. + */ + void raise(Alloc_error) __attribute__((noreturn)); } #endif /* _INCLUDE__BASE__ERROR_H_ */ diff --git a/repos/base/lib/mk/cxx.mk b/repos/base/lib/mk/cxx.mk index b928b80aa0..aee9fa3477 100644 --- a/repos/base/lib/mk/cxx.mk +++ b/repos/base/lib/mk/cxx.mk @@ -1,4 +1,5 @@ -CXX_SRC_CC += misc.cc new_delete.cc malloc_free.cc exception.cc guard.cc emutls.cc +CXX_SRC_CC += misc.cc new_delete.cc malloc_free.cc exception.cc guard.cc \ + emutls.cc raise.cc INC_DIR += $(REP_DIR)/src/include # We need the libsupc++ include directory STDINC = yes diff --git a/repos/base/lib/symbols/ld b/repos/base/lib/symbols/ld index 4e0b7f8abd..001f7da2fb 100644 --- a/repos/base/lib/symbols/ld +++ b/repos/base/lib/symbols/ld @@ -253,6 +253,7 @@ _ZN6Genode5printERNS_6OutputEl T _ZN6Genode5printERNS_6OutputEm T _ZN6Genode5printERNS_6OutputEx T _ZN6Genode5printERNS_6OutputEy T +_ZN6Genode5raiseENS_11Alloc_errorE T _ZN6Genode6Output10out_stringEPKcm T _ZN6Genode6Parent8announceERKNS_13Rpc_in_bufferILm64EEENS_10CapabilityINS_4RootEEE T _ZN6Genode6Signal19_dec_ref_and_unlockEv T diff --git a/repos/base/src/lib/cxx/raise.cc b/repos/base/src/lib/cxx/raise.cc new file mode 100644 index 0000000000..7cbef79c63 --- /dev/null +++ b/repos/base/src/lib/cxx/raise.cc @@ -0,0 +1,27 @@ +/* + * \brief Reflect error conditions as C++ exceptions + * \author Norman Feske + * \date 2025-03-05 + */ + +/* + * Copyright (C) 2025 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* Genode includes */ +#include +#include + + +void Genode::raise(Alloc_error error) +{ + switch (error) { + case Alloc_error::OUT_OF_RAM: throw Out_of_ram(); + case Alloc_error::OUT_OF_CAPS: throw Out_of_caps(); + case Alloc_error::DENIED: break; + } + throw Denied(); +}