mirror of
https://github.com/matrix-construct/construct
synced 2024-06-18 09:58:22 +02:00
ircd: Cleanup / simplify assert related interface.
This commit is contained in:
parent
e7596fba96
commit
dffb03a562
|
@ -227,6 +227,10 @@ AM_COND_IF(ASSERT,
|
||||||
if [[ ! -z "$assert_type" ]]; then
|
if [[ ! -z "$assert_type" ]]; then
|
||||||
RB_DEFINE_UNQUOTED([ASSERT], ["$assert_type"], [Assertion behavior])
|
RB_DEFINE_UNQUOTED([ASSERT], ["$assert_type"], [Assertion behavior])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$assert_type" == "trap" ]; then
|
||||||
|
RB_DEFINE([ASSERT_INTRINSIC], [1], [Intrinsic assertion behavior])
|
||||||
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
|
|
|
@ -19,43 +19,61 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#define HAVE_IRCD_ASSERT_H
|
#define HAVE_IRCD_ASSERT_H
|
||||||
|
|
||||||
namespace ircd
|
/// This file has to be included prior to the standard library assert headers
|
||||||
{
|
|
||||||
void debugtrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(RB_ASSERT) && defined(_ASSERT_H_DECLS) && defined(RB_DEBUG)
|
#if defined(RB_ASSERT) && defined(_ASSERT_H_DECLS) && defined(RB_DEBUG)
|
||||||
#error "Do not include <assert.h> or <cassert> first."
|
#error "Do not include <assert.h> or <cassert> first."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Define an indicator for whether we override standard assert() behavior in
|
||||||
|
/// this build if the conditions are appropriate.
|
||||||
#if defined(RB_ASSERT) && !defined(NDEBUG)
|
#if defined(RB_ASSERT) && !defined(NDEBUG)
|
||||||
#define _ASSERT_H_DECLS
|
#define IRCD_ASSERT_OVERRIDE
|
||||||
|
#define _ASSERT_H_DECLS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Our utils
|
||||||
|
namespace ircd
|
||||||
|
{
|
||||||
|
void print_assertion(const char *const &, const char *const &, const unsigned &, const char *const &) noexcept;
|
||||||
|
void debugtrap() noexcept;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Override the standard assert behavior, if enabled, to trap into the
|
||||||
|
/// debugger as close as possible to the offending site.
|
||||||
|
///
|
||||||
|
#if defined(IRCD_ASSERT_OVERRIDE) && defined(RB_ASSERT_INTRINSIC)
|
||||||
|
extern "C" inline void
|
||||||
|
__attribute__((flatten, always_inline, gnu_inline, artificial))
|
||||||
|
__assert_fail(const char *__assertion,
|
||||||
|
const char *__file,
|
||||||
|
unsigned int __line,
|
||||||
|
const char *__function)
|
||||||
|
{
|
||||||
|
ircd::print_assertion(__assertion, __file, __line, __function);
|
||||||
|
ircd::debugtrap();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Override the standard assert behavior to take one of several different
|
||||||
|
/// actions as defined in our internal assert.cc unit. When trapping assert
|
||||||
|
/// is disabled this path will be used instead.
|
||||||
|
///
|
||||||
|
#if defined(IRCD_ASSERT_OVERRIDE) && !defined(RB_ASSERT_INTRINSIC)
|
||||||
extern "C" void
|
extern "C" void
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default")))
|
||||||
__assert_fail(const char *__assertion,
|
__assert_fail(const char *__assertion,
|
||||||
const char *__file,
|
const char *__file,
|
||||||
unsigned int __line,
|
unsigned int __line,
|
||||||
const char *__function);
|
const char *__function);
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
__attribute__((visibility("default")))
|
|
||||||
__assert_perror_fail(int __errnum,
|
|
||||||
const char *__file,
|
|
||||||
unsigned int __line,
|
|
||||||
const char *__function);
|
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
__attribute__((visibility("default")))
|
|
||||||
__assert(const char *__assertion,
|
|
||||||
const char *__file,
|
|
||||||
int __line);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Intrinsic to halt execution for examination by a tracing debugger without
|
||||||
|
/// aborting the program.
|
||||||
|
///
|
||||||
extern inline void
|
extern inline void
|
||||||
__attribute__((always_inline, gnu_inline, artificial))
|
__attribute__((always_inline, gnu_inline, artificial))
|
||||||
ircd::debugtrap()
|
ircd::debugtrap()
|
||||||
|
noexcept
|
||||||
{
|
{
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
static_assert(__has_builtin(__builtin_debugtrap));
|
static_assert(__has_builtin(__builtin_debugtrap));
|
||||||
|
|
|
@ -10,30 +10,7 @@
|
||||||
|
|
||||||
#include <RB_INC_SIGNAL_H
|
#include <RB_INC_SIGNAL_H
|
||||||
|
|
||||||
#if !defined(NDEBUG) && defined(RB_ASSERT)
|
#ifdef IRCD_ASSERT_OVERRIDE
|
||||||
void
|
|
||||||
__assert(const char *__assertion,
|
|
||||||
const char *__file,
|
|
||||||
int __line)
|
|
||||||
{
|
|
||||||
__assert_fail(__assertion, __file, __line, "<no function>");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(NDEBUG) && defined(RB_ASSERT)
|
|
||||||
void
|
|
||||||
__assert_perror_fail(int __errnum,
|
|
||||||
const char *__file,
|
|
||||||
unsigned int __line,
|
|
||||||
const char *__function)
|
|
||||||
{
|
|
||||||
char buf[32];
|
|
||||||
snprintf(buf, sizeof(buf), "perror #%d: ", __errnum);
|
|
||||||
__assert_fail(buf, __file, __line, __function);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(NDEBUG) && defined(RB_ASSERT)
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||||
|
@ -44,12 +21,7 @@ __assert_fail(const char *__assertion,
|
||||||
unsigned int __line,
|
unsigned int __line,
|
||||||
const char *__function)
|
const char *__function)
|
||||||
{
|
{
|
||||||
if(strcmp(__assertion, "critical") != 0)
|
ircd::print_assertion(__assertion, __file, __line, __function);
|
||||||
fprintf(stderr, "\nassertion failed [%s +%u] %s :%s\n",
|
|
||||||
__file,
|
|
||||||
__line,
|
|
||||||
__function,
|
|
||||||
__assertion);
|
|
||||||
|
|
||||||
if(ircd::soft_assert)
|
if(ircd::soft_assert)
|
||||||
return;
|
return;
|
||||||
|
@ -97,3 +69,20 @@ __assert_fail(const char *__assertion,
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif __clang__
|
#endif __clang__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::print_assertion(const char *const &__assertion,
|
||||||
|
const char *const &__file,
|
||||||
|
const unsigned &__line,
|
||||||
|
const char *const &__function)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
if(strcmp(__assertion, "critical") == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fprintf(stderr, "\nassertion failed [%s +%u] %s :%s\n",
|
||||||
|
__file,
|
||||||
|
__line,
|
||||||
|
__function,
|
||||||
|
__assertion);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue