mirror of
https://github.com/matrix-construct/construct
synced 2025-03-17 06:50:23 +01:00
ircd: Add support for configurable soft-assertions.
This commit is contained in:
parent
11afd2e590
commit
ede2439a55
8 changed files with 183 additions and 9 deletions
31
configure.ac
31
configure.ac
|
@ -184,6 +184,34 @@ AM_COND_IF(ASSERT,
|
|||
CPPDEFINE([NDEBUG])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Switch to control the action of assert()
|
||||
dnl
|
||||
|
||||
AC_MSG_CHECKING(whether to change the behavior of assertions)
|
||||
AC_ARG_WITH(assert, AC_HELP_STRING([--with-assert[[[=trap]]]], [Soften assertion behavior]),
|
||||
[
|
||||
assert_type=$withval
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_SUBST(ASSERT_TYPE, $assert_type)
|
||||
], [
|
||||
AM_COND_IF(DEBUG,
|
||||
[
|
||||
assert_type="trap"
|
||||
AC_MSG_RESULT([no, defaulting to "$assert_type"])
|
||||
AC_SUBST(ASSERT_TYPE, $assert_type)
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
AM_COND_IF(ASSERT,
|
||||
[
|
||||
if [[ ! -z "$assert_type" ]]; then
|
||||
RB_DEFINE_UNQUOTED([ASSERT], ["$assert_type"], [Assertion behavior])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Explicit optimize switch for enabling optimization when using --enable-debug
|
||||
dnl
|
||||
|
@ -616,6 +644,7 @@ RB_CHK_SYSHEADER(stdarg.h, [STDARG_H])
|
|||
dnl libc++
|
||||
RB_CHK_SYSHEADER(cstddef, [CSTDDEF])
|
||||
RB_CHK_SYSHEADER(cstdint, [CSTDINT])
|
||||
RB_CHK_SYSHEADER(cstdlib, [CSTDLIB])
|
||||
RB_CHK_SYSHEADER(limits, [LIMITS])
|
||||
RB_CHK_SYSHEADER(type_traits, [TYPE_TRAITS])
|
||||
RB_CHK_SYSHEADER(typeindex, [TYPEINDEX])
|
||||
|
@ -1582,7 +1611,7 @@ echo "Linux AIO support ................. $aio"
|
|||
echo "IPv6 support ...................... $ipv6"
|
||||
echo "Precompiled headers ............... $build_pch"
|
||||
echo "Developer debug ................... $debug"
|
||||
echo "Developer assert .................. $assert"
|
||||
echo "Developer assert .................. $assert ($assert_type)"
|
||||
echo "Optimized build ................... $optimize"
|
||||
echo "Link-time optimized ............... $lto"
|
||||
echo "Optimization level ................ $optimize_level"
|
||||
|
|
39
include/ircd/assert.h
Normal file
39
include/ircd/assert.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
// This header allows for the use of soft-assertions. It is included before
|
||||
// the standard <assert.h> and these declarations will take precedence.
|
||||
//
|
||||
// These declarations exist because the system declarations may have
|
||||
// __attribute__((noreturn)) and our only modification here is to remove
|
||||
// that. Alternative definitions to the standard library also exist in
|
||||
// ircd/assert.cc
|
||||
|
||||
#if defined(RB_ASSERT) && !defined(NDEBUG)
|
||||
#define _ASSERT_H_DECLS
|
||||
|
||||
extern "C" void
|
||||
__assert_fail(const char *__assertion,
|
||||
const char *__file,
|
||||
unsigned int __line,
|
||||
const char *__function);
|
||||
|
||||
extern "C" void
|
||||
__assert_perror_fail(int __errnum,
|
||||
const char *__file,
|
||||
unsigned int __line,
|
||||
const char *__function);
|
||||
|
||||
extern "C" void
|
||||
__assert(const char *__assertion,
|
||||
const char *__file,
|
||||
int __line);
|
||||
|
||||
#endif
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
// Generated by ./configure
|
||||
#include "config.h"
|
||||
#include "assert.h"
|
||||
#include "stdinc.h"
|
||||
#include "string_view.h"
|
||||
#include "vector_view.h"
|
||||
|
|
|
@ -100,7 +100,7 @@ struct ircd::log::log
|
|||
public:
|
||||
template<class... args> void operator()(const level &, const string_view &fmt, args&&...);
|
||||
|
||||
#if RB_LOG_LEVEL >= 0 && !defined(NDEBUG)
|
||||
#if RB_LOG_LEVEL >= 0 && !defined(NDEBUG) && !defined(RB_ASSERT)
|
||||
template<class... args> [[noreturn]] void critical(const string_view &fmt, args&&...);
|
||||
#elif RB_LOG_LEVEL >= 0
|
||||
template<class... args> void critical(const string_view &fmt, args&&...);
|
||||
|
@ -398,18 +398,30 @@ struct ircd::log::error
|
|||
#if RB_LOG_LEVEL >= 0 && !defined(NDEBUG)
|
||||
struct ircd::log::critical
|
||||
{
|
||||
template<class... args> [[noreturn]]
|
||||
template<class... args>
|
||||
#if !defined(RB_ASSERT)
|
||||
[[noreturn]]
|
||||
#endif
|
||||
critical(const log &log, const string_view &fmt, args&&... a)
|
||||
{
|
||||
vlog(log, level::CRITICAL, fmt, va_rtti{std::forward<args>(a)...});
|
||||
ircd::terminate();
|
||||
|
||||
#ifndef NDEBUG
|
||||
__assert_fail("critical", "", 0, "");
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class... args> [[noreturn]]
|
||||
template<class... args>
|
||||
#if !defined(RB_ASSERT)
|
||||
[[noreturn]]
|
||||
#endif
|
||||
critical(const string_view &fmt, args&&... a)
|
||||
{
|
||||
vlog(general, level::CRITICAL, fmt, va_rtti{std::forward<args>(a)...});
|
||||
ircd::terminate();
|
||||
|
||||
#ifndef NDEBUG
|
||||
__assert_fail("critical", "", 0, "");
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#elif RB_LOG_LEVEL >= 0
|
||||
|
@ -570,7 +582,7 @@ ircd::log::log::critical(const string_view &fmt,
|
|||
operator()(level::CRITICAL, fmt, va_rtti{std::forward<args>(a)...});
|
||||
|
||||
#ifndef NDEBUG
|
||||
ircd::terminate();;
|
||||
__assert_fail("critical", "", 0, "");
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -39,6 +39,7 @@ extern "C"
|
|||
|
||||
#include <RB_INC_CSTDDEF
|
||||
#include <RB_INC_CSTDINT
|
||||
#include <RB_INC_CSTDLIB
|
||||
#include <RB_INC_LIMITS
|
||||
#include <RB_INC_TYPE_TRAITS
|
||||
#include <RB_INC_TYPEINDEX
|
||||
|
|
|
@ -100,6 +100,7 @@ libircd_la_LIBADD = \
|
|||
# the units that compile spirit grammars otherwise they thrash weaker
|
||||
# systems.
|
||||
libircd_la_SOURCES = \
|
||||
assert.cc \
|
||||
info.cc \
|
||||
allocator.cc \
|
||||
exception.cc \
|
||||
|
|
91
ircd/assert.cc
Normal file
91
ircd/assert.cc
Normal file
|
@ -0,0 +1,91 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#if !defined(NDEBUG) && defined(RB_ASSERT)
|
||||
#include <RB_INC_SIGNAL_H
|
||||
#endif
|
||||
|
||||
#if !defined(NDEBUG) && defined(RB_ASSERT)
|
||||
void
|
||||
__assert_fail(const char *__assertion,
|
||||
const char *__file,
|
||||
unsigned int __line,
|
||||
const char *__function)
|
||||
{
|
||||
if(strcmp(__assertion, "critical") != 0)
|
||||
fprintf(stderr, "\nassertion failed [%s +%u] %s :%s\n",
|
||||
__file,
|
||||
__line,
|
||||
__function,
|
||||
__assertion);
|
||||
|
||||
if(strcmp(RB_ASSERT, "trap") == 0)
|
||||
__asm__ volatile ("int $3");
|
||||
|
||||
else if(strcmp(RB_ASSERT, "quit") == 0)
|
||||
ircd::quit();
|
||||
|
||||
#if defined(HAVE_EXCEPTION)
|
||||
else if(strcmp(RB_ASSERT, "term") == 0)
|
||||
{
|
||||
std::terminate();
|
||||
__builtin_unreachable();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CSTDLIB)
|
||||
else if(strcmp(RB_ASSERT, "abort") == 0)
|
||||
{
|
||||
abort();
|
||||
__builtin_unreachable();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SIGNAL_H)
|
||||
else if(strcmp(RB_ASSERT, "SIGTRAP") == 0)
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SIGNAL_H)
|
||||
else if(strcmp(RB_ASSERT, "SIGQUIT") == 0)
|
||||
raise(SIGSTOP);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SIGNAL_H)
|
||||
else if(strcmp(RB_ASSERT, "SIGQUIT") == 0)
|
||||
raise(SIGQUIT);
|
||||
#endif
|
||||
|
||||
else __builtin_trap();
|
||||
}
|
||||
#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)
|
||||
void
|
||||
__assert(const char *__assertion,
|
||||
const char *__file,
|
||||
int __line)
|
||||
{
|
||||
__assert_fail(__assertion, __file, __line, "<no function>");
|
||||
}
|
||||
#endif
|
|
@ -25,7 +25,7 @@ noexcept
|
|||
}
|
||||
|
||||
void
|
||||
#ifndef NDEBUG
|
||||
#if !defined(NDEBUG) && !defined(RB_ASSERT)
|
||||
__attribute__((noreturn))
|
||||
#endif
|
||||
ircd::panicking(const std::exception_ptr &eptr)
|
||||
|
@ -41,7 +41,7 @@ noexcept
|
|||
/// log a critical message, which is actually what triggers a termination when
|
||||
/// assertions are enabled (!NDEBUG) otherwise a no-op.
|
||||
void
|
||||
#ifndef NDEBUG
|
||||
#if !defined(NDEBUG) && !defined(RB_ASSERT)
|
||||
__attribute__((noreturn))
|
||||
#endif
|
||||
ircd::panicking(const std::exception &e)
|
||||
|
|
Loading…
Add table
Reference in a new issue