Skip to content

Latest commit

 

History

History
107 lines (86 loc) · 4.84 KB

调试技术.md

File metadata and controls

107 lines (86 loc) · 4.84 KB

libc,uClibc

如果崩溃在libc或uClibc中,但又没有堆栈信息,可以自己下载源码编译替换库。 libc源码 uClibc源码 make menuconfig

  1. 选择小端模式
  2. 注意配置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 的优化选项,但又不缩减代码尺寸的方法。

addr2line

arm-linux-addr2line -e 可执行文件 <lr>

查看崩溃地址

gdb后,l *崩溃地址

coredump

  • 放开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

gdb 下载编译

gdb 应用程序

如果打印不出代码,可能原因是由于移动源文件的位置后,gdb无法找到源文件的位置,估计可执行文件的调试段内保存的不是源文件的内容,而是路径信息。

gdb 常用指令

断点

  • b 函数名
  • b 文件名:行号, b test.c:20
  • info b,断点信息

 scheduler-locking

GDB> show scheduler-locking     //显示线程的scheduler-locking状态
GDB> set scheduler-locking on/off/step 默认为off on:只有当前调试线程运行,其他线程处于暂停状态。
off:当前调试线程外的其他线程一直在正常运行。
step:其他线程跟随当前调试线程运行,但具体怎么协同运行,测试中无法体现。

gdb attach 进程id : 实时gdb命令

忽略信号

handle SIGPIPE nostop noprint

SIGTTIN ,读写控制台终端时,将会触发 SIGTTIN(读) 和 SIGTTOU(写)信号量. SIGPIPE :管道关闭

gdbsever,attach

  1. 如有看门狗,关闭看门狗
  2. arm-linux-gdbserver 放到设备挂载目录 debug版 可执行程序 放到挂载目录 拷贝关联库到挂载目录: cp -f /lib/* /mnt/nfs/lib
  3. 设备端启动调试的可执行程序 可能需要关联环境变量(export LD_LIBRARY_PATH=/home/app )
  4. 设备端运行gdbserver ./arm-linux-gdbserver 服务器地址:端口 --attach <pid>
  5. 编译平台或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
  1. 远程启动调试 要在不提供要运行的初始命令或要附加的进程 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