Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--[BE Week]Modify ESP_CHECK to exit not abort. #2143

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/esp/bindings/Bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ PYBIND11_MODULE(habitat_sim_bindings, m) {
#endif
m.attr("stage_id") = esp::RIGID_STAGE_ID;

/* 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
Loading