加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 崩溃后如何制作“不可能”的堆栈跟踪?

发布时间:2020-12-16 07:04:09 所属栏目:百科 来源:网络整理
导读:我的程序似乎正在遭受一个非常难以重现的错误:一旦进入了一个蓝色的月亮,当用户让他的Mac进入睡眠状态,然后再将其唤醒时,我的程序中的一个子进程将立即崩溃. Mac醒了. 当发生这种情况时,Apple的崩溃报告机制可靠地报告像这样的堆栈跟踪: Thread 0 Crashed:
我的程序似乎正在遭受一个非常难以重现的错误:一旦进入了一个蓝色的月亮,当用户让他的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进程生成的子进程,值得的.

解决方法

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

除了任何其他数据,我会非常保守地猜测你的程序期望某些指针保持有效,从睡眠状态唤醒时无效.查看该地址指令的反汇编.我打赌一个内存地址正在尝试被读取.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读