Skip to content

SIGSEGV when continuing from SIGINT handler in multi threaded code

I modified the examples/threads/import.c by removing the cl_eval(form) in thread_entry_point, and doing while (1) { printf("Working...\n"); sleep(1); }; instead.

Full code:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#define GC_THREADS
#define _REENTRANT

#include <ecl/ecl.h>

static void *
thread_entry_point(void *data)
{
        cl_object form = (cl_object)data;
        ecl_import_current_thread(ECL_NIL, ECL_NIL);
        while (1) {
          printf("Working...\n");
          sleep(1);
        }
        ecl_release_current_thread();
        return NULL;
}

int main(int narg, char **argv)
{
        pthread_t child_thread;
        int i, code;
        ecl_set_option(ECL_OPT_TRAP_SIGSEGV, 0);
        cl_boot(narg, argv);
        cl_object sym_print = c_string_to_object("PRINT");
        volatile cl_object forms[4];
        for (i = 0; i < 2; i++) {
                forms[i] = cl_list(2, sym_print, MAKE_FIXNUM(i));
                code = pthread_create(&child_thread, NULL, thread_entry_point,
                                      (void*)forms[i]);
                if (code) {
                        printf("Unable to create thread\n");
                        exit(1);
                }
        }
        pthread_join(child_thread, NULL);
        cl_shutdown();
        return 0;
}

When running the modified example, I hit Ctrl-C to get into ECL's SIGINT handler, which presents couple of restarts along with a REPL. Choosing the (continue) restart causes the program to send SIGSEGV. By setting the ECL_OPT_TRAP_SIGSEGV to 0, I get the coredump which indicates that the SIGSEGV is caused by AO_compare_and_swap_full, specifically __sync_bool_compare_and_swap (gcc/x86.h) at lock cmpxchg instruction. This happens both on 16.1.3 and latest development.

(lisp-implementation-version)
"16.1.3"

(software-type)
"Linux"

(software-version)
"4.13.12-1-ARCH"

(machine-type)
"x86_64"

*features*
(:WALKER :CDR-1 :CDR-5 :LINUX :FORMATTER :CDR-7 :ECL-WEAK-HASH :LITTLE-ENDIAN
 :ECL-READ-WRITE-LOCK :LONG-LONG :UINT64-T :UINT32-T :UINT16-T
 :RELATIVE-PACKAGE-NAMES :LONG-FLOAT :UNICODE :DFFI :CLOS-STREAMS :CMU-FORMAT
 :UNIX :ECL-PDE :DLOPEN :CLOS :THREADS :BOEHM-GC :ANSI-CL :COMMON-LISP
 :IEEE-FLOATING-POINT :CDR-14 :PREFIXED-API :FFI :X86_64 :COMMON :ECL)