when we use raise in GCD, the signal handler is executed asynchronously, whereas in pthread, it is executed synchronously as expected.
example:
#include <Foundation/Foundation.h>
#include <pthread/pthread.h>
static void HandleSignal(int sigNum, siginfo_t* signalInfo, void* userContext) {
printf("handle signal %d\n", sigNum);
printf("begin sleep\n");
sleep(3);
printf("end sleep\n");
}
void InstallSignal(void) {
static const int g_fatalSignals[] =
{
SIGABRT,
SIGBUS,
SIGFPE,
SIGILL,
SIGPIPE,
SIGSEGV,
SIGSYS,
SIGTRAP,
};
int fatalSignalsCount = sizeof(g_fatalSignals) / sizeof(int);
struct sigaction action = {{0}};
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
#if defined(__LP64__)
action.sa_flags |= SA_64REGSET;
#endif
sigemptyset(&action.sa_mask);
action.sa_sigaction = &HandleSignal;
struct sigaction pre_sa;
for(int i = 0; i < fatalSignalsCount; i++) {
int sigResult = sigaction(g_fatalSignals[i], &action, &pre_sa);
}
}
void* RaiseAbort(void *userdata) {
raise(SIGABRT);
printf("signal handler has finished\n");
return NULL;
}
int main(int argc, const char * argv[]) {
InstallSignal();
dispatch_async(dispatch_get_global_queue(0, 0), ^{
raise(SIGABRT);
// abort(); // abort() is ok
RaiseAbort(nullptr);
});
// pthread is ok
// pthread_t tid;
// int ret = pthread_create(&tid, NULL, RaiseAbort, NULL);
// if (ret != 0) {
// fprintf(stderr, "create thread failed\n");
// return EXIT_FAILURE;
// }
[[NSRunLoop mainRunLoop] run];
return 0;
}
console log:
signal handler has finished
handle signal 6
begin sleep
end sleep