mirror of
https://github.com/matrix-construct/construct
synced 2024-09-27 11:18:51 +02: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])
|
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
|
||||||
dnl Explicit optimize switch for enabling optimization when using --enable-debug
|
dnl Explicit optimize switch for enabling optimization when using --enable-debug
|
||||||
dnl
|
dnl
|
||||||
|
@ -616,6 +644,7 @@ RB_CHK_SYSHEADER(stdarg.h, [STDARG_H])
|
||||||
dnl libc++
|
dnl libc++
|
||||||
RB_CHK_SYSHEADER(cstddef, [CSTDDEF])
|
RB_CHK_SYSHEADER(cstddef, [CSTDDEF])
|
||||||
RB_CHK_SYSHEADER(cstdint, [CSTDINT])
|
RB_CHK_SYSHEADER(cstdint, [CSTDINT])
|
||||||
|
RB_CHK_SYSHEADER(cstdlib, [CSTDLIB])
|
||||||
RB_CHK_SYSHEADER(limits, [LIMITS])
|
RB_CHK_SYSHEADER(limits, [LIMITS])
|
||||||
RB_CHK_SYSHEADER(type_traits, [TYPE_TRAITS])
|
RB_CHK_SYSHEADER(type_traits, [TYPE_TRAITS])
|
||||||
RB_CHK_SYSHEADER(typeindex, [TYPEINDEX])
|
RB_CHK_SYSHEADER(typeindex, [TYPEINDEX])
|
||||||
|
@ -1582,7 +1611,7 @@ echo "Linux AIO support ................. $aio"
|
||||||
echo "IPv6 support ...................... $ipv6"
|
echo "IPv6 support ...................... $ipv6"
|
||||||
echo "Precompiled headers ............... $build_pch"
|
echo "Precompiled headers ............... $build_pch"
|
||||||
echo "Developer debug ................... $debug"
|
echo "Developer debug ................... $debug"
|
||||||
echo "Developer assert .................. $assert"
|
echo "Developer assert .................. $assert ($assert_type)"
|
||||||
echo "Optimized build ................... $optimize"
|
echo "Optimized build ................... $optimize"
|
||||||
echo "Link-time optimized ............... $lto"
|
echo "Link-time optimized ............... $lto"
|
||||||
echo "Optimization level ................ $optimize_level"
|
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
|
// Generated by ./configure
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "assert.h"
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
#include "string_view.h"
|
#include "string_view.h"
|
||||||
#include "vector_view.h"
|
#include "vector_view.h"
|
||||||
|
|
|
@ -100,7 +100,7 @@ struct ircd::log::log
|
||||||
public:
|
public:
|
||||||
template<class... args> void operator()(const level &, const string_view &fmt, args&&...);
|
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&&...);
|
template<class... args> [[noreturn]] void critical(const string_view &fmt, args&&...);
|
||||||
#elif RB_LOG_LEVEL >= 0
|
#elif RB_LOG_LEVEL >= 0
|
||||||
template<class... args> void critical(const string_view &fmt, args&&...);
|
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)
|
#if RB_LOG_LEVEL >= 0 && !defined(NDEBUG)
|
||||||
struct ircd::log::critical
|
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)
|
critical(const log &log, const string_view &fmt, args&&... a)
|
||||||
{
|
{
|
||||||
vlog(log, level::CRITICAL, fmt, va_rtti{std::forward<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)
|
critical(const string_view &fmt, args&&... a)
|
||||||
{
|
{
|
||||||
vlog(general, level::CRITICAL, fmt, va_rtti{std::forward<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
|
#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)...});
|
operator()(level::CRITICAL, fmt, va_rtti{std::forward<args>(a)...});
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
ircd::terminate();;
|
__assert_fail("critical", "", 0, "");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -39,6 +39,7 @@ extern "C"
|
||||||
|
|
||||||
#include <RB_INC_CSTDDEF
|
#include <RB_INC_CSTDDEF
|
||||||
#include <RB_INC_CSTDINT
|
#include <RB_INC_CSTDINT
|
||||||
|
#include <RB_INC_CSTDLIB
|
||||||
#include <RB_INC_LIMITS
|
#include <RB_INC_LIMITS
|
||||||
#include <RB_INC_TYPE_TRAITS
|
#include <RB_INC_TYPE_TRAITS
|
||||||
#include <RB_INC_TYPEINDEX
|
#include <RB_INC_TYPEINDEX
|
||||||
|
|
|
@ -100,6 +100,7 @@ libircd_la_LIBADD = \
|
||||||
# the units that compile spirit grammars otherwise they thrash weaker
|
# the units that compile spirit grammars otherwise they thrash weaker
|
||||||
# systems.
|
# systems.
|
||||||
libircd_la_SOURCES = \
|
libircd_la_SOURCES = \
|
||||||
|
assert.cc \
|
||||||
info.cc \
|
info.cc \
|
||||||
allocator.cc \
|
allocator.cc \
|
||||||
exception.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
|
void
|
||||||
#ifndef NDEBUG
|
#if !defined(NDEBUG) && !defined(RB_ASSERT)
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
#endif
|
#endif
|
||||||
ircd::panicking(const std::exception_ptr &eptr)
|
ircd::panicking(const std::exception_ptr &eptr)
|
||||||
|
@ -41,7 +41,7 @@ noexcept
|
||||||
/// log a critical message, which is actually what triggers a termination when
|
/// log a critical message, which is actually what triggers a termination when
|
||||||
/// assertions are enabled (!NDEBUG) otherwise a no-op.
|
/// assertions are enabled (!NDEBUG) otherwise a no-op.
|
||||||
void
|
void
|
||||||
#ifndef NDEBUG
|
#if !defined(NDEBUG) && !defined(RB_ASSERT)
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
#endif
|
#endif
|
||||||
ircd::panicking(const std::exception &e)
|
ircd::panicking(const std::exception &e)
|
||||||
|
|
Loading…
Reference in a new issue