【发布时间】:2013-08-01 13:59:44
【问题描述】:
我正在将一个已经在 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;
非常欢迎任何想法在这里可能发生的事情。稍后我会尝试将函数拆分为更小的部分,看看是否有帮助(如果是堆栈问题,可能会有所帮助)。
【问题讨论】:
-
"...如果我删除几行代码,它只会向下移动一点。" 你想说“...向上一点。 ”你不会吗?
-
loudness_on和en是线程局部变量还是全局变量?后者是您保护它们免受并发访问吗? -
我不太明白:“从该行中删除 Loudness_on 或 en 会阻止错误发生。”所以它停止发生了,很好。但是等等,它没有“(它向下移动几行,远低于 en2 超出范围的点)。”向下移动的是什么?发生错误的行?
-
抱歉不清楚。这两个变量都是函数的局部变量——这就是它如此奇怪的原因。我可以在调试器中毫无问题地查看它们的值。
-
我的意思是代码仍然在函数中进一步崩溃了几行。