gpt4 book ai didi

c++ - 向 pthread 注入(inject)运行时异常有时会失败。如何解决?

转载 作者:行者123 更新时间:2023-11-30 03:11:00 25 4
gpt4 key购买 nike

我尝试使用信号将异常注入(inject)线程,但有时异常未被捕获。例如下面的代码:

void _sigthrow(int sig)
{
throw runtime_error(strsignal(sig));
}
struct sigaction sigthrow = {{&_sigthrow}};

void* thread1(void*)
{
sigaction(SIGINT,&sigthrow,NULL);
try
{
while(1) usleep(1);
}
catch(exception &e)
{
cerr << "Thread1 catched " << e.what() << endl;
}
};

void* thread2(void*)
{
sigaction(SIGINT,&sigthrow,NULL);
try
{
while(1);
}
catch(exception &e)
{
cerr << "Thread2 catched " << e.what() << endl; //never goes here
}
};

如果我尝试像这样执行:

int main()
{
pthread_t p1,p2;

pthread_create( &p1, NULL, &thread1, NULL );
pthread_create( &p2, NULL, &thread2, NULL );

sleep(1);

pthread_kill( p1, SIGINT);
pthread_kill( p2, SIGINT);

sleep(1);

return EXIT_SUCCESS;
}

我得到以下输出:

Thread1 catched Interrupt
terminate called after throwing an instance of 'std::runtime_error'
what(): Interrupt
Aborted

如何让第二个威胁捕获异常?关于注入(inject)异常有更好的主意吗?

最佳答案

G++ 假定异常只能从函数调用中抛出。如果您要违反此假设(例如,通过将它们从信号处理程序中抛出),您需要在构建程序时将 -fnon-call-exceptions 传递给 G++。

但是请注意,这会导致 G++:

 Generate code that allows trapping instructions to throw
exceptions. Note that this requires platform-specific runtime
support that does not exist everywhere. Moreover, it only allows
_trapping_ instructions to throw exceptions, i.e. memory
references or floating point instructions. It does not allow
exceptions to be thrown from arbitrary signal handlers such as
`SIGALRM'.

这意味着从一些随机代码中间抛出异常是不安全的。您只能排除 SIGSEGVSIGBUSSIGFPE,并且只有当您通过 -fnon-call-exceptions 并且它们是由于运行代码中的错误而触发的。这在线程 1 上起作用的唯一原因是,由于 usleep() 调用的存在,G++ 被迫假设它可能会抛出异常。对于线程 2,G++ 可以看到不存在陷阱指令,并消除 try-catch block 。

您可能会发现 pthread 取消支持更符合您的需要,或者只需在某处添加这样的测试:

if (*(volatile int *)terminate_flag) throw terminate_exception();

关于c++ - 向 pthread 注入(inject)运行时异常有时会失败。如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2696171/

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