Hi,
The following piece of code shows a scenario where the main thread calls pthread_cancel on a background thread that is sleeping.
The sleeping thread would then raise an abort signal that would cause the application to terminate abnormally.
#include <pthread.h> #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> #include <iostream> #include <string.h> using namespace std; struct ToBeDestroyed { ~ToBeDestroyed() { cout << "destructor called"<< endl ; } }; static void * thread_func(void *ignored_argument) { ToBeDestroyed d; sleep(100000); /* Should get canceled while we sleep */ return NULL; } int main(void) { pthread_t thr; void *res; int s; /* Start a thread and then send it a cancellation request */ s = pthread_create(&thr, NULL, &thread_func, NULL); printf("main(): about to send cancellation request in 5 sec ...\n"); sleep(5); /* Give thread a chance to get started */ printf("main(): sending cancellation request\n"); s = pthread_cancel(thr); s = pthread_join(thr, &res); exit(EXIT_SUCCESS); }
The abort stack looks like the following:
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 #1 0x00007ffff6fb442a in __GI_abort () at abort.c:89 #2 0x00007ffff7ae80ad in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x00007ffff7ae6066 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #4 0x00007ffff7ae60b1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #5 0x00007ffff7ae5cd4 in __gxx_personality_v0 () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #6 0x00007ffff754c009 in ?? () from /lib/x86_64-linux-gnu/libgcc_s.so.1 #7 0x00007ffff754c364 in _Unwind_ForcedUnwind () from /lib/x86_64-linux-gnu/libgcc_s.so.1 #8 0x00007ffff732ed60 in __GI___pthread_unwind (buf=<optimized out>) at unwind.c:121 #9 0x00007ffff7324c5a in __do_cancel () at ./pthreadP.h:283 #10 sigcancel_handler (sig=<optimized out>, si=0x7ffff6d7aa70, ctx=<optimized out>) at nptl-init.c:220 #11 <signal handler called> #12 0x00007ffff703828d in nanosleep () at ../sysdeps/unix/syscall-template.S:84 #13 0x00007ffff70381da in __sleep (seconds=0) at ../sysdeps/posix/sleep.c:55 #14 0x00000000004011cb in _INTERNAL9b371893::thread_func(void*) () #15 0x00007ffff7326494 in start_thread (arg=0x7ffff6d7b700) at pthread_create.c:333 #16 0x00007ffff7068acf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97
The exception seems to be caused by the existence a local object on the thread stack that would need to have its destructors called.
If there is no local object on the thread stack the program terminates normally and no abort signal is raised.
Compilation command:
icpc test_pthreadsn.cpp -pthread
icpc version 18.0.2
The same code runs fine when compiled with gcc 6.3.0
Could someone please share some thoughts why this is happening and if it is inherent to the compiler.