如何使用 pthread 捕获堆栈溢出
How to trap stack overflow with pthread?
我有一个C++应用程序,它有很多线程,其中大多数都有 32k 的堆栈大小。问题是有时我得到一个堆栈溢出,我想检测哪个线程导致了堆栈溢出并将其写入日志文件,问题是我无法捕获它。
我阅读了有关SIGSEGV
的信息,并且只能在没有线程的情况下捕获此信号。我也尝试使用pthread_sigmask()
和使用libsigsegv,但我也失败了。
谁能给我看一个关于在线程中发生堆栈溢出时捕获SIGSEGV
的小例子?
在大多数情况下,多线程应用程序的捕获堆栈溢出与单线程应用程序捕获堆栈溢出没有任何不同。它可能有所不同的主要方式是,如果您溢出了很大的利润;对于主线程;在大多数情况下,这仍然会给你留下一个无效的堆栈指针和SIGSEGV
,但对于小线程堆栈,溢出可能会将堆栈指针放在另一个线程堆栈的中间,在这种情况下,会发生非常糟糕的事情,并且没有向前推进的希望。如果您使用的是小堆栈,您应该检查的另一个问题是您没有禁用保护页面。使用pthread_attr_setstack
(顺便说一下,此功能已弃用)不会为您提供保护页面,除非您已经自己设置了它们。使用 pthread_attr_setstacksize
(正确的现代界面)不应干扰保护页分配,但如果您认为溢出幅度很大,则可能需要增加保护大小(使用 pthread_attr_setguardsize
)。
话虽如此,处理堆栈溢出的一般过程是为SIGSEGV
设置处理程序并将其设置为在备用堆栈上运行。最后一点至关重要!由于堆栈指针在生成信号时无效,因此需要有一个备用堆栈供信号处理程序本身运行。虽然是否在备用堆栈上处理给定信号的标志是每个信号属性(由 sigaction
设置),但实际的备用堆栈是每个线程属性。每个线程都必须使用 sigaltstack
设置自己的备用堆栈。备用堆栈的空间可以通过 malloc
或 mmap
来分配,但最简单的方法是在线程启动函数中创建一个大小约为 2-4k 的自动char
数组,并将其用于备用堆栈。基本上,这相当于在线程堆栈的底部保留一个小范围,以便在堆栈顶部溢出后用作信号处理程序的紧急堆栈空间。
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- C++ 对象数组堆栈溢出
- 有没有一种方法可以捕获进程中的堆栈溢出?C++Linux
- 对象接收堆栈溢出异常 c++ 的排序向量
- 将公共递归转换为尾递归,因为大型输入的堆栈溢出
- C++ 中递归期间的堆栈溢出
- 启动 dll 时 C# 环境堆栈溢出
- 在C++中使用数组时如何防止堆栈溢出?
- 如何修复递归函数导致的堆栈溢出错误?C++
- 当我尝试为结构分配新指针时出现堆栈溢出错误
- 为什么析构函数无休止地调用自己(导致堆栈溢出)?
- 为什么堆栈溢出?如有建议,不胜感激
- 主函数执行时C++堆栈溢出异常
- 如何在不导致堆栈溢出的情况下计算非常大的数字和很小的 HCF.我正在使用欧几里得算法
- 我正在尝试使用回溯来解决 N queen 问题,但在编译时它会给出运行时错误(动态堆栈缓冲区溢出)
- 如何在Windows上报告堆栈缓冲区溢出
- 如何抑制来自 gcc 中地址清理器的堆栈缓冲区溢出
- 声明大数组时堆栈/堆溢出
- c++中栈溢出和分段错误的危险