If any test got segmentation fault it's better to print something useful
for debug. That function is based on example code for TM. I hope it will
help to see fails in CI where is not clear how to get core files.

Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org>
---
 test/validation/common/odp_cunit_common.c | 67 +++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/test/validation/common/odp_cunit_common.c 
b/test/validation/common/odp_cunit_common.c
index dbd8229..602a508 100644
--- a/test/validation/common/odp_cunit_common.c
+++ b/test/validation/common/odp_cunit_common.c
@@ -4,10 +4,19 @@
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
+#include <odp_posix_extensions.h>
 #include <string.h>
+#include <stdio.h>
+#include <signal.h>
+#include <execinfo.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
 #include <odp_api.h>
 #include <odp_cunit_common.h>
 #include <odp/helper/linux.h>
+
 /* Globals */
 static odph_linux_pthread_t thread_tbl[MAX_WORKERS];
 
@@ -23,6 +32,7 @@ static struct {
 } global_init_term = {tests_global_init, tests_global_term};
 
 static odp_suiteinfo_t *global_testsuites;
+static odp_spinlock_t print_lock;
 
 /** create test thread */
 int odp_cunit_thread_create(void *func_ptr(void *), pthrd_arg *arg)
@@ -115,6 +125,61 @@ static odp_testinfo_t *cunit_get_test_info(odp_suiteinfo_t 
*sinfo,
        return NULL;
 }
 
+static void fault_handler(int signal)
+{
+       size_t num_stack_frames;
+       const char  *signal_name;
+       void  *bt_array[128];
+       sigset_t sigset;
+
+       /* disable all signals */
+       sigfillset(&sigset);
+       sigprocmask(SIG_BLOCK, &sigset, NULL);
+
+       switch (signal) {
+       case SIGILL:
+               signal_name = "SIGILL";   break;
+       case SIGFPE:
+               signal_name = "SIGFPE";   break;
+       case SIGSEGV:
+               signal_name = "SIGSEGV";  break;
+       case SIGTERM:
+               signal_name = "SIGTERM";  break;
+       case SIGBUS:
+               signal_name = "SIGBUS";   break;
+       default:
+               signal_name = "UNKNOWN";  break;
+       }
+
+       odp_spinlock_lock(&print_lock);
+       num_stack_frames = backtrace(bt_array, 100);
+       printf("\nThread %d terminated with signal=%u (%s)\n",
+              odp_thread_id(), signal, signal_name);
+       backtrace_symbols_fd(bt_array, num_stack_frames, fileno(stderr));
+       fflush(NULL);
+       sync();
+       odp_spinlock_unlock(&print_lock);
+
+       CU_ASSERT_FATAL(0);
+}
+
+static void register_fault_handler(void)
+{
+       struct sigaction signal_action;
+
+       odp_spinlock_init(&print_lock);
+
+       memset(&signal_action, 0, sizeof(signal_action));
+       signal_action.sa_handler = fault_handler;
+       sigfillset(&signal_action.sa_mask);
+
+       sigaction(SIGILL,  &signal_action, NULL);
+       sigaction(SIGFPE,  &signal_action, NULL);
+       sigaction(SIGSEGV, &signal_action, NULL);
+       sigaction(SIGTERM, &signal_action, NULL);
+       sigaction(SIGBUS,  &signal_action, NULL);
+}
+
 /* A wrapper for the suite's init function. This is done to allow for a
  * potential runtime check to determine whether each test in the suite
  * is active (enabled by using ODP_TEST_INFO_CONDITIONAL()). If present,
@@ -328,6 +393,8 @@ int odp_cunit_register(odp_suiteinfo_t testsuites[])
 
        CU_set_error_action(CUEA_ABORT);
 
+       register_fault_handler();
+
        CU_initialize_registry();
        global_testsuites = testsuites;
        cunit_register_suites(testsuites);
-- 
2.7.1.250.gff4ea60

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to