我的程序似乎正在遭受一个非常难以重现的错误:一旦进入了一个蓝色的月亮,当用户让他的Mac进入睡眠状态,之后再次将其唤醒时,我程序中的一个子进程将崩溃在Mac醒来之后立即。
当发生这种情况时,Apple的崩溃报告机制可靠地报告像这样的堆栈跟踪:
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
! (我把我所有的源代码都用了两次来确保)
所以我的问题是,这个堆栈跟踪试图告诉我什么?这很可能是一个线程0的堆栈被严重破坏的情况,以至于堆栈跟踪机制已经脱离轨道并指责一个无辜的旁观者作为罪魁祸首?或者Apple的唤醒机制是否有可能以某种方式将程序计数器“跳”到ParsePortArg()中(由此导致的混乱导致崩溃)?还是还有一些其他更深层次的魔法,我甚至无法想象?
有问题的崩溃过程是一个vanilla非GUI后台进程,它是一个由Qt GUI进程产生的子进程,值得的。
答案 0 :(得分:1)
我假设你已经开启了一些优化。叠加痕迹没有魔力。一旦代码被内联或省略,它们就变得越来越模糊(读作“不太准确”),这正是C ++优化器所做的。
在ParsePortArg
的情况下,在该行的末尾有一个+80,这意味着在代码段中该函数的入口点之前80个字节。这表示0x001442d0
处指令指针的真实地址,而ParsePortArg
是堆栈转储猜测的最近符号。你认为这是一只红鲱鱼是对的。
除了任何其他数据,我会非常谨慎地猜测你的程序期望某些指针保持有效,从睡眠状态唤醒时无效。查看该地址指令的反汇编。我打赌一个内存地址正在尝试被读取。