一个解了两次的bug

一个解了两次的bug

发了一版软件,其中问题多多,没折,一个个解决,本来解个bug算什么事的,不过这个比较特殊,还解了两次才彻底解决,原因当然是自己功力不行。

第一次解的时候,是直接从上面丢下来的,我又刚接手这活,豪无话语权,也不太熟悉这些代码,所以他们说是什么就是什么(本来是要那些芯片商的技术支持来解的,他们说这个问题好解,可以借这次机会锻炼一下我上司,结果是任务到我身上了),就这样,开始分析了。

首先根据反馈,上司也觉得这是一个系统的bug,与上层没有什么关系,所以问题的定位就在系统部分了,(如果不是系统的,还轮不到我来解),方向定了,所以我就开干了。当然解系统bug,最好用的方法就是printf一些调试信息,抓这些log,然后分析log了,我也是这么干的。抓了log,分析log:SecureCRT 这个工具还算好用,我后面喜欢这个命令就是logcat -c; logcat -s xxxxx。通过分析log后,找到了一个从数据库中读的值不对,导致每次切个信源,状态就乱了。我当时很是想不明白,怎么回事,不就是读个数据库吗,为什么只有这么一处不对,其它地方又是正确的,所以排除不是读从数据库的数据接口有问题。时间比较赶,这样分析了几天,压力也是大大的,无意中,我不能直接解决问题,我就想回避问题了,我冷不丁的注释了这段代码,结果测试一下,好了。又催着要发新软件版本,上司测试了一下,我也解释了一下注释这代码不会引入新问题(现在想想,我当时是瞎扯蛋,无知啊),就这样,软件发布出去了,还要SQA测试,后面居然没测试出问题来,(这之后引入了另外一个大bug,导致了第2次来解)


后面软件派生,重新发了一版软件,SQA终于测试出那次引入的BUG了。这次对代码感觉不再陌生了,加打印,分析log,并且能针对性的对这块产生问题的部分重点观注,分析log后,死死的锁定了问题产生的原因,就是在切信源时,会对该信源进行初始化,会从一个数据库中读取数据来初始化状态,但读出来的数据不对。其实第一次解的时候,也有意识到这个,但是那时不是太确定, 原因是当时对代码不太熟悉,初次自己分析这种复杂代码来解决系统bug。锁定问题后,所有涉及的代码都开始怀疑了,到处加log,终于在读取数据库的接口中发现了问题的原因。原来切信源时,读数据库的接口,不会真正的去读数据库中的值,而是读的保存在内存中的拷贝。进一 步分析代码,发现读数据库接口有一个dirty标志位,如果上层改变了数据库中的值,而没有设置数据库dirty标志,那么底层不会重新load数据库的值, 从而不会刷新在内存中保存的值。经过确认java应用层在设置数据库中的值时,的确没有设置该标志位,更改后,问题彻底解决,切信源的状态正常了。以前改过的代码全都倒回去,引入的bug也解决了。至此解决了这个bug。

初次解决这种bug,从本来认为是系统的原因,到最终得出引起问题的是应用层,这个过程,对我来说,虽然不是那么容易,但最终解决了bug,还是给自己一个赞。当然最高兴的是,我对这些代码有了新认识,感觉看这些代码有感觉了,第二次解决这个bug时,人都比较兴奋,本想贴点代码上来,怕出问题,还是不弄了。

学到几个点:
1、上层改了数据库,要设置dirty标志,通知底层的重新load数据库。底层有一个线程,用来监控数据库,如果有dirty标志被设置,那么,会重新load数据库到内存,否则不会同步数据库中的更新;

2、在代码中加入合适的打印调试语句有时更有利于分析bug;

3、不要想当然的认为有些代码不会出错,往往忽视的地方,就是问题产生的地方;

其它的话,无非就是对代码的理解有所提升。本文到些




转:
如何调试分析Android中发生的tombstone

Android中较容易出现以下三类问题:Force close / ANR / Tombstone

前两者主要是查看当前的进程或者系统框架层的状态和堆栈就基本可以分析出来,本文主要讨论一下tombstone的情况。

tombstone一般是由Dalvik错误、状态监视调试器、C层代码以及libc的一些问题导致的。

当系统发生tombstone的时候,kernel首先会上报一个严重的警告信号(signal),上层接收到之后,进程的调试工具会把进程中当时的调用栈现场保存起来,并在系统创建了data/tombstones目录后把异常时的进程信息写在此目录里面,开发者需要通过调用栈来分析整个调用流程来找出出问题的点。

基本工具:

prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin

在分析的时候仔细读取汇编会获得更多有用的异常发生时的信息。

1.arm-eabi-addr2line 将类似libxxx.so 0x00012345的调用栈16进制值翻译成文件名和函数名

  arm-eabi-addr2line -e libxxx.so 0x00012345

2.arm-eabi-nm 列出文件的符号信息

  arm-eabi-nm -l -C -n -S libdvm.so > dvm.data

3.arm-eabi-objdump 列出文件的详细信息

  arm-eabi-objdump -C -d libc.so > libc.s

通过以上工具的分析 ,我们可以得到较完整的调用栈以及调用逻辑的汇编码。

然后需要结合ARM架构及ARM汇编的知识(有些情况下可能需要使用gdb)

来分析出现tombstone的原因,以下是本人遇到过的一些tombstone的情况:

1.无效的函数指针:指针为NULL或者已经被重新赋值

2.strlen崩溃:导致不完全的栈信息,栈被破坏

3.FILE操作:因为stdio并非线程安全的,多线程操作时,容易出现异常。

    本文涉及到的tombstone处理的主要逻辑所在文件如下:
    BootReceiver.java -- frameworks\base\services\java\com\android\server
    Debuggerd.c -- system\core\debuggerd
    ThreadLocal.java -- libcore\luni\src\main\java\java\lang

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值