1.Android NDK Tombstone/Crash 分析
2.linux内核调试之 crash分析dump文件
3.C++中Crash定位原理与常见案例反汇编分析
4.crash流程详解(完结撒花)
5.Linux内核调试:kdump、源码vmcore、源码crash、源码kernel-debuginfo
6.å¦ä½å®ä½å¯¼è´Crashç代ç ä½ç½®
Android NDK Tombstone/Crash 分析
程序员在调试Bug的源码过程中,访问非法内存是源码最让人头疼的问题。调试程序Bug通常有三种方法:那么如何调试引发Crash的源码直播源码怎么开NDK程序呢?
幸运的是,Google早已预见到我们编写的源码NDK代码可能存在缺陷。当NDK程序发生Crash时,源码会在/data/tombstones/路径下生成记录Crash信息的源码文件tombstone_xx。同时,源码Google在NDK包中也提供了一系列调试工具,源码如addr2line、源码objdump、源码ndk-stack。源码
在介绍Tombstone之前,源码我们先补充一下Linux信号机制的相关知识。信号机制是Linux进程间通信的一种重要方式,用于正常的进程间通信和同步,以及监控系统异常及中断。当应用程序运行异常时,Linux内核会产生错误信号并通知当前进程。当前进程在接收到该错误信号后,可以有三种不同的处理方式。
当Linux应用程序在执行时发生严重错误,一般会导致程序crash。Linux专门提供了一类crash信号,程序接收到此类信号时,缺省操作是将crash的现场信息记录到core文件,然后终止进程。
什么是Tombstone?Android Native程序本质上就是一个Linux程序,当它在执行时发生严重错误,也会导致程序crash,百变石器源码然后产生一个记录crash的现场信息的文件,在Android系统中就是tombstone文件。
Tombstone文件位于路径/data/tombstones/下,它记录了死亡进程的基本信息、死亡的地址以及死亡时的现场信息。
分析出现Crash的原因和代码位置最重要的就是分析这个tombstone文件。tombstone文件主要由以下几部分组成:Build fingerprint、Crashed process and PIDs、Terminated signal and fault address、CPU registers、Call stack、Stack content of each call。
Crashed process and PIDs信息表示Crash掉进程的基本信息,包括进程号、线程号等。Terminated signal and fault address信息表示程序因为什么信号导致了Crash以及出现错误的地址。Call Stack信息记录了程序在Crash前的函数调用关系以及当前正在执行函数的信息。
在分析tombstone文件时,我们主要关注Crashed process and PIDs、Terminated signal and fault address和Call stack部分。
addr2line是NDK中用来获得指定动态链接库文件或者可执行文件中指定地址对应的源代码信息的工具。ndk-stack能自动分析tombstone文件,将崩溃时的调用内存地址和C++代码一行一行对应起来。
总结来说,Android NDK程序的系统调试并不复杂,只要掌握了正确的方法,了解Tombstone文件中关键信息的含义,学会使用addr2line和ndk_stack这两个超级方便的工具,就可以快速定位到导致NDK程序Crash的Bug。但具体的Bug还需要进一步根据业务逻辑来分析代码。
linux内核调试之 crash分析dump文件
Linux 下有多个内存转储分析工具,公开网盘源码如 lcrash、Alicia、Crash。Crash 是一个由 Dave Anderson 开发并维护的内存转储分析工具,当前版本为5.0.0。在没有统一标准的内存转储文件格式的情况下,Crash 支持多种格式。
Crash 的命令格式如下:crash [OPTION]... NAMELIST MEMORY-IMAGE[@ADDRESS]其中,namelist 是用于调试版本内核的名称列表,通常需要自定义编译,或者从发行版网站下载包含内核的/usr/lib/debug/lib/modules/内核版本/vmlinux软件包。而memory-image是转存的某种格式的dump文件。
为了使用 Crash,需要安装相应的kernel-debuginfo和debug-info-common软件包,如 CentOS 8 下,可以从debuginfo.centos.org/8/...下载安装包。
使用 Crash 的命令提示符执行相关操作。Crash 内置命令用于查看寄存器值、调用堆栈等信息,这些命令与 gdb 相似。
例如,bt命令用于打印内核堆栈,可以列出所有内核堆栈或指定进程的堆栈。使用 bt + pid列出特定进程的堆栈,bt -f列出所有堆栈详细信息,bt -p仅打印崩溃线程的内核栈。
dmesg命令用于查看崩溃时的内核日志信息。
dis命令用于反汇编地址或函数,显示该地址对应的源码。例如,dis 时机指标源码大全-l显示特定行号的源码。
rd命令用于读取内存内容。
mod命令用于查看、加载模块的符号调试信息。需要加载包含符号信息的模块。
x/FMT命令用于查看内存内容,FMT参数包括大小、格式和长度。
sym命令用于将虚拟地址转换为符号。
ps命令用于打印内核崩溃时的进程信息。
file命令用于打印指定进程的文件打开列表。
Crash 还支持如 vm [pid]查看进程的虚拟地址空间,task [pid]查看进程的task_struct和thread_info信息,以及kmem -I查看内存使用情况。
Crash 可以用于实际测试,如主动触发崩溃情况分析和分析空指针产生的 core dump 文件。在实验中,内核版本为 4..0-..1.el8_2.x_,Crash 版本为 7.2.7-3.el8,且使用了 kexec-tool。
以上是 Crash 工具的主要功能和使用方法,通过这些命令,开发者可以深入分析内存转储文件,定位并解决潜在的内存错误。
C++中Crash定位原理与常见案例反汇编分析
在C++的世界里,程序崩溃的瞬间仿佛是一场神秘的迷宫,但通过理解其定位原理和实践案例,我们能逐渐揭开这个谜团。让我们一起探索Crash解析的奥秘,以及如何利用反汇编分析来揭示背后的真相。
首先,理解Crash定位的egret桌球游戏源码关键在于理解执行环境。寄存器、栈内存、堆内存的动态变化是分析的基础。定位函数则是通过计算代码偏移量和模块加载基址,同时,行号定位(在编译时启用-g选项的情况下)可以提供宝贵的线索。堆栈回溯是查找崩溃源头的重要手段,但可能由于地址破坏而失去效用。
面对Crash,直接从源代码出发是最直接的方法,结合行号和调用栈,寻找问题的根源。对于无行号或服务器版本的代码,反汇编工具如IDA和GDB则成为我们的得力助手。GDB的远程调试服务尤其适合在Linux服务器上进行问题排查。
在Windows、Linux、Android和iOS等不同平台上,由于二进制文件格式的差异,调试策略也会有所调整。例如,Windows可能使用PE文件,而Linux则使用ELF。编译时的-g选项能帮助我们追踪源代码行号,这对于定位问题至关重要。
深入到细节,我们关注一些关键指令的使用。设置断点(如core.h:,test.cpp:),反汇编特定函数(如MyProcessor::ActijonHelper),以及检查内存状态(如0x7fffec8ed)都是定位问题的实用技巧。
在分析过程中,我们应对一些常见问题有所了解。比如,空指针和低地址指针引发的crash,需要通过寄存器和汇编代码来确定问题所在。虚函数调用如果遇到this指针为空或越界,也可能导致程序崩溃,这时寄存器和内存检查是必不可少的。
内存异常,特别是位系统中的内存区域划分,对于理解问题至关重要。异常处理,如除0错误,可能需要根据平台特性进行特殊处理,如在PC上使用特定指令,而在arm架构上可能需要深入到内部函数。
面对 SIGSEGV 和 SIGABRT 这样的异常,我们需要仔细检查内存操作、参数和数据状态。例如,SIGABRT常常出现在业务与系统库交互时,检查参数异常是关键步骤。
总结来说,C++ Crash定位是一个既需要实践操作,又需要理论知识的过程。通过反汇编和调试工具,我们可以逐步解构和修复那些看似无解的崩溃。在日常开发中,理解并掌握这些技巧,将帮助我们更有效地应对各种内存问题。感谢您的关注,希望本文能为您的C++编程之旅提供帮助。
crash流程详解(完结撒花)
终于,我带着Nexus 4和Nexus 5x,因为Android 7的版本较高,决定在Nexus 5x上进行刷机,过程简单易行。
为了实验的高效,我在Android开源项目(AOSP)的源码上直接动手,添加了必要的插桩,目标是监控crash附近的内存操作。涉及的漏洞是Android 5.X版本中,MPEG4编码文件在parseChunk函数处理stsc box时,由于整数溢出导致的问题。
在5.X版本中,stsc的sampletoChunk大小的读取中,右值是int,但左值却是int,一般情况下不会溢出,但当与SampletoChunk结构体大小相乘时,可能会出现问题。特别是当它紧跟着内存分配结构myDataSource时,可能会造成严重的覆盖,尽管未序覆盖只能引发crash。
在Android 7.X版本中,虽然修复了溢出问题并调整了内存分配顺序,但我依然设法制造了内存溢出。我修改了malloc空间,使得mSampleToChunkEntries的分配超出预期,从而引发crash。然而,实际的crash报告并未触发我预设的插桩点,揭示了ASLR和内存布局差异对crash表现的影响。
要重现一致的crash并非易事,因为不同执行环境下,即使相同的漏洞,crash表现也可能千变万化。这暗示着控制流劫持的可能性很小,错误通常源于内存污染,而非控制流的改变。因此,分析需从变量传递转向内存传递,以更深入理解问题。
尽管静态分析结合crash报告能部分揭示从Binder通信到crash的路径,但这些路径不一定揭示出错误行为。人工调试在ASLR的复杂环境下,难以精确定位crash点和代码行。
综上所述,这就是业界在处理这类问题时面临的挑战。
Linux内核调试:kdump、vmcore、crash、kernel-debuginfo
本文将深入探讨 Linux 内核调试技术,主要涉及 kdump、vmcore、crash、以及 kernel-debuginfo 的应用与安装。
kdump 是 Linux 内核崩溃时生成内核转储文件(vmcore)的机制,vmcore 文件包含内核崩溃时的状态,可用于诊断内核崩溃原因。crash 是一个广泛使用的内核崩溃转储文件分析工具,通过使用 crash,我们可以从 vmcore 文件中获取详细信息,来定位和解决内核问题。
为了充分发挥 crash 的功能,需要安装 crash 工具和内核调试工具 kernel-debuginfo。确保安装的版本与 Linux 内核相匹配,可通过执行 `uname -a` 命令查看内核版本。然后,按照以下步骤安装必要的组件:
1. **安装 kexec-tools**:执行 `yum search kexec-tools` 查找 kexec-tools 包,然后使用 `yum install kexec-tools.x_` 进行安装。
2. **配置 kdump**:通过编辑 `/boot/grub/menu.lst` 设置 `crashkernel=auto`,并使用 `vim /etc/kdump.conf` 设置核心转储文件的保存路径,例如 `/var/crash`。最后,启动 kdump 服务,执行 `service kdump start`。
3. **安装 crash**:查找 crash 包,执行 `yum install crash.x_` 安装。
4. **安装 kernel-debuginfo**:安装两个相关 rpm 包,`rpm -ivh kernel-debuginfo-common-x_-2.6.-.el6.x_.rpm` 和 `rpm -ivh kernel-debuginfo-2.6.-.el6.x_.rpm`。
安装完成后,可以通过模拟内核崩溃来测试 kdump 的功能。执行 `echo c > /proc/sysrq-trigger`,这样内核就会崩溃,并在 `/var/crash` 目录下生成 vmcore 文件。接下来,使用 crash 工具分析 vmcore 文件,执行命令 `/usr/bin/crash /usr/lib/debug/lib/modules/2.6.-.el6.x_/vmlinux vmcore`。具体的分析过程可参考“Linux 内核:分析 coredump 文件 - 内核代码崩溃”。
Linux 内核源码的高级知识可以加入开发交流群获取。群内提供免费资源、公开课技术分享,入群不亏,欢迎加入。
资源免费领
学习直通车
å¦ä½å®ä½å¯¼è´Crashç代ç ä½ç½®
1. å¨å¼åç¯å¢ä¸å®ä½Crashé误
ãã1.1 æ®éçcrash
ããããå æ¥ççææ®éçcrash
ããããåè§å¾1(c.png)
ããããå½ä½ å¨debug模å¼ä¸è¿è¡ä¸é¢çç¨åºå°±ä¼å¼¹åºä¸é¢çæ¡ãvcå°±å¸®ä½ å®ä½å°äºé误çä½ç½®ãæ¯ä¸ªå¯¹é¶æéçæä½ãé常ç®åï¼ä¸æ¯åã
ãã1.2 è¾é¾å®ä½çcrash
ããããè¾é¾å®ä½çcrashå¾å¾æ¯ç±äºå åé误(åè§5.1 为ä»ä¹ç¨åºcrashæ¶è°ç¨å æ æ¯ä¹±ç)ãä¾å¦ä»¥ä¸ä»£ç ï¼
代ç
ããããchar *p = new char[];
ããããp[] = 0xfd;
ããããdelete[] p;
ããããprintf(p);
ãããã以ä¸ä»£ç æ两å¤é误ï¼ä¸æ¯ç¬¬2è¡çå ååè¶çï¼äºæ¯ç¬¬4è¡ä½¿ç¨è¢«å é¤çæéã
ããããä½ä»¥ä¸ä»£ç å¨vcçreleaseådebugä¸é½ä¸ä¼æ¥éãè¿ä½¿å¾è¿ç±»é误å¾é¾å®ä½ã
ããããæ£æµè¿ä¸ç±»é®é¢å¯ä»¥ä½¿ç¨BoundsCheckerå·¥å ·çFinalCheck模å¼ï¼BoundsCheckerï¼
ããããç¨BoundsCheckeræ£æµåå¯å¾å°ä¸¤ä¸ªé误ï¼Write overrun(åè¶ç) å Dangling pointer(使ç¨è¢«å é¤çæé)èä¸é½ç²¾ç¡®å®ä½å°äºåºéçä½ç½®ãæ¯ä¸ªä¸éçå·¥å ·ã
ããããåè§å¾2(c.png)
ããããåè§å¾3(c.png)
ãã1.3 注ævcçè¾åºæ¥å¿
ããããç±äºä¸äºç®åæªç¥çåå ï¼æå¯è½æ¯ç¨åºçé误太严éææ¯BoundsCheckeræ¬èº«çbugï¼ï¼BoundsChekcerææ¶ä¸è½æ£å¸¸å·¥ä½ã
ããããè¿évcçè¾åºæ¥å¿ææ¶è½æä¾ä¸äºæç¨çä¿¡æ¯ã
ããããå¨é¾æ¾çcrashä¸ï¼æå¾å¤§ä¸é¨åæ¯å¼ç¨äºéæ³çæéã
ããããææ¶å¨vcçè¾åºæ¥å¿éå¯ä»¥çå°ç±»ä¼¼äºè¿æ ·çä¿¡æ¯
ããããâemule.exe ä¸ç 0xb7 å¤æå¯è½çå¼å¸¸: 0xC: 读åä½ç½® 0xfeeeff æ¶åç访é®å²çª ãâ
ããããå¨ç¼ºå°BoundsCheckerçæ¯ææ¶ï¼è¿æ¯ä¸æ¡å¾éè¦çä¿¡æ¯ãæææ¯è¯´å¨âç¨åºå°å0xb7å¤â对âå¼ä¸º0xfeeeffçæéâè¿è¡æä½ã
ããããï¼æä¹éè¿âç¨åºå°å0xb7âæ¾å°å¯¹åºç代ç è¡å¯åç § 3.1ï¼ï¼
ããããè¿æ¡ä¿¡æ¯çéè¦æ§å¨äºï¼è¿ä¸ªæä½åªä¼è§¦åä¸ä¸ªè¦åï¼èä¸ä¼å¯¼è´crashï¼å½crashçæ£åçæ¶ï¼å¾æå¯è½ä¸ä¼å¨0xb7éè¿ï¼
ããããçè³è°ç¨å æ é½å·²ç»è¢«åä¹±ï¼è®©ä½ æ ä»ä¸æãï¼åè§5.1 为ä»ä¹ç¨åºcrashæ¶è°ç¨å æ æ¯ä¹±çï¼
2. å®ä½åå¸å¨å¤ççæ¬çCrashé误
ããåå¸å¨å¤ç软件crashäºï¼å¾å¾ä¸å¥½è°è¯ï¼æ以ç®åå¾å¤è½¯ä»¶é½æâåéé误æ¥åâè¿ä¸åè½ã
ããå®ç°è¿ä¸åè½ä¸è¬å以ä¸å æ¥ï¼
ããa. 使ç¨SetUnhandledExceptionFilterå½æ°
ãããã使ç¨SetUnhandledExceptionFilter设置æé«ä¸çº§çå¼å¸¸å¤çå½æ°ï¼å½ç¨åºåºç°ä»»ä½æªå¤ççå¼å¸¸ï¼é½ä¼è§¦åä½ è®¾ç½®çå½æ°éãå ·ä½ä½¿ç¨å¯åç §msdnåemuleæºç ã
ããb. 使ç¨MiniDumpWriteDumpå½æ°
ããããå¨ä½ çå¼å¸¸å¤çå½æ°éï¼ä½¿ç¨MiniDumpWriteDumpæé误信æ¯åæç¹å®æ ¼å¼çæ件ãå ·ä½ä½¿ç¨å¯åç §msdnåemuleæºç ã
ããc. åéé误æ¥å
ããããéç¨ä¸ç§å½¢å¼æ第äºæ¥äº§ççé误æ¥å(.dmp)æ件åéç»ä½ æå®çå°æ¹ã
ããd. æ¥çé误æ¥å
ããããè¿éä»ç»ç¨vcæ¥çé误æ¥åçæ¹æ³ï¼è¿å¯ä»¥ç¨windows debug toolsè¿ä¸ªå·¥å ·çï¼æ¹æ³è§5.2 使ç¨windows debug toolsæ¥ç.dmpæ件(é误æ¥å)
ãããã
ããããæ¥çé误æ¥åéè¦æä¸æ ·ä¸è¥¿ï¼å¯¹åºreleaseçç代ç ï¼å½æ¶ç¼è¯releaseçæ产çç.exeå.pdbæ件ãï¼è¿ä¸¤ä¸ªæ件é½å¨ç¼è¯çè¾åºç®å½éãï¼æ以å½ç¨åºåå¸æ¶ï¼è¦ä¿çä¸è¿ä¸¤ä¸ªæ件ã
ããããæ.dmpï¼é误æ¥åæ件ï¼, .pdb, .exe. 代ç ï¼å¨åä¸ç®å½ä¸ï¼ç¨vcæå¼.dmp æ件ã
ããããæF5è¿è¡ï¼ç¨åºå³å°è¾¾crashæ¶çç¶æï¼å¯ä»¥å¯¹å ¶è¿è¡ç¸åºçåæã
ãããã
ããä¸ç¹è¡¥å ï¼å½æ²¡æâåéé误æ¥åâçåè½ï¼ææ¯æ¤åè½å¤±æï¼ä»¥è´å¼¹åºäºwindowsçâåéé误æ¥åâç对è¯æ¡ãè¿æ¶å ¶å®ä¹æ¯æé误æ¥åçï¼ä¸è¬å¨C:Documents and Settingsç¨æ·åLocal SettingsTempéçä¸ä¸ª.dmpæ件(ä¸è¬åªæä¸ä¸ª.dmp)
3. å°æå·§
ãã3.1 æ ¹æ®ç¨åºå°åæ¾å°ä»£ç ä½ç½®
ããããå¯æå¦ä¸æ¥éª¤ï¼
ããããa. 使ç¨åºå¤äºåæ¢ç¶æãï¼æ¯å¦ç¨åºè¿è¡æ¶ï¼å¨vcéæCtrl+Alt+Breakï¼æ设æç¹ä½¿ç¨åºåä¸ï¼
ããããb. åæ¢å°æ±ç¼ç¶æãï¼Ctrl+Fï¼
ããããc. å¨å°åæ è¾å ¥ç¨åºå°åï¼å车ã
ããããd. å¯æCtrl+Fåå代ç 模å¼ã
ãã3.2 æ ¹æ®æ¶æ¯å¼æ¥ç对åºçwindowsæ¶æ¯
ããããå¨vcççè§çªå£éè¾å ¥âæ¶æ¯å¼,wmâå³å¯çå°å¯¹åºçæ¶æ¯ã
ãã3.3 æ¥çGetLastErrorè¿åå¼
ããããå¨vcççè§çªå£éè¾å ¥â@err,hrâï¼å³å¯çå°LastErroråå ¶è§£éã
ãã3.4 å¨ä»£ç ä¸æåç¨åº
ããããå¨debugçä¸å¯ä»¥å¨ä»£ç ä¸å ä¸âAfxDebugBreak()ï¼â以æåç¨åºãreleaseçå¯ä½¿ç¨ â_asm int 3;â
4. ç¼ç¨å°è¦ç¤º
ãã4.1 æ ç¨IsBadPtrç³»åå½æ°
ããããå½ä½¿ç¨IsBadReadPtr, IsBadWritePtr, IsBadCodePträ¸ç³»åå½æ°æ¶è¦æ³¨æï¼è¿ä¸ç±»å½æ°å¯è½å¹¶ä¸è½è¾¾å°ä½ ææ³è¦çæå¾ã
ããããæ¯å¦ä¸é¢ç代ç ï¼ä¸¤ä¸ªè¿åé½æ¯falseã
代ç
char *p = new char[];
bool b;
b = IsBadReadPtr(p+, 1);
delete[] p;
char *q = new char[];
b = IsBadReadPtr(p, 1);
ããããæ以åå¿å¨ç¨åºä¸ä»¥IsBadPtrå½æ°æ¥å¤ææ¯å¦å¯ä»¥å¯¹è¿ä¸ªæéè¿è¡æä½ãè¿äºå½æ°åªè½å¨è°è¯ä¸ä½¿ç¨ï¼ææ¯ä½ ç¡®åçç¥éè¿äºå½æ°çè¿åå¼è¡¨ç¤ºçæ¯ä»ä¹æä¹çæ¶åã
ãã4.2 æ ç¨catch(...)
ãããã为äºé²æ¢ç¨åºcrashææ¯è§£å³ä¸ä¸ªä¸æç½çcrashæ¶ï¼å¤§å®¶å¾å®¹ææ³å°ä¸ä¸ª try{ }catch(...){ }æ¥è§£å³é®é¢ã
ããããç确大é¨åæ¶é´è¿æ ·ä¸ä¼åºé®é¢äºï¼ä½è¿ä¸ªtry-catchå¾æå¯è½éèæå¨tryéé¢çé误ï¼èå½ç±æ¤é误å¼èµ·å ¶ä»é误æ¶ï¼å°±å¾é¾è¿½è¸ªå°è¿ä¸ªé®é¢äºã
ããããæ以建议尽éå°ç¨catch(...)ï¼å¦æç¥éæä¸å代ç ä¼æåºå¼å¸¸ï¼åºè¯¥ç¨ç¡®åçåæ³ãæ¯å¦catch(CFileException *e), catch(int e)ççã
5. éå½
ãã5.1 为ä»ä¹ç¨åºcrashæ¶è°ç¨å æ æ¯ä¹±ç
ããããå½å å被åä¹±æ¶ç¨åºå¾æå¯è½åºç°å¾é¾å®ä½çcrashï¼æ¯å¦è°ç¨å æ æ¯ä¹±çï¼æèµ°å°ä¸åå¨ç代ç éãè¿é举ä¸ä¾
代ç
class CA
{
public:
CA(){ }
~CA(){ }
virtual f(){ }
};
void show()
{
printf("shown");
}
int main()
{
// 对å被å建å é¤
CA *p = new CA;
delete p;
// ä¸äºæ£å¸¸çæä½
int *q = new int;
int codeAddress = (int)show;
*q = (int)&codeAddress;
// è°ç¨è¢«å é¤ç对åï¼ç¨åºæå¯è½æ§è¡å°ä»»ä½å°æ¹ã
p->f();
}
ããããä¸é¢ä»£ç çç»æä¼èµ°å°show()éæ¾ç¤ºåºshowï¼è¿è·ç¼è¯ç¯å¢æå ³ï¼vcä¸æµè¯ç»ææ¯è¿æ ·ï¼ãå¦æä½ äºè§£c++çvtableæºå¶å°±æç½è¿æ¯æä¹åäºã
ããããå¦æä¸æç½ä¹æ²¡å ³ç³»ï¼æä¸é¢è¯´ä¸ªå¤§æ¦ã
ããããé¦å CA对象被å建å被å é¤ãå¦ææ¤æ¶è°ç¨p->f()å¤åä¼crashã
ãããã第äºå代ç å¯è§ä¸ºä¸äºæ£å¸¸çæä½ï¼newäºä¸ä¸ªqï¼ç¶å对å®è¿è¡äºä¸äºèµå¼ã
ããããå¦æä½ ä¸æç½vtableæºå¶ï¼é£ä½ åªè¦ç¥éï¼æåä¸è¡ç âp->f();âä¼æ§è¡åéqææåçåéææåçåéææ 示çå°åãï¼è¿é没æéåï¼æ¯ä¸¤ä¸ªâææåçåéâï¼
ããããè¿éæâå¿å°åè¯âçç»è¿ä¸ªå¼èµä¸äºä¸ä¸ªåæ³çå½æ°å°åshowãä½å®é ç¨åºä¸qææåçåéæå¯è½æ¯ä»»æå¼ï¼å®åæåçåéå°±æ´æ¯ä»»æå¼äºã
ããããé£ç¨åºå°±ä¸ç¥éè·åªéå»äºãå¦æè¿ä¸ªå¼è¿äºç¦»è°±ï¼é£ç®ä½ è¿æ°å¥½ï¼ç¨åºä¼ç«å³crashï¼èä½ å°±ç¥éé误ä½ç½®å¨åªäºãä½è®¨äººåçæ¯ï¼å®æå¯è½æ¯ä¸ä¸ªåæ³å°åï¼é£ç¨åºå°±ç»§ç»èµ°ä¸å»ï¼
ããããä½è¿æ©ä¼crashï¼å¹¶ä¸è°ç¨å æ é¢ç®å ¨éï¼åå çµæ¶å°âè°ç¨å æ çæ¨å¯¼âçé®é¢è¿éå°±ä¸å¤è¯´äºï¼ï¼
ããããå°æ¶å°±æ ¹æ¬æ ä»ç¥éåæ¥æ¯è°ç¨äºè¢«å é¤çp对象è导è´çã
ãã5.2 使ç¨Debugging tools for windowsæ¥ç.dmpæ件(é误æ¥å)
ããããa. åå¤å¥½ç¨åºå¯¹åºç代ç ï¼exeæ件ï¼pdbæ件ï¼ç¼è¯æ¶å¨ç¼è¯è¾åºç®å½éï¼
ããããb. å®è£ WinDbg
ããããc. å¨winDbgéæSymbolç®å½è®¾å¨.pdbæå¨ç®å½ï¼Imageç®å½è®¾å¨.exeæå¨ç®å½ï¼codeç®å½è®¾å°ä»£ç ç®å½ã
ããããd. æå¼.dmpæ件
ããããe. è¾å ¥å½ä»¤.ecxrãï¼æ¤å½ä»¤ä½¿ç¯å¢åå°å´©æºæ¶çç¶æï¼
ããããf. æå¼è°ç¨å æ (ALT + F6)æ¥çCrashçä½ç½®
ããããg. è¿è¡åæ
ç®ä»
ããï¼FinalCheckè½æ£æµåºçé误å表è§éå½1ï¼
ããBoundsCheckeræ¯ä¸ä¸ªå¾å¼ºå¤§çè°è¯å·¥å ·ãè¿éåªç®åä»ç»å¦ä½ç¨å®çFinalCheck模å¼å®ä½æ¯è¾é¾å®ä½çé误ã
FinalCheck模å¼ç®åæ¥è¯´å°±æ¯BoundsCheckerå¨ä½ ç代ç éå ä¸äºè¯æ代ç æ¥æ£æ¥å¹³æ¶æ¯è¾é¾æ¥åºçå åè¶çï¼é误çæé使ç¨çã
ä¸è¿ä»åºç代价就æ¯ç¨åºè·èµ·æ¥ä¼æ¯è¾æ ¢ï¼æ以å¨ä¸ç¨æ¶æ好æ¯æFinalCheck模å¼å ³æãç¹å«æ¯åå¸åã
Android crash问题分析定位方法
当Android应用运行时遭遇crash异常,关键线索往往隐藏在tombstone文件中。首先,我们需要从/data/tombstones目录获取这个文件,其内容大致记录了异常发生时的内存状态。通过阅读crash日志,可以看到一个内存申请错误的迹象。
为了进一步定位问题,我们采取以下步骤:首先,利用addr2line工具解析tombstone文件,它能揭示错误发生的代码行,便于对照源代码进行分析。如果前两步还不能确定问题源头,可以尝试使用objdump工具。objdump能反汇编出出错函数的代码,帮助我们深入理解问题的底层逻辑。
在objdump的帮助下,我们注意到在出错函数的fp-2位置(通常fp对应r,fp-2则是fp后的第二个内存地址)存储着入参Id。在tombstone中,fp的值为eff,而在stack中fp-2的值为0x。这些信息为我们揭示了crash的具体位置,结合源码和汇编代码,就能有效地定位到问题所在。