gpt4 book ai didi

c++ - 子级和父级 C 程序中的 SIGSEGV 处理

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:48:48 26 4
gpt4 key购买 nike

下面提到的是我的 C++ 程序。当在任何子进程或父进程内部生成段错误信号时,我想终止所有子进程和父进程。

我从 linux 内核得到 sigterm 信号到达 handle_signal 函数。但我坚持在后来的流程中,调试时我什至看到 gSegSignalRcvd=1 已设置。但是过程控制没有到达子 r 父中的任何 for 循环。


#include<iostream>
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>

bool gSignalRcvd = 0;
bool gSegSignalRcvd = 0;

pid_t lCid1;
pid_t lCid2;
pid_t lPid;

void handle_signal(int sig)
{
switch(sig)
{
case SIGSEGV:
{
gSegSignalRcvd = 1;
printf("Reecived Signal:%d SegSignal:%d\n", gSignalRcvd, gSegSignalRcvd);
}
default:
printf("Reecived Signal :%d\n",sig);
};
gSignalRcvd = 1;
signal(SIGSEGV, handle_signal);
}

int main()
{
signal(SIGSEGV, handle_signal);

lCid1 = fork();

if(lCid1 < 0)
{
printf("Error in child Creation Err:%d\n", lCid1);
exit(1);
}
else if(lCid1 > 0)
{
lCid2 = fork();

if(lCid2 < 0)
{
printf("Error in child Creation Err:%d\n", lCid1);
exit(2);
}
else if(lCid2 > 0)
{
struct tm * lTimePtr;
int lSleepTime=0;
int mUploadTime=0;
int lCount = 1;
time_t lTimeObj;

for(;;)
{
lCount = lCount++;
printf("Received Signal @ Parent Seg:%d Sig%d\n", gSegSignalRcvd, gSignalRcvd);
if(gSignalRcvd)
{
if(gSegSignalRcvd)
{
printf("Received Signal Inside Parent now killing the Process\n");
kill(lCid1, SIGTERM);
kill(lCid2, SIGTERM);
kill(getpid(), SIGTERM);
}
}
gSignalRcvd = 0;

printf("Time:%ld tm_min:%d tm_sec:%d UploadTime:%d SleepTime:%d\n", lTimeObj, lTimePtr->tm_min, lTimePtr->tm_sec, mUploadTime, lSleepTime);

sleep(mUploadTime + lCount);
}
}
else
{
int lNumb,lResult;

for(;;)
{
printf("Received Signal @ Child2 Seg:%d Sig%d\n", gSegSignalRcvd, gSignalRcvd);
if(gSignalRcvd)
{
if(gSegSignalRcvd)
{
printf("Received Signal Inside Child2 **************\n");
kill(lCid1, SIGTERM);
kill(lCid2, SIGTERM);
kill(getpid(), SIGTERM);
}
}
gSignalRcvd = 0;
printf("Printing the Child2 Value\n");
lNumb = rand() / 100;

lResult = lNumb / 2;
printf("Number:%s Result:%d\n", lNumb, lResult);

usleep(lNumb);
}
}
}
else
{
for(;;)
{
printf("Received Signal @ Child1 Seg:%d Sig%d\n", gSegSignalRcvd, gSignalRcvd);
if(gSignalRcvd)
{
if(gSegSignalRcvd)
{
printf("Received Signal Inside Child1 ---------------\n");
kill(lCid1, SIGTERM);
kill(lCid2, SIGTERM);
kill(getpid(), SIGTERM);
}
}
gSignalRcvd = 0;

printf("Printing the Child1 Value\n");
usleep(rand());
}
}
return 0;
}

----------- Program OutPut ---------
[scuser@Bilx-Congo-Lab ~]$ ./sigHandle
Received Signal @ Child1 Seg:0 Sig0
Printing the Child1 Value
Received Signal @ Child2 Seg:0 Sig0
Printing the Child2 Value
Number:Reecived Signal:0 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1
Reecived Signal :11
Reecived Signal:1 SegSignal:1

最佳答案

将所有进程放在它们自己的进程组中,然后在任何成员获得 SEGV 时向整个组发送一个 SIGTERM。

在父级中,在任何 fork 之前:

pid_t gPGid;
volatile sig_atomic_t gSegSignalRcvd = 0;

... main() ...
setpgid(0, 0); // Make new process group, if needed
gPGid = getpgid(0);

然后,在处理程序中,向整个进程组发送信号:

void handler(int sig) {
if (sig == SIGSEGV) {
kill(-gPGid, SIGTERM); // Note the -gPGid here
_exit(1); // We segfaulted - we'd better quit now
} else if (sig == SIGTERM) {
gSegSignalRcvd = 1;
}
...
}

在实践中,可能无法达到 _exit(),因为进程组的 SIGTERM 也会中断生成它的程序。

一些注意事项:不要使用 signal() 和在处理程序中重新安装处理程序的过时约定 — 使用 sigaction()反而。不要在处理程序中调用 printf()that's not safe .您的“标志” bool 值可能应该是 volatile sig_atomic_t类型。

关于c++ - 子级和父级 C 程序中的 SIGSEGV 处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18761789/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com