工作线程中堆栈溢出时的信息性退出
Informative exit on stack overflow in worker thread
我正在编写一个C++程序,该程序将在递归数据上运行一堆工作线程,这样,即使我增加了默认的堆栈空间,线程也可能遇到堆栈溢出。
理想的情况是根据需要动态扩展堆栈,但如果这不可能,则可以接受程序失败,用户在用更大的堆栈大小重新编译后重试。
程序在没有错误消息的情况下崩溃的默认行为的问题是,用户无法知道问题是什么,也无法知道该怎么办;据用户所知,该程序可能试图除以零或取消引用空指针;因此,如果程序必须崩溃,我希望它首先将"堆栈溢出"打印到stderr。
很明显,在可移植C++中不会有解决方案,但我会很高兴有一个在Windows上工作的解决方案,另一个在Linux上工作。
在Windows上,我一直在阅读有关矢量化和结构化异常处理的文档,寻找让程序退出并显示信息性错误消息的方法;一个问题是,这些似乎是线程本地的,线程无法安全地写入stderr;充其量你会得到一个比赛条件。
有已知的处理方法吗?
操作系统(至少是Linux或Unix版本)允许您捕获堆栈错误。
类似这样的东西:
// Note: Calling printf here is probably not a brilliant idea,
// as we're in a signal handler. It is NOT well-defined what happens.
void handler(int arg)
{
fprintf(stderr, "Crashed due to signal handlern");
exit(42);
}
然后主要是这样的。。。
struct sigaction sa = { handler, NULL, 0, 0, NULL };
struct sigaction oldsa;
sigaction(SIGSTKFLT, sa, oldsa);
我将尝试提出一个更"完整"的解决方案,并在一点时间内进行一些实验。
(我相信更换堆栈是可能的,但我不认为你可以以一种有意义的方式,在那一点上继续,只是让你以一种比简单崩溃更理智的方式恢复!)
这似乎奏效了:
#include <signal.h>
#include <unistd.h>
#include <iostream>
#include <cstdlib>
void handler(int arg)
{
write(2, "stack overflown", 15);
_exit(42);
}
void* duh(void *arg)
{
if(duh(arg))
{
return duh(NULL);
}
else
{
return duh(arg);
}
}
void* crash_wrapper(void *arg)
{
static char stack[SIGSTKSZ];
stack_t ss = {};
ss.ss_sp = stack;
ss.ss_size = SIGSTKSZ;
sigaltstack(&ss, 0);
struct sigaction sa = {};
sa.sa_handler = handler;
sa.sa_flags = SA_ONSTACK,
sigfillset(&sa.sa_mask);
sigaction(SIGSEGV, &sa, 0);
return duh(arg);
}
int main()
{
pthread_t t;
int status = pthread_create(&t, 0, crash_wrapper, 0 );
for(;;)
{
std::cout << "Still going..." << std::endl;
sleep(1);
}
}
我对处理程序中的write
并不完全满意,但我尝试的所有其他方法似乎也不起作用…:(
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 创建LinkedList退出,返回代码为-11(SIGSEGV)
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 如何让LLDB在成功时退出,在失败时等待
- C++控制台应用程序阻止退出
- 程序在执行程序的其余部分之前退出
- 构造函数在退出函数时无法初始化一个参数
- 为什么异常不退出程序?
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- 退出简单while循环时出现问题
- 使用vscode调试时,GDB意外退出
- pclose() 不会给我进程退出代码
- 为什么系统函数总是在C++中返回已转移的退出状态?
- C++从另一个函数退出函数
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- C++逗号分隔的输入数组代码过早退出
- Netbeans 10:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- 为什么 C++ 中的以下结构声明会导致退出 127?
- 编译问题:在函数"_start"中:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 工作线程中堆栈溢出时的信息性退出