Hol*_*dad 7 c c++ multithreading signals pthreads
我有一个C++应用程序,它有很多线程,大多数都是32k的堆栈大小.问题是,有时我得到一个stackoverflow,我想检测哪个线程导致stackoverflow并将其写入日志文件,问题是我无法捕获它.
我读到了这个SIGSEGV,我只能在没有线程的情况下捕获这个信号.我也试过使用pthread_sigmask()和使用libsigsegv,但我也失败了.
任何人都可以向我展示一个关于SIGSEGV在线程中发生堆栈溢出时捕获的小例子吗?
对于多线程应用程序而言,陷阱堆栈溢出在很大程度上与单线程应用程序没有任何不同.它可能有所不同的主要方式是你是否有大幅度的溢出; 为主线程; 这仍然会给你一个无效的堆栈指针,SIGSEGV在大多数情况下,但是对于小的线程堆栈,溢出可能会将你的堆栈指针放在另一个线程堆栈的中间,在这种情况下会发生非常糟糕的事情并且没有前进的希望进展.如果你使用小堆栈,你应该检查的另一个问题是你没有禁用防护页面.使用pthread_attr_setstack(顺便推荐使用此功能)除非您已自行设置,否则不会为您提供保护页面.使用pthread_attr_setstacksize(适当的现代界面)不应该干扰保护页面分配,但pthread_attr_setguardsize如果你认为你的溢出很大,你可能想要增加保护大小(with ).
话虽如此,处理堆栈溢出的一般过程是设置处理程序SIGSEGV并将其设置为在备用堆栈上运行.最后一点非常关键!由于堆栈指针在生成信号时无效,因此需要有一个备用堆栈,供信号处理程序自身运行.虽然在备用堆栈上处理给定信号的标志是每信号属性(设置为sigaction),但实际的备用堆栈是每线程属性.每个线程必须设定自己的备用堆栈使用sigaltstack.备用堆栈的空间可以通过malloc或分配mmap,但最简单的方法是char在线程启动函数中创建一个大小约为2-4k 的自动数组,并将其用于备用堆栈.基本上,这相当于在线程堆栈底部保留一个小范围,以便在堆栈顶部溢出后用作信号处理程序的紧急堆栈空间.
| 归档时间: |
|
| 查看次数: |
1847 次 |
| 最近记录: |