委婉地说,我有一个小的内存问题,并且正在用完工具和想法来隔离原因。
我有一个高度多线程(pthreads)的 C/C++ 程序,它在 4.4.4 之后和 4.7.1 之前的 GCC 优化编译下开发了堆栈粉碎问题。
症状是在创建其中一个线程期间,我得到了一个完整的堆栈粉碎,不仅仅是 %RIP,而且所有父帧和大多数寄存器都是 0x00 或其他无意义的地址。哪个线程导致问题似乎是随机的,但是从日志消息来看,它似乎与同一块代码隔离,并且似乎在创建新线程时出现了半可重复的点。
这使得捕获和隔离有问题的代码变得非常困难,而不是一个可能数千行的编译单元,因为到目前为止,在有问题的文件中的 print() 在试图缩小活动部分时被证明是不可靠的.
导致最终破坏堆栈的线程的线程创建是:
extern "C"
{
static ThreadReturnVal ThreadAPI WriterThread(void *act)
{
Recorder *rec = reinterpret_cast (act);
xuint64 writebytes;
LoggerHandle m_logger = XXGetLogger("WriterThread");
if (SetThreadAffinity(rec->m_cpu_mask))
{ ... }
SetThreadPrio((xint32)rec->m_thread_priority);
while (true)
{
... poll a ring buffer ... Hard Spin 100% use on a single core, this is that sort of crazy code.
}
}
我尝试了调试版本,但症状仅存在于优化版本中,-O2 或更好。我已经尝试过 Valgrind/memcheck 和 DRD,但在堆栈被吹走之前都没有发现任何问题(大约需要 12 小时才能达到故障)
使用 -O2 -Wstack-protector 进行编译没有任何问题,但是使用 -fstack-protector-all 进行编译确实可以保护我免受错误的影响,但不会发出任何错误。
Electric-Fence 也有陷阱,但只有在堆栈消失之后。
问题:还有哪些其他工具或技术可用于缩小违规部分的范围?
非常感谢,--比尔