0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-05-18 10:53:48 +02:00

ircd: Cleanup / simplify assert related interface.

This commit is contained in:
Jason Volk 2019-08-11 19:02:50 -07:00
parent e7596fba96
commit dffb03a562
3 changed files with 61 additions and 50 deletions

View file

@ -227,6 +227,10 @@ AM_COND_IF(ASSERT,
if [[ ! -z "$assert_type" ]]; then
RB_DEFINE_UNQUOTED([ASSERT], ["$assert_type"], [Assertion behavior])
fi
if [ "$assert_type" == "trap" ]; then
RB_DEFINE([ASSERT_INTRINSIC], [1], [Intrinsic assertion behavior])
fi
])
dnl

View file

@ -19,43 +19,61 @@
#pragma once
#define HAVE_IRCD_ASSERT_H
namespace ircd
{
void debugtrap();
}
/// This file has to be included prior to the standard library assert headers
#if defined(RB_ASSERT) && defined(_ASSERT_H_DECLS) && defined(RB_DEBUG)
#error "Do not include <assert.h> or <cassert> first."
#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)
#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
__attribute__((visibility("default")))
__assert_fail(const char *__assertion,
const char *__file,
unsigned int __line,
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
/// Intrinsic to halt execution for examination by a tracing debugger without
/// aborting the program.
///
extern inline void
__attribute__((always_inline, gnu_inline, artificial))
ircd::debugtrap()
noexcept
{
#if defined(__clang__)
static_assert(__has_builtin(__builtin_debugtrap));

View file

@ -10,30 +10,7 @@
#include <RB_INC_SIGNAL_H
#if !defined(NDEBUG) && defined(RB_ASSERT)
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 IRCD_ASSERT_OVERRIDE
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
@ -44,12 +21,7 @@ __assert_fail(const char *__assertion,
unsigned int __line,
const char *__function)
{
if(strcmp(__assertion, "critical") != 0)
fprintf(stderr, "\nassertion failed [%s +%u] %s :%s\n",
__file,
__line,
__function,
__assertion);
ircd::print_assertion(__assertion, __file, __line, __function);
if(ircd::soft_assert)
return;
@ -97,3 +69,20 @@ __assert_fail(const char *__assertion,
#pragma clang diagnostic pop
#endif __clang__
#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);
}