From 502aedb33e904a9c854d641d0d85b50ef571357a Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Wed, 20 Jan 2016 12:41:33 +0100 Subject: [PATCH] Provide a way to selectively enable assertions in release mode - Throwing an assertion exception for proper stack unwinding, making sure destructors are called - On in Debug mode, in Release, enable via: cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_ASSERTIONS=ON Current problem that I'm seeing is that some code is not catching exceptions or worse silently swallowing them. Would like to check the whole pipeline before merging this in. --- CMakeLists.txt | 7 +++++++ include/util/assert.hpp | 20 ++++++++++++++++++++ src/util/assert.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 include/util/assert.hpp create mode 100644 src/util/assert.cpp 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); +} +}