巧用你的gdb
一、调试段错误
当运行程序发生段错误时,使用GDB调试能快速定位错误位置
Linux提供的core dump机制:当程序中出现内存操作错误时,会发生崩溃并产生核心文件(core文件)。
(1)无论你是用Makefile来编译,还是直接在命令行手工输入命令来编译,都应该加上 -g
选项。
(2)一般来说,在默认情况下,在程序崩溃时,core文件是不生成的(很多Linux发行版在默认时禁止生成核心文件)。所以,你必须修改这个默认选项,在命令行执行:
$ ulimit -c unlimited // 不限制生成的core文件的大小
(3)运行你的程序,使之重现Segmentation Fault错误。
(4)这时,你会发现在你程序同一目录下,生成了一个文件名为 core.*** 的文件,即核心文件。例如,“core.1523”这样的文件。
(5)用GDB调试它。假设你的可执行程序名为test,则在命令行执行:
$ gdb test core.1523
二、调试桌面文件管理器caja软件
当你试图在Linux系统上解一个bug,而且之前也对出问题的软件不熟悉,只知道该项目使用C/C++,那么GDB是你的不二选择。
1.问题背景:
某厂商需要参照window系统,修改移动桌面文件到U盘中删除文件,需要delete
删除U盘中文件,而不是删除桌面文件。
2.问题分解
根据window系统的现象,可以得知:
1)移动桌面文件到U盘中,此时鼠标焦点在U盘窗口,U盘窗口是activate状态;
2)在U盘窗口是activate状态时,此时按下delete
键删除的是U盘中的文件。
所以,要完成某厂商的需求,可以在移动桌面文件到U盘后,进行U盘文件窗口的激活,即成为activate状态。
3. C/C++跟踪利器GDB
经过2的问题分解后,就应该进行代码跟踪,常规的通过syslog进行手动跟踪日志,会有以下几个限制:
1)一个文件中需要watch的变量过多,手动添加日志过于繁琐;
2)当前问题未知在哪个文件中,经常会遇到辛苦半天在预期的文件加上日志,但发现徒劳无功;
所以,GDB的调试优势就出来了,通过打断点break,进行快速定位。
这里将GDB调试的几个技巧总结如下:
1)需要调试的软件源码包在编译时需要加上-g
选项,同时扩大编译范围-O0
。
CFLAGS='-O0 -g -march=loongson3a -mabi=64 -Wall '
export CFLAGS
2)当bug修改周期很长,此时应该将bug的断点和gdb配置优化保存在指定文件,如~/caja-break。
在下一次的调试开始,可以加载当前断点配置文件,达到快速复盘调试环境。
保存当前断点
save breakpoints ~/caja-break
gdb中加载当前断点文件
source ~/caja-break
3)添加断点最好的情况就是在复现你的问题中时断在了你的断点上,而且不是频繁断在这边。
当不同操作频繁断在指定函数时,如report_copy_progress
,那么就应该bt
查看函数调用栈。
通过函数调用栈进行将调用report_copy_progress
的函数进行添加断点。
4)不需要使用一些前端GDB,如insight,经过试验后对于第三方库文件中的变量,命令行
没法print
查看变量的前提下,insight也没法打开。也就是insight只是一个gdb的前端封装,
命令行gdb没法实现的,通过前端也没法实现,所以不需要过分依赖。某种程度来说,前端是现象,
后端是本质。
三、调试lightdm
set print pretty on
break get_users_cb
参考:lightdm
-------------------------------------------
Wish you all the best and good health in 2021.