Android native crash log分析

本文介绍两种分析Android native crash log的方法:使用Google的stack工具和使用android-ndk-stacktrace-analyzer。文中详细展示了这两种工具的使用步骤及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原帖地址:http://blog.youkuaiyun.com/huaciom/article/details/6997708

http://pjq.me/wiki/doku.php?id=android:android-jni:android-ndk-stacktrace-analyzer

Android native crash log分析

找到两种方法一种是使用google 的stack工具,一种是使用Analyze android-ndk stack trace.

参考:

stack下载:

android-ndk-stacktrace-analyzer用法

android-ndk/android-ndk-1.6_r1/build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/arm-eabi-objdump -S mylib.so > mylib.asm
python parse_stack.py mylib.asm logcat.txt

举例:

D:\stack>python parse_stack.py libslpi.asm logcat.txt
0x000b7e80:            pjsua_acc_unregister + 0x0068

D:\stack>ls
libslpi.asm  libslpi.so  logcat.txt  parse_stack.py  stack.py

stack用法:

python stack.py logcat.txt

说明:stack看起来是google内部使用的工具,在windows上跑不起来,需要在Linux环境下,还有使用的时候会提示so文件的位置不存在,按照它的要求,建立相应的目录,并放入so文件就可以了。举例:

root@impjq:~/stack# python stack.py logcat.txt
make: build/core/envsetup.mk: No such file or directory
make: *** No rule to make target `build/core/envsetup.mk'.
Searching for native crashes in logcat.txt
Reading symbols from
pid: 4538, tid: 4553  >>> com.arcsoft.ddtui <<<
signal 11 (SIGSEGV), fault addr deadbaad
  r0 00000000  r1 afd14679  r2 00000027  r3 00000070
  r4 afd42328  r5 00000000  r6 00000000  r7 00000cb0
  r8 80fac890  r9 485d8d8c  10 485d8ce4  fp 0000033c
  ip 00001770  sp 485d8880  lr deadbaad  pc afd11cd0
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file
arm-eabi-addr2line: '/system/lib/libc.so': No such file

Stack Trace:
  ADDR      FUNCTION              FILE:LINE
  00011cd0  (unknown)             (unknown)
  00018fac  (unknown)             (unknown)
  000b7e80  pjsua_acc_unregister  ??:0

Stack Data:
  ADDR      VALUE     FILE:LINE/FUNCTION
  485d8840  00000340
  485d8844  afd146a9  (unknown)
                      (unknown)
  485d8848  afd42498  (unknown)
                      (unknown)
  485d884c  afd43bb4  (unknown)
                      (unknown)
  485d8850  00000000
  485d8854  afd156c3  (unknown)
                      (unknown)
  485d8858  afd14679  (unknown)
                      (unknown)
  485d885c  afd14679  (unknown)
                      (unknown)
  485d8860  00000070
  485d8864  afd42328  (unknown)
                      (unknown)
  485d8868  00000000
  485d886c  485d8894
  485d8870  00000cb0
  485d8874  afd1491b  (unknown)
                      (unknown)
  485d8878  df002777
  485d887c  e3a070ad
  485d8880  485d8df4
  485d8884  80fad540
  485d8888  00000cb0
  485d888c  afd14c81  (unknown)
                      (unknown)
  485d8890  afd4254c  (unknown)
                      (unknown)
  485d8894  fffffbdf
  485d8898  00000002
  485d889c  485d8df4
  485d88a0  80fad540
  485d88a4  afd18fb1  (unknown)
                      (unknown)
  485d88a8  00000946
  485d88ac  00000946
  485d88b0  80f5b018  ??:0
                      ??
  485d88b4  80eb7e84  ??:0
                      pjsua_acc_unregister

指定路径:

root@impjq:~/stack# python stack.py  --symbols-dir=. logcat.txt

这样会提示某些lib不存在

root@impjq:~/stack# python stack.py  --symbols-dir=. logcat.txt
make: build/core/envsetup.mk: No such file or directory
make: *** No rule to make target `build/core/envsetup.mk'.  Stop.
Searching for native crashes in logcat.txt
Reading symbols from .
pid: 4538, tid: 4553  >>> com.arcsoft.ddtui <<<
signal 11 (SIGSEGV), fault addr deadbaad
  r0 00000000  r1 afd14679  r2 00000027  r3 00000070
  r4 afd42328  r5 00000000  r6 00000000  r7 00000cb0
  r8 80fac890  r9 485d8d8c  10 485d8ce4  fp 0000033c
  ip 00001770  sp 485d8880  lr deadbaad  pc afd11cd0
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './data/data/com.arcsoft.ddtui/lib/libslpi.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './system/lib/libc.so': No such file
arm-eabi-addr2line: './data/data/com.arcsoft.ddtui/lib/libslpi.so': No such file
arm-eabi-addr2line: './data/data/com.arcsoft.ddtui/lib/libslpi.so': No such file

按照它的提示,建立相应的目录就可以了,其中libc.so我是直接从ndk里拷贝过来的,这样正常的运行结果如下:

root@impjq:~/stack# python stack.py  --symbols-dir=. logcat.txt
make: build/core/envsetup.mk: No such file or directory
make: *** No rule to make target `build/core/envsetup.mk'.  Stop.
Searching for native crashes in logcat.txt
Reading symbols from .
pid: 4538, tid: 4553  >>> com.arcsoft.ddtui <<<
signal 11 (SIGSEGV), fault addr deadbaad
  r0 00000000  r1 afd14679  r2 00000027  r3 00000070
  r4 afd42328  r5 00000000  r6 00000000  r7 00000cb0
  r8 80fac890  r9 485d8d8c  10 485d8ce4  fp 0000033c
  ip 00001770  sp 485d8880  lr deadbaad  pc afd11cd0

Stack Trace:
  ADDR      FUNCTION              FILE:LINE
  00011cd0  pclose                /usr/local/google/home/digit/android/main/cupc
ake/android/bionic/libc/unistd/popen.c:146
  00018fac  strtod                /opt/digit/android/main/cupcake/android/bionic
/libc/stdlib/strtod.c:1327
  000b7e80  pjsua_acc_unregister  ??:0

Stack Data:
  ADDR      VALUE     FILE:LINE/FUNCTION
  485d8840  00000340
  485d8844  afd146a9  /usr/local/google/home/digit/android/main/cupcake/android/
bionic/libc/stdio/setvbuf.c:84
                      setvbuf
  485d8848  afd42498  libgcc2.c:0
                      __timer_table
  485d884c  afd43bb4  libgcc2.c:0
                      __timer_table
  485d8850  00000000
  485d8854  afd156c3  /usr/local/google/home/digit/android/main/cupcake/android/
bionic/libc/stdio/vfprintf.c:396
                      vfprintf
  485d8858  afd14679  /usr/local/google/home/digit/android/main/cupcake/android/
bionic/libc/stdio/setvbuf.c:67
                      setvbuf
  485d885c  afd14679  /usr/local/google/home/digit/android/main/cupcake/android/
bionic/libc/stdio/setvbuf.c:67
                      setvbuf
  485d8860  00000070
  485d8864  afd42328  libgcc2.c:0
                      __timer_table
  485d8868  00000000
  485d886c  485d8894
  485d8870  00000cb0
  485d8874  afd1491b  /usr/local/google/home/digit/android/main/cupcake/android/
bionic/libc/stdio/tempnam.c:50
                      tempnam
  485d8878  df002777
  485d887c  e3a070ad
  485d8880  485d8df4
  485d8884  80fad540
  485d8888  00000cb0
  485d888c  afd14c81  /usr/local/google/home/digit/android/main/cupcake/android/
bionic/libc/stdio/ungetc.c:139
                      ungetc
  485d8890  afd4254c  libgcc2.c:0
                      __timer_table
  485d8894  fffffbdf
  485d8898  00000002
  485d889c  485d8df4
  485d88a0  80fad540
  485d88a4  afd18fb1  /opt/digit/android/main/cupcake/android/bionic/libc/stdlib
/strtod.c:1327
                      strtod
  485d88a8  00000946
  485d88ac  00000946
  485d88b0  80f5b018  ??:0
                      ??
  485d88b4  80eb7e84  ??:0
                      pjsua_acc_unregister


<think>好的,我现在需要回答用户关于数据库或存储系统中crash-safe机制的问题。用户已经提供了一些引用资料,我需要结合这些引用和之前的对话内容来组织答案。 首先,用户提到的crash-safe机制,根据引用资料,主要涉及redo log和WAL技术。我需要先明确crash-safe的定义,即数据库在崩溃后能够恢复数据到一致状态的能力。然后,根据引用[2]和[3],WAL是关键,即在修改数据前先写日志。这样即使崩溃,也能通过日志恢复。 接下来,要分点说明实现原理。首先,WAL技术,确保所有修改先记录到日志。这里需要提到redo log的作用,如引用[1]和[4]提到的,redo log在InnoDB引擎中,保障了crash-safe。然后,需要解释redo log的工作流程,比如事务修改数据时先写入redo log buffer,再刷盘到磁盘的redo log文件组,这样即使崩溃,也能通过redo log恢复未写入数据文件的数据。 然后,需要提到两阶段提交,因为用户之前的问题提到了这个,引用[4]也涉及。两阶段提交是保证事务在binlog和redo log之间的一致性,避免数据不一致。这需要详细解释prepare和commit阶段,以及如何通过日志确保原子性。 接着,保障措施部分,可以包括日志持久化策略,如innodb_flush_log_at_trx_commit参数的不同设置对数据安全性的影响,以及checkpoint机制如何减少恢复时间。此外,还可以提到双写缓冲(Double Write Buffer)防止部分写问题,虽然引用中没有提到,但根据常识,这是InnoDB的另一个保障措施,需要确认是否相关。 然后,对比redo log和binlog的不同,如引用[1]和[4]指出,redo log用于崩溃恢复,binlog用于数据复制和备份,两者角色不同,无法替代。这部分可以作为实现原理的一部分,帮助用户理解为什么需要两种日志。 在组织答案时,需要确保结构清晰,分点列出实现原理和保障措施,每部分都引用相关资料支持。同时,用户之前的问题涉及redo log文件组在磁盘中的情况,所以在回答crash-safe时,需要关联到redo log的持久化存储,如引用[3]提到的日志先行和异步写入磁盘。 可能需要注意的地方是,用户的问题还提到存储系统,所以可能需要稍微扩展一下,但根据引用资料,主要集中在数据库,特别是MySQL的实现。因此,可以主要围绕MySQL的机制展开,适当提及通用原理。 最后,生成相关问题时要基于当前内容,比如两阶段提交的详细过程,WAL的其他应用,checkpoint的作用等。</think>--- ### **逐步解答** Crash-safe机制是数据库/存储系统在意外崩溃后仍能**保证数据一致性**和**持久性**的核心保障。其实现依赖于**预写日志(WAL)**、**原子性事务控制**和**多版本控制**等技术。以下是具体实现原理及保障措施: --- ### **一、Crash-safe的实现原理** #### 1. **预写日志(WAL, Write-Ahead Logging)** - **核心规则**:任何数据修改必须**先记录日志,再写入数据文件** - **作用**: - 避免直接修改数据文件时的随机I/O(性能优化)[^3] - 通过日志记录操作序列,确保崩溃后可**重放(Redo)**或**撤销(Undo)**未完成事务[^2] - **日志类型**: - **Redo Log**:记录**物理修改**(如InnoDB引擎的页修改),用于恢复未持久化的数据[^1][^4] - **Undo Log**:记录**逻辑操作**(如事务前的数据版本),用于回滚未提交事务[^4] #### 2. **两阶段提交(2PC, Two-Phase Commit)** - **背景**:协调事务日志(如binlog)与存储引擎日志(如redo log)的一致性[^4] - **流程**: ```text 1. 准备阶段(Prepare Phase): - InnoDB将事务的redo log写入磁盘并标记为PREPARE状态 2. 提交阶段(Commit Phase): - 写入binlog后,将redo log标记为COMMIT状态 ``` - **崩溃恢复逻辑**: - 若binlog完整且redo log为COMMIT → 提交事务 - 若binlog不完整但redo log为PREPARE → 回滚事务[^4] #### 3. **检查点(Checkpoint)机制** - **作用**:标记已持久化到数据文件的日志位置,缩小崩溃恢复时的日志扫描范围 - **实现方式**: - 定期将内存中的脏页(Dirty Page)刷盘 - 更新日志序列号(LSN)以标识已完成持久化的日志点[^2] --- ### **二、关键保障措施** #### 1. **日志持久化策略** - **Redo Log刷盘控制**: - `innodb_flush_log_at_trx_commit=1`:事务提交时**同步刷盘**(最高安全级别) - `innodb_flush_log_at_trx_commit=0/2`:异步刷盘(性能优化,但可能丢失最近1秒的日志)[^2] - **Binlog同步策略**: - `sync_binlog=1`:事务提交后强制刷盘binlog #### 2. **日志文件组设计** - **Redo Log循环写入**: - 通过多个固定大小的日志文件(如MySQL默认2个)循环覆盖写入 - 避免日志文件无限增长,同时保留足够信息用于恢复[^1] - **日志块对齐**: - 以512字节为单位写入磁盘,匹配物理磁盘扇区大小(防止部分写问题) #### 3. **崩溃恢复流程** ```text 1. 分析阶段(Analysis Phase): - 扫描redo log确定崩溃时活跃事务的状态 2. 重做阶段(Redo Phase): - 根据LSN重放所有未持久化的修改 3. 撤销阶段(Undo Phase): - 回滚未提交事务(通过undo log) ``` --- ### **三、与Binlog的协作与差异** | **对比维度** | **Redo Log** | **Binlog** | |-------------------|-----------------------------|--------------------------------| | **层级** | 存储引擎层(如InnoDB) | 数据库服务层(Server层) | | **内容类型** | 物理日志(页修改) | 逻辑日志(SQL语句或行变更) | | **主要用途** | 崩溃恢复(Crash-safe) | 数据复制(主从同步)、时间点恢复 | | **持久性保障** | 强制刷盘保证事务持久性 | 依赖配置参数(sync_binlog) | --- ### **总结** Crash-safe通过**WAL**、**两阶段提交**和**检查点**等机制,结合**redo log的物理日志特性**和**binlog的逻辑日志能力**,实现了崩溃后的数据一致性恢复[^1][^2]。其核心思想是:**用顺序追加的日志写入替代随机数据修改,以性能换安全**。 --- ### **相关问题** 1. 为什么说Redo Log的写入是顺序I/O?这与传统数据文件写入有何区别? 2. 两阶段提交中如果Binlog写入失败,数据库如何保证事务一致性? 3. Checkpoint机制如何平衡崩溃恢复速度与系统性能?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值