gpt4 book ai didi

c++ - 如何用 pthread 捕获堆栈溢出?

转载 作者:可可西里 更新时间:2023-11-01 18:29:34 25 4
gpt4 key购买 nike

我有一个 C++ 应用程序,它有很多线程,其中大多数线程的堆栈大小为 32k。问题是有时我会遇到 stackoverflow,我想检测哪个线程导致了 stackoverflow 并将其写入日志文件,问题是我无法捕获它。

我阅读了有关 SIGSEGV 的内容,并且我能够仅在没有线程的情况下捕获此信号。我还尝试使用 pthread_sigmask() 并使用 libsigsegv但我也失败了。

谁能给我一个关于在线程中发生堆栈溢出时捕获 SIGSEGV 的小示例?

最佳答案

在大多数情况下,为多线程应用程序捕获堆栈溢出与为单线程应用程序捕获堆栈溢出没有任何不同。它可能不同的主要方式是你是否大量溢出;对于主线程;在大多数情况下,这仍然会给您留下无效的堆栈指针和 SIGSEGV,但是对于小线程堆栈,溢出可能会将您的堆栈指针放在另一个线程堆栈的中间,在这种情况下非常糟糕将会发生,并且没有前进的希望。如果您使用小堆栈,您应该检查的另一个问题是您没有禁用保护页面。使用 pthread_attr_setstack(顺便说一下,这个函数已被弃用)不会给你保护页面,除非你已经自己设置了它们。使用 pthread_attr_setstacksize(正确的现代接口(interface))不应干扰保护页分配,但如果您认为溢出是通过很大的差距。

话虽如此,处理堆栈溢出的一般过程是为 SIGSEGV 设置一个处理程序并将其设置为在备用堆栈上运行。最后一点很关键!由于堆栈指针在信号生成时无效,因此需要有一个备用堆栈供信号处理程序本身运行。虽然表示给定信号是否在备用堆栈上处理的标志 是每个信号的属性(由 sigaction 设置),但实际的备用堆栈是每个线程的属性. 每个线程都必须使用 sigaltstack 设置自己的备用堆栈。备用堆栈的空间可以通过 mallocmmap 分配,但最简单的方法是创建一个自动 char 数组线程启动函数中的大小约为 2-4k,并将其用于备用堆栈。基本上,这相当于在线程堆栈的底部保留一个小范围,用作堆栈顶部溢出后信号处理程序的紧急堆栈空间。

关于c++ - 如何用 pthread 捕获堆栈溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14508382/

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