c - 信号处理程序返回并恢复程序执行

标签 c linux signals powerpc signal-handling

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

程序流程:

(A) SIGTRAP -> (B) Process -> (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();

}
}

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

最佳答案

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

我建议您在一个单独的线程中完成繁重的工作,这由信号处理程序发出信号,但信号处理程序会很快返回。我创建了一个粗略的示例,基于您的示例,使用互斥锁(在 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

关于c - 信号处理程序返回并恢复程序执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22721374/

相关文章:

多个文件错误 : dereferencing pointer to incomplete type 中的 c 结构

c - strcpy 从一个 struct char* 到另一个 struct char* - 段错误

c - 如果语句为真,如何只显示 printf 语句?

C 双值向上舍入

linux - 为什么在支持 X 线程的硬件中使用 X 线程?为什么不是 X-1 线程?

django - 创建实例时如何更新 ManyToManyField

c - sigtimedwait() 在超时前返回 EAGAIN

c - 为什么在结构和套接字创建中提到套接字的地址族?

linux - 在 Linux shell 脚本上运行行选择

qt - 杀死停止并恢复的 QProcess