我正在将已经在Windows和Linux中运行的程序移植到MacOS(Lion),我遇到了一个非常奇怪的问题。
我有一个非常长的函数(大约3000行C ++代码),如果我直接从我的主线程调用它,它运行正常。
但是,如果我创建一个单独的pthread并从那里调用相同的函数,我会崩溃。即使主线程没有做任何事情(睡眠)。崩溃总是发生在完全相同的地方(所以这不是时间问题),大约2000行进入这个功能;如果我删除几行代码,它只会向下移动一点。
使用gcc 4.2,在调试模式下会发生错误,如果我启用了一些优化,则会消失(但是再次出现-O3)。对于gcc 4.9,如果我启用-O2或-O3,它只会在释放模式下发生。所以,我现在试图弄清楚gcc 4.2会发生什么(因为我可以在调试模式下重现它)。
让事情更奇怪:我有2个布尔值(loudness_on和en),崩溃发生在以下行:
bool en2 = loudness_on && en;
从此行中删除loudness_on或en可阻止错误发生。 (它向下移动几行,远低于en2超出范围的点。)
我运行了valgrind并且它没有报告任何错误。
我怀疑是堆栈问题(也许线程有一个较小的堆栈?)但gdb会报告一些似乎与堆栈无关的东西:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000109588ec7
[Switching to process 12928 thread 0x4203]
0x00000001002e4809 in ParSet::refresh_parameters () at /Users/User/BUILD/Param.cpp: 3017
3017 bool en2 = loudness_on && en;
任何想到这里可能发生的事情都会非常受欢迎。我稍后会尝试将函数拆分成更小的部分,看看是否有帮助(如果它是堆栈问题可能会发生)。
答案 0 :(得分:1)
我找到了解决方案:如果我用更大的堆栈创建pthread,它就不会再崩溃了。我必须说gdb警告非常不清楚,似乎根本没有指出堆栈空间不足(调试器应该能够检测到这一点吗?)
无论如何,这段代码解决了它:
size_t stacksize = 0;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &stacksize);
pthread_attr_setstacksize(&attr, max(stacksize, 1024 * (1024 + 512));
pthread_t wxmt;
pthread_create(&wxmt, &attr, mainThread, NULL);
事实证明,Mac上pthreads的默认堆栈大小仅为512 kB(在Linux上为8 MB!) - 此代码将其增加到1.5 MB(1可能已经足够,但由于发生的错误真的很奇怪,我想避免将来再做一次搜索,我会多给它一点。)