如果崩溃在libc或uClibc中,但又没有堆栈信息,可以自己下载源码编译替换库。 libc源码 uClibc源码 make menuconfig
- 选择小端模式
- 注意配置Target Architecture Features and Options 中头文件目录为交叉编译工具链的include
默认为O2优化级别,gdb时候会出现<optimized out>,需加上-o0参数项以及fno-omit-frame-pointer
fomit-frame-pointer, -O(= -O1), -O2, -O3等 函数调用时不保存frame指针。
- -O0,最少的优化。(这是默认的编译选项)(可以最大程度上配合产生代码调试信息,可以在任何代码行打断点,特别是死代码处)
- -O 或 -O1,有限优化。(编译时占用稍微多的时间和相当大的内存,减少代码生成尺寸、缩短执行时间)(去除无用的 inline 和无用的 static 函数、死代码消除等,在影响到调试信息的地方均不进行优化,在适当的代码体积和充分的调试之间平衡,代码编写阶段最常用的优化等级)
- -O2,高度优化。(在 -O1 的基础上,尝试更多的寄存器级的优化以及指令级的优化)(调试信息不友好,有可能会修改代码和函数调用执行流程,自动对函数进行内联)
- -O3,最大程度优化。(在 -O2 的基础上,针对循环进行更多的优化,更激进的函数内陆等)
- -Os,相当于 -O2.5。使用了所有 -O2 的优化选项,但又不缩减代码尺寸的方法。
arm-linux-addr2line -e 可执行文件 <lr>
gdb后,l *崩溃地址
- 放开core大小限制:
ulimit -c unlimited
- 如有看门狗,关闭看门狗
- 修改生成coredump规则:
echo "core.%e.%p.%t.%s" > /proc/sys/kernel/core_pattern
- gdb调试debug文件: gdb ./应用程序
- 设置关联库路径: set solib-search-path
- core corefile
- http://ftp.gnu.org/gnu/gdb/
- wget http://ftp.gnu.org/gnu/gdb/gdb-7.12.tar.gz, 下载gdb-7.12.tar.gz,gdb 8之后需要编译器支持C++ 11,可能会编译不通过
- 交叉编译:
./configure --prefix=/Users/work/gdblib --host=arm-linux --target=arm-linux; make; make install
如果打印不出代码,可能原因是由于移动源文件的位置后,gdb无法找到源文件的位置,估计可执行文件的调试段内保存的不是源文件的内容,而是路径信息。
- b 函数名
- b 文件名:行号,
b test.c:20
- info b,断点信息
GDB> show scheduler-locking //显示线程的scheduler-locking状态
GDB> set scheduler-locking on/off/step 默认为off on:只有当前调试线程运行,其他线程处于暂停状态。
off:当前调试线程外的其他线程一直在正常运行。
step:其他线程跟随当前调试线程运行,但具体怎么协同运行,测试中无法体现。
handle SIGPIPE nostop noprint
SIGTTIN ,读写控制台终端时,将会触发 SIGTTIN(读) 和 SIGTTOU(写)信号量. SIGPIPE :管道关闭
- 如有看门狗,关闭看门狗
- arm-linux-gdbserver 放到设备挂载目录
debug版 可执行程序 放到挂载目录
拷贝关联库到挂载目录:
cp -f /lib/* /mnt/nfs/lib
- 设备端启动调试的可执行程序 可能需要关联环境变量(export LD_LIBRARY_PATH=/home/app )
- 设备端运行gdbserver
./arm-linux-gdbserver 服务器地址:端口 --attach <pid>
- 编译平台或PC运行
./arm-linux-gdb 调试的可执行程序
set solib-search-path ./lib #设置编译动态库
set target-async 1 #打开异步模式
set pagination off #关闭自动分页
set non-stop on #调试特定线程不影响其他线程运行, off影响
set print pretty on #打印结构体时每隔成员占据单独的一行
target remote 10.6.120.241:8888
attach 可执行程序的pid
有时候线程太多,想写到文件里,可以:
(gdb)set logging file <文件名>
(gdb)set logging on
(gdb)thread apply all bt
(gdb)set logging off
(gdb)quit
- 远程启动调试 要在不提供要运行的初始命令或要附加的进程 ID 的情况下启动“gdbserver”,请使用 --multi 命令行选项。 在这种情况下,您应该使用“target extended-remote”连接来启动您要调试的程序。 使用set remote exec-file filename来指定gdbserver执行路径下的某个文件将被执行调试。 gdb这边指定被调试程序有两种方法,在命令行启动gdb时使用gdb program来指定,或者直接gdb进入,然后使用命令file program来指定。
目标 ./gdbserver --multi localhost:端口 &
服务端:./gdb
(gdb) target extended-remote IP:端口
(gdb) set remote exec-file /home/app/xx
(gdb) file xx
(gdb) r