如何利用 release 版本的 backtrace 来定位 android NDK 程序的崩溃位置

我们知道 android NDK 程序在崩溃时会生成一个 tombstone 的 backtrace (也可利用 ADB logcat 抓取),从这个 backtrace 中我们可以了解是哪个函数引发的崩溃,但是通常由于我们发布时都是 release 版,无法利用 backtrace 中的地址信息直接定位到源码和行号,当引发崩溃的错误不是很明显时,对于我们解决问题的帮助就不大。

这时通常我们是重编一个 debug 版本并设法重现 crash。这样做有个两个问题,一是如果我们不知道复现步骤,或者复现概率很低时,效率不高;二是我们不一定总能满足 crash 产生的条件,而一旦版本发布后,使用 debug 版本去替换用户场景中的 release 版又非常麻烦(甚至可能无法实现)。

事实上,有一个办法可以解决这个问题。我们知道,release 版本的库文件也是有 DYNAMIC SYMBOL TABLE 的,你可以使用命令 objdump -T -R <your so> (并重定向到一个文本文件中)来查看,然后你可以用同样的命令去查看 debug 版本的 DYNAMIC SYMBOL TABLE,通过比较,不难发现,他们的格式是一样的,你需要关注的只是第一列(symbol address)和最后一列(symbol name)。

接下来,你在 debug 版本的 DYNAMIC SYMBOL TABLE 中搜索引发崩溃的函数名,并记下它的 symbol address,然后,你只需要在这个地址上增加一个偏移量,就可以使用 addr2line 命令来定位源码和行号了。这个偏移量是多少?请注意 backtrace 中 #00  pc 的最后一列(使用括号括住),其中在函数名的后面有一个+N,这个N就是崩溃位置的偏移量(注意它是10进制数,而 symbol address 是16进制数,你需要先做转换才能相加)。

需要说明的是,由于 release 版通常都经过了优化,backtrace 中的偏移量并不一定非常准确,但离实际值差得不会太远,你可以使用 debug 版做一个对比测试就可以验证。现在你可以去试试这个方法了,希望这个方法能帮助你提高解决 crash 问题的效率。

如何利用 release 版本的 backtrace 来定位 android NDK 程序的崩溃位置,布布扣,bubuko.com

时间: 2025-01-19 23:20:08

如何利用 release 版本的 backtrace 来定位 android NDK 程序的崩溃位置的相关文章

如何定位Android NDK开发中遇到的错误

做android应用的调试,最怕就是报错,crash,看到这篇好文章,记录一下: 转自:http://www.csdn.net/article/2014-12-30/2823366-Locate-Android-NDK Android NDK是什么? Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”.众所周知,Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代

如何定位Release 版本中程序崩溃的位置 ---利用map文件 拦截windows崩溃函数

1       案例描述 作为Windows程序员,平时最担心见到的事情可能就是程序发生了崩溃(异常),这时Windows会提示该程序执行了非法操作,即将关闭.请与您的供应商联系.呵呵,这句微软的“名言”,恐怕是程序员最怕见也最常见的东西了. 在一个大型软件的测试过程中,初期出现程序崩溃似乎成了不可避免的事.其实测试中出现程序崩溃并不可怕,反而是测试的成功.作为开发的我们更需要关心的是程序中的哪个函数或哪一行导致了系统崩溃,这样才能有针对性的进行改正. 本文描述了自己总结的几种定位崩溃的办法.

【转】Debug 运行正常,Release版本不能正常运行

http://blog.csdn.net/ruifangcui7758/archive/2010/10/18/5948611.aspx引言 如果在您的开发过程中遇到了常见的错误,或许您的Release版本不能正常运行而Debug版本运行无误,那么我推荐您阅读本文:因为并非如您想象的那样,Release版本可以保证您的应用程序可以象Debug版本一样运行. 如果您在开发阶段完成之后或者在开发进行一段时间之内从来没有进行过Release版本测试,然而当您测试的时候却发现问题,那么请看我们的调试规则1

Debug与Release版本的区别详解

原文链接 Debug 和 Release 并没有本质的区别,他们只是VC预定义提供的两组编译选项的集合,编译器只是按照预定的选项行动.如果我们愿意,我们完全可以把Debug和Release的行为完全颠倒过来.当然也可以提供其他的模式,例如自己定义一组编译选项,然后命名为MY_ABC等.习惯上,我们仍然更愿意使用VC已经定义好的名称.     Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M).至于是否需要DLL支持,主要看你采用的编译选项.如果是基于ATL的,则D

VS中 Debug和Release版本的区别

VS Debug和Release版本的区别 1. 变量.大家都知道,debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc(注1),而release的赋值近似于随机(我想是直接从内存中分配的,没有初始化过).这样就明确了,如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常:用作控制变量将导致流程导向不一致:用作数组下标将会使程序崩溃:更加可能是造成其他变量的不准确而引起其他的错误.所以在声明变量后马上对其初始化一个默认的值是最简单有效的办法

利用.dSYM跟.app文件准确定位Crash位置

本文转载至  http://blog.csdn.net/lvxiangan/article/details/28102629 利用.dSYM和.app文件准确定位Crash位置首先,确保在release(Ad Hoc或者App Store)一个版本时,保存了对应的xxx.app和xxx.dSYM文件. 其次,验证xxx.crash.xxx.app和xxx.dSYM三者的uuid是否一致. 验证方法: 1)查看xxx.app的uuid. [plain] view plaincopy $ dwarf

Debug与Release版本的区别

Debug 和 Release 并没有本质的区别,他们只是VC预定义提供的两组编译选项的集合,编译器只是按照预定的选项行动.如果我们愿意,我们完全可以把Debug和Release的行为完全颠倒过来.当然也可以提供其他的模式,例如自己定义一组编译选项,然后命名为MY_ABC等.习惯上,我们仍然更愿意使用VC已经定义好的名称. Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M).至于是否需要DLL支持,主要看你采用的编译选项.如果是基于 ATL的,则Debug和Rel

Debug与Release版本区别

Debug与Release版本区别 Debug版本就是调试版本,Visual C++ 6.0默认的就是Debug版本.在Debug版本中,可以使用单步执行.跟踪等功能,但其生成的可执行文件比较大,代码运行比较慢.Release版本就是发行版本,其运行速度较快,可执行文件较小,但在其编译条件下无法执行调试功能.     还有一点,Release版本的exe文件链接的目标是标准的MFC DLL(Use MFC in a shared or static dll).比如MFC42.DLL.这些DLL在

VC下Debug 和 Release 版本区别

Debug 和 Release 并没有本质的区别,他们只是VC预定义提供的两组编译选项的集合,编译器只是按照预定的选项行动.如果我们愿意,我们完全可以把Debug和Release的行为完全颠倒过来.当然也可以提供其他的模式,例如自己定义一组编译选项,然后命名为MY_ABC等.习惯上,我们仍然更愿意使用VC已经定义好的名称.     Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M).至于是否需要DLL支持,主要看你采用的编译选项.如果是基于 ATL的,则Debug