`
andyzhchy
  • 浏览: 96856 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

[转]Show Stopper 一次 crash 调试的夺命狂奔

 
阅读更多
这几天一直在忙着调试 crash 的问题。周末两天都在加班。 周日更是从早上8:00 到晚上 12:50 一直没离开过办公室. 加上这个项目对我们整个开发组以及 EM 都很重要,不容有失,这不禁让我想起了微软 NT 开发组开发 NT 的情形,所以有了这个标题.



这次是在 android 上,但不是 arm,而是 x86 atom。我们的程序是从 windows 上移植到 android 上的, 一个 C++ 写的底层库作为 service,UI 是 java 写的。 因为是在 android 2.2 上,java 也是唯一的写 UI 的选择。 java 通过 aidl/jni 与底层 service/c++ 代码交互。这样的架构让调试很悲剧。



之前一直抱怨 xcode 调试多么不给力,而现在在 android 上的调试已经原始到通过 log 分析程序的执行。arm 上的调试还能用 gdb 勉强为之,而 x86 下那简直就是坑爹。好不容易把符号神马的搞定,gdb 远程调试到设备上,却发现程序不 crash 了。



logcat 和 tombstone 显示的 crash 调用栈是这样的:

06370 INF/DEBUG   ( 1670): signal 11 (SIGSEGV), fault addr deadbaad
06371 INF/DEBUG   ( 1670):  eax 00000000  ebx 801614f4  ecx 00000004  edx 00001000
06372 INF/DEBUG   ( 1670):  esi b3afa000  edi bfca7b18
06373 INF/DEBUG   ( 1670):  xcs 00000073  xds 0000007b  xes 0000007b  xfs 00000000 xss 0000007b
06374 INF/DEBUG   ( 1670):  eip 8011c768  ebp bfca7b28  esp bfca7af0  flags 00010286
06375 INF/DEBUG   ( 1670): #00
06376 INF/DEBUG   ( 1670):     eip: 8011c768  /system/lib/libc.so (abort)
06377 INF/DEBUG   ( 1670): #01
06378 INF/DEBUG   ( 1670):     eip: 8010ed4b  /system/lib/libc.so (dlfree)
06379 INF/DEBUG   ( 1670): #02
06380 INF/DEBUG   ( 1670):     eip: 80111503  /system/lib/libc.so (free)
06381 INF/DEBUG   ( 1670): #03
06382 INF/DEBUG   ( 1670):     eip: 80200a1d  /system/lib/libstdc++.so (_ZdlPv)
06383 INF/DEBUG   ( 1670): #04
06384 INF/DEBUG   ( 1670):     eip: 86138519  /data/data/cip.impservice/lib/libimpjni2.so (_ZSt12__stl_deletePv)
06385 INF/DEBUG   ( 1670): #05
06386 INF/DEBUG   ( 1670):     eip: 8613853d  /data/data/cip.impservice/lib/libimpjni2.so (_ZNSt11__new_alloc10deallocateEPvj)
06387 INF/DEBUG   ( 1670): #06
06388 INF/DEBUG   ( 1670):     eip: 8613856e  /data/data/cip.impservice/lib/libimpjni2.so (_ZNSaIcE10deallocateEPcj)
06389 INF/DEBUG   ( 1670): #07
06390 INF/DEBUG   ( 1670):     eip: 861385b1  /data/data/cip.impservice/lib/libimpjni2.so (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06391 INF/DEBUG   ( 1670): stack:
06392 INF/DEBUG   ( 1670): #00
06393 INF/DEBUG   ( 1670):     bfca7af0  00000002   (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06394 INF/DEBUG   ( 1670):     bfca7af4  bfca7b18  [stack] (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06395 INF/DEBUG   ( 1670):     bfca7af8  00000000   (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06396 INF/DEBUG   ( 1670):     bfca7afc  00000000   (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06397 INF/DEBUG   ( 1670):     bfca7b00  00000000   (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06398 INF/DEBUG   ( 1670):     bfca7b04  00000000   (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06399 INF/DEBUG   ( 1670):     bfca7b08  84a60900  /system/lib/libstlport.so (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06400 INF/DEBUG   ( 1670):     bfca7b0c  00000010   (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06401 INF/DEBUG   ( 1670):     bfca7b10  0a1f8300  [heap] (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06402 INF/DEBUG   ( 1670):     bfca7b14  00000001   (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06403 INF/DEBUG   ( 1670):     bfca7b18  fffffbdf   (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06404 INF/DEBUG   ( 1670):     bfca7b1c  801614f4  /system/lib/libc.so (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06405 INF/DEBUG   ( 1670):     bfca7b20  0a1f6c98  [heap] (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06406 INF/DEBUG   ( 1670):     bfca7b24  bfca8410  [stack] (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06407 INF/DEBUG   ( 1670):     bfca7b28  bfca7b68  [stack] (_ZNSt4priv17_STLP_alloc_proxyIPccSaIcEE10deallocateES1_j)
06408 INF/DEBUG   ( 1670): #01
06409 INF/DEBUG   ( 1670):     bfca7b2c  8010ed4b  /system/lib/libc.so (dlfree)
06410 INF/DEBUG   ( 1670):     bfca7b30  80163118   (dlfree)
06411 INF/DEBUG   ( 1670):     bfca7b34  00000000   (dlfree)
06412 INF/DEBUG   ( 1670):     bfca7b38  8010f3ab  /system/lib/libc.so (dlmalloc)
06413 INF/DEBUG   ( 1670):     bfca7b3c  801614f4  /system/lib/libc.so (dlmalloc)
06414 INF/DEBUG   ( 1670):     bfca7b40  00000066   (dlmalloc)
06415 INF/DEBUG   ( 1670):     bfca7b44  bfca8410  [stack] (dlmalloc)
06416 INF/DEBUG   ( 1670):     bfca7b48  0a1f6c90  [heap] (dlmalloc)
06417 INF/DEBUG   ( 1670):     bfca7b4c  801114d2  /system/lib/libc.so (malloc)
06418 INF/DEBUG   ( 1670):     bfca7b50  0000002f   (malloc)
06419 INF/DEBUG   ( 1670):     bfca7b54  80201d98  /system/lib/libstdc++.so
06420 INF/DEBUG   ( 1670):     bfca7b58  bfca7b68  [stack]
06421 INF/DEBUG   ( 1670):     bfca7b5c  801614f4  /system/lib/libc.so
06422 INF/DEBUG   ( 1670):     bfca7b60  0a1f6caf  [heap]
06423 INF/DEBUG   ( 1670):     bfca7b64  bfca8410  [stack]
06424 INF/DEBUG   ( 1670):     bfca7b68  bfca7b78  [stack]
06425 INF/DEBUG   ( 1670):     ......  ......


每次都几乎看不到我们的代码,好不容易看到一个用户代码的地址,通过 addr2line, 也是 STL 里的 _alloc.h 之类。这其实是一个提示,但一开始我们并没有在意。我们还是坚忍的打着 log,试图逐一的排查 crash, 好不容易向前推进了一些让程序跑得更远一点,再跑一次却发现又回到了起点, crash 又在前面的代码中出现鸟,我勒个去~



不稳定的 crash 让我有些沮丧,同时也让我产生了怀疑,这到底是不是我们的代码的问题? 看看每次 crash 的调用栈,都有 STL 牵涉其中,又联想起我们用的 stlport 不是线程安全的 (编译时使用了 _NOTHREADS 宏),  是不是应该去掉 _NOTHREADS 编译试试? 但遇到的新问题是,我们使用的动态链接的系统自带的 STL,虽然可以替换掉系统的,但势必影响其他的程序。这是不能接受的。 马上想到我们可以编译一个静态库,连接到我们的程序中。说干就干,拿到 stlport 的代码,折腾一番,也就编译好了。这里还有一个小插曲, android 的头文件说它对 #include_next 支持的并不好,但最终我们还是用了 gcc 的这个 feature 才让代码编译通过。



但测试的结果却让人沮丧,我再次确认了的确是链接到了自己编译的静态版本,悲催的发现这次尝试可耻的失败鸟~ 这时已是周一凌晨 0:50 了,而我已经在办公室呆了 16个小时没有离开。



周一早上9:40到达公司。一计不成,又生一计,这次我注意到调用栈顶端的 lib 的 free 函数,既然每次都 crash 在这里,那我能不能让它不调用这个函数。联想起之前看过的 stlport 文档 (http://www.stlport.com/doc/configure.html),的确有一个宏  _STLP_USE_NEWALLOC 可以让 stlport 使用 new/delete 而不是 malloc/free 来分配/释放内存, 无独有偶,目前我们做的这个项目的前身(另一个项目组开发的)编译的时候就加了 stlport 的这个宏(我们在移植代码的时候由于匆忙,急于让代码通过编译,没能加上这个宏),这更坚定了我做这个尝试的决心。于是给十几个模块的 mk 文件都加上了这几个 stlport 相关的宏(看 stlport 文档关于分配内存的宏),rebuild all。 哈利露亚~ 幸福来得那么突然, 程序真的跑起来了,不再 crash!



总结这次调试的经验教训:

1. 开始时调试进展缓慢,问题出在编译/调试环境很不给力。

我们需要把代码放到另一个 site 的唯一的 build machine 上让同事帮忙编译,这个过程让调试过程变得很漫长。 所以我让同事给我在 build machine 上单独弄了一个环境,这样我就可以随意的修改/调试代码了

2. 对问题不敏感,虽然每次都看到 stl/free 出现在调用栈中,直到在错误的方向上迷失才意识到我们可能走错路了

3. 对项目本身不够了解,我没能意识到我们其实有一个能用的版本(虽然我们重构了很多),的确应该早些查看别人是怎么做到的。 这里有一个客观原因是我之前一直不在这个项目。

4. Android 的调试环境太坑爹了。既然符号神马的都齐活了,在调研栈里却只显示地址和莫名其妙的函数名(还是 decorated), 尼玛就不能把代码行也加进去啊!有木有!Android 开发小组在忙于追赶/超越苹果的时候,明显对开发者照顾不够。 当然,也有可能是我被微软给惯坏了.

注:本人转自http://nick.luckygarden.org/?p=454
分享到:
评论

相关推荐

    观止——微软创建NT和未来的夺命狂奔(中、英)PDF

    《观止——微软创建NT和未来的夺命狂奔》是一本深入探讨微软公司发展历史,尤其是NT操作系统创建过程的重要书籍。这本书以独特的视角揭示了微软如何在科技行业中崛起,以及NT系统如何奠定现代Windows操作系统的基础...

    观止--微软创建NT和未来的夺命狂奔Show Stopper The Breakneck Race To Create Windows Nt And The Next Generation At Microsoft.pdf

    观止--微软创建NT和未来的夺命狂奔ShowStopper The Breakneck Race To Create Windows Nt And The Next Generation At Microsoft.pdf 本书讲述的是微软创建Windows NT这个计算机技术领域惊人突破背后的故事。揭示了...

    Show Stopper

    微软创建NT和未来的夺命狂奔(英文版):观止这本书主要是讲述微软创建WindowsNT这个计算机技术领域惊人突破背后的故事,揭示了成功创新的艰难和痛苦。集中表现了卡特勒的反复无常、激励和鞭策团队的能力,色彩鲜明...

    观止-微软创建NT和未来的夺命狂奔

    《观止:微软创建NT和未来的夺命狂奔》是一本深入揭示微软公司发展历史的著作,特别是关于Windows NT操作系统研发过程的详细记述。书中的故事并不只是关于微软的成功,更是关于那些在幕后默默付出的关键人物,其中一...

    show stopper

    - **构建延迟的影响**:构建延迟会影响整个团队的工作进度,因为团队成员需要等待构建完成才能进行下一步的测试和调试工作。在Windows NT项目中,构建延迟导致团队无法按时完成预定的目标,从而增加了项目的压力。 ...

    《Show Stopper!: The Breakneck Race to Create Windows NT and the Next Generation at Microsoft by G. Pascal Zachary》

    《Show Stopper!: The Breakneck Race to Create Windows NT and the Next Generation at Microsoft by G. Pascal Zachary》是一本深入探讨Windows NT操作系统开发历程的著作。这本书由记者G. Pascal Zachary撰写,...

    SHOW STOPPER!

    《SHOW STOPPER!》这本书揭示了微软在创建Windows NT操作系统时所经历的激烈竞争与文化挑战。这本书由G. Pascal Zachary撰写,深入探讨了微软如何在极短的时间内开发出这款革命性的操作系统,以及这一过程中所遇到的...

    Show.Stopper.The.Breakneck.Race.To.Create.WindowsNt.And.The.Next.Generation.At.Microsoft

    《Show.Stopper:The Breakneck Race To Create Windows NT And The Next Generation At Microsoft》是一本深入探讨微软内部开发过程的经典著作,由G. Pascal Zachary撰写。本书不仅详细记录了Windows NT这一里程碑...

    (完整版)Show.Stopper.The.Breakneck.Race.To.Create.WindowsNt.And.The.Next.Generation.At.Microsoft.pdf

    完整E文版Show.Stopper.The.Breakneck.Race.To.Create.WindowsNt.And.The.Next.Generation.At.Microsoft.pdf

    state-stopper:任何状态解析值的自动停止器

    标题中的“state-stopper”是一个专门针对状态管理的工具,可能是用于JavaScript开发的库或框架。这个工具的主要功能是提供一种自动停止状态解析的机制,这意味着它能够帮助开发者有效地管理和控制应用程序中的状态...

    Image Stopper-crx插件

    为了解决这些问题,“Image Stopper-crx插件”应运而生,旨在为用户提供一种简单有效的方法来控制网页中的图像动画。这款由专业开发者精心设计的浏览器扩展程序,能够让用户在浏览网页时,通过右键点击图像,快速...

    矩子JutzeAOI程式误报调试.doc

    《矩子JutzeAOI程式误报调试详解》 自动光学检测(AOI,Automatic Optical Inspection)技术在现代电子制造中扮演着至关重要的角色,它能够有效地检测电路板上的各种缺陷,确保产品质量。然而,AOI设备在运行过程中...

    Rotary Cylinder SDR系列旋转气缸产品手册.pdf

    3. 组成部件:Rotary Cylinder SDR系列包括了各种组件,例如Stopper Pin(定位销)、Turn Table(旋转台)、Stopper Bearing(定位轴承)、Cover(盖板)、Ball Bearing(滚珠轴承)、Driving Gear(驱动齿轮)、...

    force-stopper-for-android:一种有助于强制停止不想让其在后台运行的应用程序的工具

    针对这一问题,"force-stopper-for-android"应运而生,它是一款专为Android系统设计的工具,旨在帮助用户强制停止那些不希望在后台运行的应用程序,以提升设备的性能和电池寿命。 首先,我们来理解一下"force-stop...

    破解软件时间限制

    破解软件时间限制工具 Time Stopper.exe 偷天换日2.0.exe

    vim-troll-stopper:阻止Unicode巨魔弄乱您的代码

    vim-troll-stopper 当心,那里有(Unicode)巨魔! 在这里,请使用此插件进行保护。 问题 有许多相同或看起来非常相似的Unicode字符。 最著名的示例:分号(;)和希腊问号(;)。 拖钓者(例如,您的同事)可以...

    WSBot Stopper-crx插件

    语言:English (United States) ...此扩展名在r / wallstreetbets中的用户名旁边添加了一个样式,以显示他们参与subreddit多久了。 使用此信息,您可以更好地选择用户是否值得信任,或者用户是否为垃圾邮件机器人。

    Web Stopper-crx插件

    该扩展程序可在阻止任何可能使您分心的网站的同时最大程度地提高生产力 只需将链接复制并粘贴到…中即可。 该扩展程序可在阻止任何可能使您分心的网站的同时最大程度地提高生产力。 只需将链接复制并粘贴到扩展程序...

Global site tag (gtag.js) - Google Analytics