From 4ee4117810e51dba802348ab17b2e0b1cc264b69 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 1 Apr 2019 11:55:33 -0400 Subject: [PATCH] Re-implement BT_ASSERT without using the assert macro BT_ASSERT is currently defined using the assert macro. If NDEBUG is inadvertently defined, BT_ASSERT has no effect. This is quite unfortunate, since a user who has defined BABELTRACE_DEBUG_MODE to 1 probably wants BT_ASSERT to be effective. This problem was encountered while building the Python bindings, where the distutils native code builder is passing -DNDEBUG to the compiler. The BT_ASSERT macro usages in these files were found to be ineffective. This patch avoids this situation by making BT_ASSERT call our own handler if the assertion fails. This also has the advantage of letting us personalize the behavior on assertion failures. The presence of the so-called Lenny Face having absolutely no regards for the furniture is a good example of this (and was a requirement coming from Philippe Proulx). Removing the inclusion of assert.h in assert-internal.h revealed a few spots that use the assert macro without including assert.h, so they were adjusted accordingly. Signed-off-by: Simon Marchi --- cli/Makefile.am | 2 ++ common/Makefile.am | 2 +- common/assert.c | 36 +++++++++++++++++++ include/babeltrace/assert-internal.h | 12 ++++++- logging/log.c | 1 + .../common/metadata/ctf-meta-update-in-ir.c | 1 + tests/utils/tap/tap.c | 6 ++-- 7 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 common/assert.c diff --git a/cli/Makefile.am b/cli/Makefile.am index 8993c2f8..ed309d02 100644 --- a/cli/Makefile.am +++ b/cli/Makefile.am @@ -89,6 +89,8 @@ babeltrace_CFLAGS = $(AM_CFLAGS) -DBT_SET_DEFAULT_IN_TREE_CONFIGURATION babeltrace_log_bin_SOURCES = babeltrace-log.c babeltrace_log_bin_LDADD = \ $(top_builddir)/compat/libcompat.la \ + $(top_builddir)/common/libbabeltrace-common.la \ + $(top_builddir)/logging/libbabeltrace-logging.la \ $(POPT_LIBS) babeltrace_log_bin_CFLAGS = $(AM_CFLAGS) '-DBT_CLI_PATH="$(abs_top_builddir)/cli/babeltrace$(EXEEXT)"' diff --git a/common/Makefile.am b/common/Makefile.am index 0584b1c8..ce0b661a 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -3,4 +3,4 @@ AM_CPPFLAGS += -DINSTALL_LIBDIR=\"$(libdir)\" noinst_LTLIBRARIES = libbabeltrace-common.la -libbabeltrace_common_la_SOURCES = common.c logging.c logging.h +libbabeltrace_common_la_SOURCES = assert.c common.c logging.c logging.h diff --git a/common/assert.c b/common/assert.c new file mode 100644 index 00000000..d02e9113 --- /dev/null +++ b/common/assert.c @@ -0,0 +1,36 @@ +/* + * Copyright 2019 EfficiOS Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +void bt_common_assert_failed( + const char *file, int line, const char *func, const char *assertion) { + bt_common_color_bold(); + bt_common_color_fg_red(); + fprintf(stderr, + "%s%s:%d: %s: Assertion %s`%s`%s failed. (╯ ͡° □ ͡°)╯︵ ┻━┻%s\n", + bt_common_color_bold(), file, line, func, + bt_common_color_fg_red(), assertion, + bt_common_color_fg_default(), bt_common_color_reset()); + abort(); +} \ No newline at end of file diff --git a/include/babeltrace/assert-internal.h b/include/babeltrace/assert-internal.h index 431230c9..f8fd0b92 100644 --- a/include/babeltrace/assert-internal.h +++ b/include/babeltrace/assert-internal.h @@ -28,12 +28,22 @@ #include #ifdef BT_DEBUG_MODE + +extern void bt_common_assert_failed(const char *file, int line, + const char *func, const char *assertion) __attribute__((noreturn)); + /* * Internal assertion (to detect logic errors on which the library user * has no influence). Use BT_ASSERT_PRE() to check a precondition which * must be directly or indirectly satisfied by the library user. */ -# define BT_ASSERT(_cond) do { assert(_cond); } while (0) +#define BT_ASSERT(_cond) \ + do { \ + if (!(_cond)) { \ + bt_common_assert_failed(__FILE__, __LINE__, __func__, \ + TOSTRING(_cond)); \ + } \ + } while (0) /* * Marks a function as being only used within a BT_ASSERT() context. diff --git a/logging/log.c b/logging/log.c index f2fa0cb6..0d317f03 100644 --- a/logging/log.c +++ b/logging/log.c @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef __CYGWIN__ extern unsigned long pthread_getsequence_np(pthread_t *); diff --git a/plugins/ctf/common/metadata/ctf-meta-update-in-ir.c b/plugins/ctf/common/metadata/ctf-meta-update-in-ir.c index 5ad71c85..5048c53a 100644 --- a/plugins/ctf/common/metadata/ctf-meta-update-in-ir.c +++ b/plugins/ctf/common/metadata/ctf-meta-update-in-ir.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "ctf-meta-visitors.h" diff --git a/tests/utils/tap/tap.c b/tests/utils/tap/tap.c index d3d3f3df..5699f387 100644 --- a/tests/utils/tap/tap.c +++ b/tests/utils/tap/tap.c @@ -29,9 +29,9 @@ #include #include #include -#include #include #include +#include #include "tap.h" @@ -304,7 +304,7 @@ diag_multiline(const char *val) { size_t len, i, line_start_idx = 0; - BT_ASSERT(val); + assert(val); len = strlen(val); for (i = 0; i < len; i++) { @@ -314,7 +314,7 @@ diag_multiline(const char *val) continue; } - BT_ASSERT((i - line_start_idx + 1) <= INT_MAX); + assert((i - line_start_idx + 1) <= INT_MAX); line_length = i - line_start_idx + 1; fprintf(stderr, "# %.*s", line_length, &val[line_start_idx]); line_start_idx = i + 1; -- 2.34.1