[英]Signal handler terminates program
I try to install a signalhandler using sigaction and then call it on a single thread like this: 我尝试使用sigaction安装信号处理程序,然后在单个线程上调用它,如下所示:
void
my_signal_handler ( int signo, siginfo_t *info, void *extra )
{
printf("my signal handler\n" );
}
int threadsupervisor() {
<...>
struct sigaction action;
struct sigaction oldHandler;
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = my_signal_handler;
sigaction(SIGRTMIN + 3, &action, &oldHandler );
// send signal to affected thread
pthread_kill( threadId, SIGRTMIN + 3 );
// restore original signal handler
sigaction( SIGRTMIN + 3, &oldHandler, NULL );
}
The thread does receive a SIG37, then the whole application terminates. 该线程确实收到一个SIG37,然后整个应用程序终止。 Shouldn't the program/thread continue after the signal handler is done?
信号处理程序完成后,程序/线程是否应该继续执行?
Regards 问候
The main problem is that the restore original signal handler
is executed too early. 主要问题是
restore original signal handler
执行得太早。
I wrote a SystemTap script to trace do_sigaction
and do_signal
, as follows: 我编写了一个SystemTap脚本来跟踪
do_sigaction
和do_signal
,如下所示:
probe begin {
printf("start.\n");
}
probe kernel.function("do_signal") {
if ("test_sigaction" == execname()) {
printf("do_signal pid=%d\n", pid());
}
}
probe kernel.function("handle_signal") {
if ("test_sigaction" == execname()) {
printf("handle_signal pid=%d\n", pid());
}
}
probe kernel.function("do_sigaction").return {
if ("test_sigaction" == execname()) {
printf("do_sigaction: ret=%d sig=%d act=%p oact=%p pid=%d\n",
$return, @entry($sig), @entry($act),
@entry($oact), pid());
}
}
The result is 结果是
do_sigaction: ret=0 sig=37 act=0xffffc90006ccbec8 oact=0xffffc90006ccbee8 pid=45920 //STEP1
do_sigaction: ret=0 sig=37 act=0xffffc90006ccbec8 oact=0x0 pid=45920 //STEP2
do_signal pid=45920 //STEP3
do_signal pid=45920
The reason: 原因:
Obviously there are concurrency issues here. 显然这里存在并发问题。 It is possible to restore the signal handler before executing do_signal.
在执行do_signal之前可以恢复信号处理程序。 Concurrent control is required before restore the signal handler, or move restore handler to my_signal_handler function, like as:
在还原信号处理程序之前,或将还原处理程序移至my_signal_handler函数之前,需要并发控制,例如:
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct sigaction oldHandler;
void my_signal_handler(int signo, siginfo_t *info, void *extra)
{
printf("my signal handler\n" );
// restore original signal handler
sigaction( SIGRTMIN + 3, &oldHandler, NULL );
}
int threadsupervisor(pthread_t thread_id)
{
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = my_signal_handler;
sigaction(SIGRTMIN + 3, &action, &oldHandler );
// send signal to affected thread
pthread_kill(thread_id, SIGRTMIN + 3 );
return 0;
}
void *test_thread(void *args)
{
long loop = 0;
while(1) {
printf("sleep %ld\n", ++loop);
sleep(1);
}
return (void *)NULL;
}
int main()
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, test_thread, NULL);
threadsupervisor(thread_id);
pthread_join(thread_id, NULL);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.