我正致力于遗留应用程序开发,涉及大量信号处理和虚拟化。我在处理下面提到的情况时面临困难......
(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();
}
}
这里,在上面的例子中,sentyscall()在内核内存区域中执行X操作,该操作在sigtrap下经常停止。在这里,哪种信号/警报有助于恢复正常执行(无需杀死)。
答案 0 :(得分:0)
在信号处理程序中阻塞不是一个好主意,在这种情况下很难推断出程序行为。
我建议你在一个单独的线程中执行繁重的操作,这由信号处理程序发出信号,但信号处理程序会快速返回。我创建了一个粗略的例子,基于你的,使用互斥体(在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