diff --git a/CMakeLists.txt b/CMakeLists.txt index b07b94b53..6a2fca602 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ endif() option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF) option(DEBUG_GEOMETRY "Enables an option to dump GeoJSON of the final routing graph" OFF) option(BUILD_TOOLS "Build OSRM tools" OFF) +option(ENABLE_ASSERTIONS OFF) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/) @@ -97,6 +98,7 @@ if(NOT CMAKE_BUILD_TYPE MATCHES Debug) endif() if(CMAKE_BUILD_TYPE MATCHES Debug) message(STATUS "Configuring OSRM in debug mode") + set(ENABLE_ASSERTIONS ON) if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-inline -fno-omit-frame-pointer") @@ -366,6 +368,11 @@ if(BUILD_TOOLS) install(TARGETS osrm-springclean DESTINATION bin) endif() +if (ENABLE_ASSERTIONS) + message(STATUS "Enabling assertions") + add_definitions(-DBOOST_ENABLE_ASSERT_HANDLER) +endif() + # Add RPATH info to executables so that when they are run after being installed # (i.e., from /usr/local/bin/) the linker can find library dependencies. For # more info see http://www.cmake.org/Wiki/CMake_RPATH_handling diff --git a/include/util/assert.hpp b/include/util/assert.hpp new file mode 100644 index 000000000..d9bfb9542 --- /dev/null +++ b/include/util/assert.hpp @@ -0,0 +1,20 @@ +#ifndef OSRM_ASSERT_HPP +#define OSRM_ASSERT_HPP + +#include + +#include + +namespace osrm +{ +namespace util +{ +// Assertion type to be thrown for stack unwinding +struct assertionError final : std::logic_error +{ + assertionError(const char *msg) : std::logic_error{msg} {} +}; +} +} + +#endif diff --git a/src/util/assert.cpp b/src/util/assert.cpp new file mode 100644 index 000000000..70517840a --- /dev/null +++ b/src/util/assert.cpp @@ -0,0 +1,29 @@ +#include "util/assert.hpp" + +#include + +namespace +{ +// We throw to guarantee for stack-unwinding and therefore our destructors being called. +void assertion_failed_msg_helper( + char const *expr, char const *msg, char const *function, char const *file, long line) +{ + std::ostringstream fmt; + fmt << file << ":" << line << "\nin: " << function << ": " << expr << "\n" << msg; + throw osrm::util::assertionError{fmt.str().c_str()}; +} +} + +// Boost.Assert only declares the following two functions and let's us define them here. +namespace boost +{ +void assertion_failed(char const *expr, char const *function, char const *file, long line) +{ + ::assertion_failed_msg_helper(expr, "", function, file, line); +} +void assertion_failed_msg( + char const *expr, char const *msg, char const *function, char const *file, long line) +{ + ::assertion_failed_msg_helper(expr, msg, function, file, line); +} +}