2013-04-26 85 views
4

我的程序似乎遭受了一个非常难以重现的错误:一旦进入蓝色月亮,当用户将他的Mac置于睡眠状态并稍后再次唤醒时,我的程序的一个子进程会立即崩溃Mac唤醒后。崩溃后“不可能”堆栈跟踪的内容是什么?

发生这种情况时苹果公司的崩溃报告机制可靠地报告一个堆栈跟踪像这样的:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 
0 libsystem_kernel.dylib   0x967f9a6a __pthread_kill + 10 
1 libsystem_c.dylib    0x9003dacf pthread_kill + 101 
2 libsystem_c.dylib    0x900744f8 abort + 168 
3 com.meyersound.VirtualD-Mitri 0x0014438e muscle::CrashSignalHandler(int) + 190 
4 libsystem_c.dylib    0x9002886b _sigtramp + 43 
5 ???        0xffffffff 0 + 4294967295 
6 com.meyersound.VirtualD-Mitri 0x001442d0 muscle::ParsePortArg(muscle::Message const&, muscle::String const&, unsigned short&, unsigned long) + 80 
7 com.meyersound.VirtualD-Mitri 0x005b3393 qnet::RepDBPeer::Pulse(muscle::PulseNode::PulseArgs const&) + 1187 
8 com.meyersound.VirtualD-Mitri 0x0015717b muscle::PulseNode::PulseAux(unsigned long long) + 203 
9 com.meyersound.VirtualD-Mitri 0x000cfb90 muscle::ReflectServer::ServerProcessLoop() + 3232 
10 com.meyersound.VirtualD-Mitri 0x00607c7e dcasldmain(int, char**) + 2222 
11 com.meyersound.VirtualD-Mitri 0x0072c14d dmitridmain(int, char**) + 4749 
12 com.meyersound.VirtualD-Mitri 0x0000bc3a main + 4938 
13 com.meyersound.VirtualD-Mitri 0x000061ab _start + 209 
14 com.meyersound.VirtualD-Mitri 0x000060d9 start + 41 

这是一切都很好,除了(提示怪异音乐) - 这是逻辑上是不可能。特别是,我的RepDBPeer::Pulse()方法不仅不会调用ParsePortArg,崩溃过程永远不会调用任何地方的ParsePortArg! (我grepped所有的源代码两次,以确保)

所以我的问题是,这是什么堆栈跟踪试图告诉我?这很可能是一个线程0的堆栈严重损坏的情况,堆栈跟踪机制已经离开轨道,并指出一个无辜的旁观者作为罪魁祸首?或者苹果的唤醒机制有可能将程序计数器“跳”到ParsePortArg()中(由此导致的混乱导致崩溃)?还是还有其他更深层的魔法在这里发生,我甚至无法想象?

有问题的崩溃过程是一个香草非GUI后台进程,它是由Qt GUI进程产生的子进程,值得一看。

+1

我想要考虑的情况下,可以调用一个命名的函数而不会看起来像。宏和函数指针立刻浮现在脑海中。该函数明显定义了,我们可以看到'ParsePortArg'的其他地方吗? – 2013-04-26 02:36:55

+0

也许很重要的优化。如果以某种方式在变量中传递此函数,grep将无济于事。 – Elazar 2013-04-26 02:39:15

+1

异常会在堆栈上推送非标准框架,并且展开代码不会始终识别它们。 – 2013-04-26 03:28:18

回答

1

我打算假设您已经开启了一些优化功能。没有魔术来堆叠痕迹。一旦代码被内联或省略,它们变得越来越模糊(读作“不太准确”),这正是C++优化器所做的。 对于ParsePortArg,该行末尾有+80,表示代码段中该函数入口点之前80个字节。这表示指令指针的真实地址为0x001442d0,而ParsePortArg是栈转储猜测的最接近的符号。你认为这是一只红鲱鱼是对的。

除非有其他数据,否则我会做出非常保守的猜测,即您的程序期望某些指针保持有效,该指针在从睡眠中唤醒时无效。查看该地址的指令反汇编。我敢打赌,一个内存地址正在尝试被读取。

+0

谢谢,这非常有帮助。在检查反汇编时(通过“otool -tv MyApp。app/Contents/MacOS/MyApp“我可以看到ParsePortArg()与可执行文件中的CrashSignalHandler()相邻,所以当它实际上是CrashSignalHandler()函数时,偏移量必须将堆栈跟踪生成器愚弄到打印ParsePortArg在堆栈上。 – 2013-04-30 17:41:42

相关问题