【问题标题】:Signal Handler return and resume the program executionSignal Handler 返回并恢复程序执行
【发布时间】:2014-05-08 10:03:35
【问题描述】:

我正在从事涉及大量信号处理和虚拟化的遗留应用程序开发。我很难理解下面提到的场景......

程序流程:

(A) SIGTRAP -> (B) 进程 -> (C) SIGTRAPHANDLER -> (D) foo() [在 libfoo 中实现的功能] -> (E) 向内核发送消息(通过 NETLINK 套接字)-> (F ) 返回

(A) is the sigtrap signal which is sent to process1 
(B) is the normal user space process 
(C) is the sigtrap handler invoked upon sigtrap signal 
(D) foo() function is invoked under sigtrap handler and the function implemention is in libfoo library
(E) Upon the invocation of foo() function , message is send to query x() data from kernel thru netlink socket
(F) Successful message reply

在这里,在事件 (F) 处,如果未收到消息回复,则进程 (B) 将永远停止,从而导致依赖于 (B) 的所有其他进程失败。

到目前为止,我尝试使用 alarm() 中断信号,但这无助于恢复程序执行,而是只能将 alarm() 视为恢复/清理的东西。

有人可以帮助我了解如何恢复程序执行(在进程 B 上下文中)吗?

对不起,如果解释不清楚和准确。

平台:Linux、C

int main() {

bind_sigtrap_hand(); 
bind_sigalarm_hand();
bind_handler_for_others();

}

bind_sigtrap_hand() {

sa.sa_handler = invoke_me_sigtrap;
if (sigaction(SIGTRAP, &sa, NULL)  != 0)
{
//Error
}
}
bind_sigalarm_hand() {

sa.sa_handler = invoke_me_sigalarm;
if (sigaction(TIMER_SIGNAL, &sa, NULL)  != 0)
{
//Error
}

}

void invoke_me_sigtrap(sig stuff)
{

if (SIGTRAP == sendsys){

sendsyscall();

}
}

在这里,在上面的示例中,sendsyscall() 在内核内存区域中执行 X 操作,该操作经常在 sigtrap 下停止。在这里,哪种信号/警报有助于恢复进程(不杀死)到正常执行。

【问题讨论】:

  • 你应该展示一些源代码。否则你的解释不够清楚!
  • @BasileStarynkevitch 谢谢巴西尔。端到端代码非常大。所以试图捕捉上面更新的问题框中的伪代码。你/大家能帮我吗?

标签: c linux signals powerpc signal-handling


【解决方案1】:

在信号处理程序中阻塞不是一个好主意,在这种情况下很难推断程序行为。

我建议您在一个单独的线程中完成繁重的工作,该线程由信号处理程序发出信号,但信号处理程序很快返回。我创建了一个基于您的粗略示例,使用互斥锁(在 Linux 中工作),但最好使用消息队列来向处理程序线程发出信号:

#include <stdio.h>
#include <signal.h>
#include <pthread.h>

void sendsyscall() {printf("sendsyscall blocks for a long time\n"); sleep(3); printf("sendsyscall done\n");}
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void*thread(void*arg) {printf("in helper thread\n");
for(;;) {
        printf("thread-locking\n");
         pthread_mutex_lock(&mutex);
        printf("thread-unlocking\n");
         pthread_mutex_unlock(&mutex);
        printf("thread calling the troubled sendsyscall()\n");
         sendsyscall();
         sleep(1);//this is a hack, use msgrcv instead of a mutex
}
}//thread

int main() {
pthread_t thread_id;
printf("MAIN1\n");
pthread_mutex_lock(&mutex);
pthread_create(&thread_id,NULL,thread,NULL);
printf("MAIN2\n");
bind_sigtrap_hand();
bind_sigalarm_hand();
//bind_handler_for_others();
for(;;) {sleep(1); printf(".");}
}

void invoke_me_sigtrap(int sendsys)
{
        printf("invoke_me_sigtrap(%d)\n",sendsys);
if (SIGTRAP == sendsys) {
        //INSTEAD OF: sendsyscall(); WE DO:
        pthread_mutex_unlock(&mutex);
        printf("hopefully, sendsyscall() executes in the other thread\n");
        sleep(1);//this is a hack, use msgsnd instead of a mutex
        pthread_mutex_lock(&mutex);
        printf("main thread resumes quickly\n");
}
}

//END OF NEW CODE, ORIGINAL SAMPLE FOLLOWS
bind_sigtrap_hand() {
struct sigaction sa;
sa.sa_handler = invoke_me_sigtrap;
if (sigaction(SIGTRAP, &sa, NULL)  != 0)
{
//Error
}
}//bind_sigtrap_hand

#define TIMER_SIGNAL SIGALRM
void invoke_me_sigalarm(int signal) { }
bind_sigalarm_hand() {
struct sigaction sa;
sa.sa_handler = invoke_me_sigalarm;
if (sigaction(TIMER_SIGNAL, &sa, NULL)  != 0)
{
//Error
}

}//bind_sigalarm_hand

【讨论】:

  • Blocking in the signal handler is not a good idea,... -->> 在信号处理程序中调用 printf() 也不是一个好主意...
  • @Madaa Kaama :感谢您提供的代码。代码非常遗留,没有机会将多线程编程固定在那里。我正在寻找某种 sigaction 来帮助中断 SIGTRAP 并在没有 _exit() 的情况下从它离开的地方(最后一个 nip)恢复进程执行;
  • @wildplasser:完全相同的问题。我不想在信号处理程序中被阻塞超过 5 毫秒。而且,如果信号处理程序工作未在预期时间(5 毫秒)内完成,也不想终止进程。
  • 由于代码使用sigaction(),它不是“非常遗留”。既然你使用 sigaction(),你也应该看看 sigsetmask() 和 sigprocmask() 和朋友。顺便说一句:如果 foo() 是“外部”库的一部分,则可能是该库(重新)安装了它自己的信号处理程序。
  • @wildplasser:感谢您的回复。我仔细检查了 foo() 库代码,但找不到任何与信号手相关的代码。我怀疑的代码真的是 netlink 套接字 recv call() ..顺便说一句,如果有人可以帮助设置警报()或调度中断以中断此系统调用.. 我尝试了示例编,但我无法在 sigtrap 下恢复程序执行,而是我采取了不同的sigcontext (sigalarm) 并且必须 _exit() 进程执行..
猜你喜欢
  • 2021-09-21
  • 2011-08-11
  • 2022-01-10
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
  • 2011-03-20
  • 2013-05-10
  • 2021-11-15
相关资源
最近更新 更多