Always abort on DDS_FATAL variants + test (#270)
The test only works on Linux and macOS because of the system dependencies in catching an abort. The logging code is platform independent so testing only on these platforms still gives a good sanity check. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
50e63b3324
commit
5a746cad81
2 changed files with 105 additions and 1 deletions
|
@ -64,7 +64,7 @@ static void default_sink (void *ptr, const dds_log_data_t *data)
|
||||||
|
|
||||||
static struct ddsrt_log_cfg_impl logconfig = {
|
static struct ddsrt_log_cfg_impl logconfig = {
|
||||||
.c = {
|
.c = {
|
||||||
.mask = DDS_LC_ERROR | DDS_LC_WARNING,
|
.mask = DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL,
|
||||||
.tracemask = 0,
|
.tracemask = 0,
|
||||||
.domid = UINT32_MAX
|
.domid = UINT32_MAX
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#endif /* __APPLE__ */
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
#include "CUnit/Test.h"
|
#include "CUnit/Test.h"
|
||||||
|
#include "CUnit/Theory.h"
|
||||||
#include "dds/ddsrt/heap.h"
|
#include "dds/ddsrt/heap.h"
|
||||||
#include "dds/ddsrt/log.h"
|
#include "dds/ddsrt/log.h"
|
||||||
#include "dds/ddsrt/misc.h"
|
#include "dds/ddsrt/misc.h"
|
||||||
|
@ -403,3 +404,106 @@ CU_Test(dds_log, synchronous_sink_changes, .fini=reset)
|
||||||
CU_ASSERT(arg.after < dds_time());
|
CU_ASSERT(arg.after < dds_time());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sanity checks that FATAL calls abort() -- this is very much platform
|
||||||
|
dependent code, so we only do it on Linux and macOS, assuming that
|
||||||
|
the logging implementation doesn't make any distinction between different
|
||||||
|
platforms and that abort() is correctly implemented by the C library.
|
||||||
|
|
||||||
|
macOS: abort causes abnormal termination unless the handler doesn't return,
|
||||||
|
hence the setjmp/longjmp. */
|
||||||
|
#if defined __linux || defined __APPLE__
|
||||||
|
#define TEST_DDS_LC_FATAL 1
|
||||||
|
#else
|
||||||
|
#define TEST_DDS_LC_FATAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_DDS_LC_FATAL
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
static sigjmp_buf abort_jmpbuf;
|
||||||
|
static char abort_message[100];
|
||||||
|
static char abort_message_trace[100];
|
||||||
|
static ddsrt_log_cfg_t abort_logconfig;
|
||||||
|
|
||||||
|
static void abort_handler (int sig)
|
||||||
|
{
|
||||||
|
(void) sig;
|
||||||
|
siglongjmp (abort_jmpbuf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void abort_log (void *arg, const dds_log_data_t *info)
|
||||||
|
{
|
||||||
|
(void) arg;
|
||||||
|
ddsrt_strlcpy (abort_message, info->message, sizeof (abort_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void abort_trace (void *arg, const dds_log_data_t *info)
|
||||||
|
{
|
||||||
|
(void) arg;
|
||||||
|
ddsrt_strlcpy (abort_message_trace, info->message, sizeof (abort_message_trace));
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_TheoryDataPoints(dds_log, fatal_aborts) = {
|
||||||
|
CU_DataPoints(bool, false, false, false, true, true, true), /* global/config */
|
||||||
|
CU_DataPoints(int, 0, 1, 2, 0, 1, 2), /* mask init mode */
|
||||||
|
CU_DataPoints(bool, false, false, true, false, false, true) /* expect in trace? */
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
CU_TheoryDataPoints(dds_log, fatal_aborts) = {
|
||||||
|
CU_DataPoints(bool, false), /* global/config */
|
||||||
|
CU_DataPoints(int, 0), /* mask init mode */
|
||||||
|
CU_DataPoints(bool, false) /* expect in trace? */
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CU_Theory((bool local, int mode, bool expect_in_trace), dds_log, fatal_aborts)
|
||||||
|
{
|
||||||
|
#if TEST_DDS_LC_FATAL
|
||||||
|
struct sigaction action, oldaction;
|
||||||
|
action.sa_flags = 0;
|
||||||
|
action.sa_handler = abort_handler;
|
||||||
|
|
||||||
|
if (sigsetjmp (abort_jmpbuf, 0) != 0)
|
||||||
|
{
|
||||||
|
sigaction (SIGABRT, &oldaction, NULL);
|
||||||
|
CU_ASSERT_STRING_EQUAL (abort_message, "oops\n");
|
||||||
|
CU_ASSERT_STRING_EQUAL (abort_message_trace, expect_in_trace ? "oops\n" : "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset (abort_message, 0, sizeof (abort_message));
|
||||||
|
memset (abort_message_trace, 0, sizeof (abort_message_trace));
|
||||||
|
dds_set_log_sink (abort_log, NULL);
|
||||||
|
dds_set_trace_sink (abort_trace, NULL);
|
||||||
|
sigaction (SIGABRT, &action, &oldaction);
|
||||||
|
if (local)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
/* FALL THROUGH */
|
||||||
|
case 1: dds_log_cfg_init (&abort_logconfig, 0, 0, 0, 0); break;
|
||||||
|
case 2: dds_log_cfg_init (&abort_logconfig, 0, DDS_LC_TRACE, 0, 0); break;
|
||||||
|
}
|
||||||
|
DDS_CLOG (DDS_LC_FATAL, &abort_logconfig, "oops\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 0: break;
|
||||||
|
case 1: dds_set_log_mask (0); break;
|
||||||
|
case 2: dds_set_log_mask (DDS_LC_TRACE); break;
|
||||||
|
}
|
||||||
|
DDS_FATAL ("oops\n");
|
||||||
|
}
|
||||||
|
sigaction (SIGABRT, &oldaction, NULL);
|
||||||
|
CU_ASSERT (0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void) local;
|
||||||
|
(void) mode;
|
||||||
|
(void) expect_in_trace;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue