Skip to content

Commit

Permalink
--modify ESP_CHECK to exit not abort.
Browse files Browse the repository at this point in the history
  • Loading branch information
jturner65 committed Feb 7, 2024
1 parent 9f7c84e commit 9bebdda
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 36 deletions.
10 changes: 6 additions & 4 deletions src/esp/bindings/Bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ PYBIND11_MODULE(habitat_sim_bindings, m) {
false;
#endif

/* This function pointer is used by ESP_CHECK(). If it's null, it
std::abort()s, if not, it calls it to cause a Python AssertionError */
esp::core::throwInPython = [](const char* const message) {
PyErr_SetString(PyExc_AssertionError, message);
/**
* This function pointer is used by ESP_CHECK(). If this is null, the macro
* std::exit(1)s, if not, the macro calls this to throw a Python RuntimeError
*/
esp::core::throwRuntimeInPython = [](const char* const message) {
PyErr_SetString(PyExc_RuntimeError, message);
throw pybind11::error_already_set{};
};

Expand Down
30 changes: 15 additions & 15 deletions src/esp/core/Check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,28 @@
namespace esp {
namespace core {

void (*throwInPython)(const char*) = nullptr;
void (*throwRuntimeInPython)(const char*) = nullptr;

/* [[noreturn]] will help the compiler optimize -- it basically tells it that
the condition passed to HABITAT_EXCEPTION() can be assumed to be always true
in the following code, because if not then the execution ends in this
function. */
[[noreturn]] void throwIfInPythonOtherwiseAbort(const char* message) {
/* The throwInPython function pointer gets filled during Python bindings
startup. If it's nullptr, we're in plain C++ code. */
if (throwInPython) {
throwInPython(message);
/* I failed to apply the NORETURN attribute to the throwInPython function
pointer so at least this */
CORRADE_INTERNAL_ASSERT_UNREACHABLE();

[[noreturn]] void throwIfInPythonOtherwiseExit(const char* message) {
/* The throwRuntimeInPython function pointer gets filled during Python
bindings startup. If it's nullptr, we're in plain C++ code. */
if (throwRuntimeInPython) {
throwRuntimeInPython(message);

std::exit(1);
}

/* If it isn't defined, do an abort the same way as CORRADE_ASSERT(). This
could be in an `else` block but I like to play with fire, so it's not --
the NORETURN above should tell that to the compiler and the function
should throw. */
Corrade::Utility::Error{Corrade::Utility::Error::defaultOutput()} << message;
std::abort();
/*
* If it isn't defined, display a Fatal message, which will terminate with
* std::exit(1).
*/
Corrade::Utility::Fatal{Corrade::Utility::Fatal::defaultOutput(), 1}
<< message;
}

} // namespace core
Expand Down
29 changes: 12 additions & 17 deletions src/esp/core/Check.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
/** @file
@brief ESP_CHECK macro, for use with fatal runtime errors.
Below is an overview of asserts, ESP_CHECK, exception-throwing, and warnings
in Habitat-sim. These are new guidelines as of Feb 2021; not all Habitat code
follows these guidelines yet.
Below is an overview of asserts, ESP_CHECK vs. ESP_FATAL, exception-throwing,
and warnings in Habitat-sim. These are new guidelines as of Feb 2021, and
updated June 2023; not all Habitat code follows these guidelines yet.
assert
- see CORRADE_ASSERT and CORRADE_ASSERT_INTERNAL.
Expand Down Expand Up @@ -51,32 +51,27 @@
namespace esp {
namespace core {

/**
* @brief The throwInPython function pointer gets filled during Python bindings
* startup. If it's nullptr, we're in plain C++ code.
*/
extern void (*throwInPython)(const char*);
/* The throwRuntimeInPython function pointer gets filled during Python bindings
startup. If it's nullptr, we're in plain C++ code. */
extern void (*throwRuntimeInPython)(const char*);

/**
* @brief For use in ESP_CHECK
*/
[[noreturn]] void throwIfInPythonOtherwiseAbort(const char* message);
// For use in ESP_CHECK
[[noreturn]] void throwIfInPythonOtherwiseExit(const char* message);

} // namespace core
} // namespace esp

/**
* @brief A runtime check that must pass, otherwise we consider this a fatal
* runtime error. The program terminates with the supplied error message.
*/
/* A runtime check that must pass, otherwise we consider this a fatal
* user-caused error (bad data). The program exist with the supplied error
* message but no core dump. */
#define ESP_CHECK(condition, ...) \
do { \
if (!(condition)) { \
std::ostringstream out; \
Corrade::Utility::Debug{ \
&out, Corrade::Utility::Debug::Flag::NoNewlineAtTheEnd} \
<< "ESP_CHECK failed:" << __VA_ARGS__; \
esp::core::throwIfInPythonOtherwiseAbort(out.str().data()); \
esp::core::throwIfInPythonOtherwiseExit(out.str().data()); \
} \
} while (false)

Expand Down

0 comments on commit 9bebdda

Please sign in to comment.