Implement ssassert(), a replacement for oops().

pull/10/head
whitequark 2016-05-18 19:38:17 +00:00
parent 1b52c46b81
commit 4415f5bb91
4 changed files with 60 additions and 5 deletions

View File

@ -49,6 +49,8 @@ if(MSVC)
# they have their own __inline; this breaks `static inline` functions.
# We do not want to care and so we fix this with a definition.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Dinline=__inline")
# Same for the (C99) __func__ special variable; we use it only in C++ code.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D__func__=__FUNCTION__")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)

View File

@ -8,6 +8,7 @@
// Copyright 2013 Daniel Richard G. <skunk@iSKUNK.ORG>
//-----------------------------------------------------------------------------
#include <time.h>
#include <execinfo.h>
#include "solvespace.h"
@ -25,6 +26,29 @@ void dbp(const char *str, ...)
fputc('\n', stderr);
}
void assert_failure(const char *file, unsigned line, const char *function,
const char *condition, const char *message) {
fprintf(stderr, "File %s, line %u, function %s:\n", file, line, function);
fprintf(stderr, "Assertion '%s' failed: ((%s) == false).\n", message, condition);
static void *ptrs[1024] = {};
size_t nptrs = backtrace(ptrs, sizeof(ptrs) / sizeof(ptrs[0]));
char **syms = backtrace_symbols(ptrs, nptrs);
fprintf(stderr, "Backtrace:\n");
if(syms != NULL) {
for(size_t i = 0; i < nptrs; i++) {
fprintf(stderr, "%2zu: %s\n", i, syms[i]);
}
} else {
for(size_t i = 0; i < nptrs; i++) {
fprintf(stderr, "%2zu: %p\n", i, ptrs[i]);
}
}
abort();
}
FILE *ssfopen(const std::string &filename, const char *mode)
{
if(filename.length() != strlen(filename.c_str())) oops();

View File

@ -24,6 +24,17 @@ void dbp(const char *str, ...)
OutputDebugStringA(buf);
}
void assert_failure(const char *file, unsigned line, const char *function,
const char *condition, const char *message) {
dbp("File %s, line %u, function %s:\n", file, line, function);
dbp("Assertion '%s' failed: ((%s) == false).\n", message, condition);
#ifdef NDEBUG
_exit(1);
#else
abort();
#endif
}
std::string Narrow(const wchar_t *in)
{
std::string out;

View File

@ -56,14 +56,26 @@ struct FT_FaceRec_;
#endif
// Debugging functions
#ifdef NDEBUG
#define oops() do { dbp("oops at line %d, file %s\n", __LINE__, __FILE__); \
exit(-1); } while(0)
#if defined(__GNUC__)
#define ssassert(condition, message) \
do { \
if(__builtin_expect((condition), true) == false) { \
SolveSpace::assert_failure(__FILE__, __LINE__, __func__, #condition, message); \
__builtin_unreachable(); \
} \
} while(0)
#else
#define oops() do { dbp("oops at line %d, file %s\n", __LINE__, __FILE__); \
abort(); } while(0)
#define ssassert(condition, message) \
do { \
if((condition) == false) { \
SolveSpace::assert_failure(__FILE__, __LINE__, __func__, #condition, message); \
abort(); \
} \
} while(0)
#endif
#define oops() ssassert(false, "oops() called")
#ifndef isnan
# define isnan(x) (((x) != (x)) || (x > 1e11) || (x < -1e11))
#endif
@ -74,6 +86,12 @@ using std::min;
using std::max;
using std::swap;
#if defined(__GNUC__)
__attribute__((noreturn))
#endif
void assert_failure(const char *file, unsigned line, const char *function,
const char *condition, const char *message);
#if defined(__GNUC__)
__attribute__((__format__ (__printf__, 1, 2)))
#endif