assert: throw FailedAssertion exception instead of inducing segfault

This will allow callers to catch failed assertions, if they so
choose.
This commit is contained in:
Sage Weil 2009-06-26 09:44:37 -07:00
parent 14d7fdf248
commit c5faf4097a
2 changed files with 35 additions and 15 deletions

View File

@ -8,25 +8,30 @@
void __ceph_assert_fail(const char *assertion, const char *file, int line, const char *func)
{
BackTrace bt(1);
BackTrace *bt = new BackTrace(1);
_dout_lock.TryLock();
*_dout << file << ": In function '" << func << "':" << std::endl;
*_dout << file << ":" << line << ": FAILED assert(" << assertion << ")" << std::endl;
bt.print(*_dout);
bt->print(*_dout);
*_dout << " NOTE: a copy of the executable, or `objdump -rdS <executable>` is needed to interpret this." << std::endl;
_dout->flush();
cerr << file << ": In function '" << func << "':" << std::endl;
cerr << file << ":" << line << ": FAILED assert(" << assertion << ")" << std::endl;
bt.print(cerr);
bt->print(cerr);
cerr << " NOTE: a copy of the executable, or `objdump -rdS <executable>` is needed to interpret this." << std::endl;
cerr.flush();
char *p = 0;
while (1)
*p-- = 0; // make myself core dump.
if (1) {
throw new FailedAssertion(bt);
} else {
// make myself core dump.
char *p = 0;
while (1)
*p-- = 0;
}
}
void __ceph_assert_warn(const char *assertion, const char *file, int line, const char *func)

View File

@ -4,6 +4,18 @@
#include <features.h>
#include "common/tls.h"
#ifdef __cplusplus
class BackTrace;
struct FailedAssertion {
BackTrace *backtrace;
FailedAssertion(BackTrace *bt) : backtrace(bt) {}
};
#endif
#if defined __cplusplus && __GNUC_PREREQ (2,95)
# define __CEPH_ASSERT_VOID_CAST static_cast<void>
#else
@ -28,12 +40,19 @@
extern void __ceph_assert_fail(const char *assertion, const char *file, int line, const char *function)
__attribute__ ((__noreturn__));
extern void __ceph_assert_warn(const char *assertion, const char *file, int line, const char *function);
#if 1
#define assert(expr) \
((expr) \
? __CEPH_ASSERT_VOID_CAST (0) \
: __ceph_assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION))
#else
#define assert_warn(expr) \
((expr) \
? __CEPH_ASSERT_VOID_CAST (0) \
: __ceph_assert_warn (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION))
/*
#define assert(expr) \
do { \
static int __assert_flag = 0; \
@ -47,15 +66,11 @@ extern void __ceph_assert_warn(const char *assertion, const char *file, int line
: __ceph_assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION)); \
} while (0)
#endif
#define assert_warn(expr) \
((expr) \
? __CEPH_ASSERT_VOID_CAST (0) \
: __ceph_assert_warn (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION))
*/
/*
#define assert_protocol(expr) assert(expr)
#define assert_disk(expr) assert(expr)
*/
#endif