GDB调试

一、什么是GDB

gdb是GNU debugger的缩写,是编程调试工具。

功能:

  • 启动程序,可以按照用户自定义的要求随心所欲的运行程序。

  • 可让被调试的程序在用户所指定的调试断点处停住(断点可以是条件表达式)。

  • 当程序停住时,可以检查此时程序中所发生的事。比如,可以打印变量的值。

  • 动态改变变量程序的执行环境。

二、段错误

段错误是由于访问非法地址而产生的错误。

产生原因:

1.内存访问越界

a) 由于使用错误的下标,导致数组访问越界

b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符

c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。

2 多线程程序使用了线程不安全的函数。

3 多线程读写的数据未加锁保护。对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump

4 非法指针

a) 使用空指针

b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型 的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它 时就很容易因为bus error而core dump.

5 堆栈溢出.不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。

三、core文件

在程序崩溃时,一般会生成一个文件叫core文件。core文件记录的是程序崩溃时的内存映像,并加入调试信息,core文件生成过程叫做core dump(核心已转储)。系统默认不会生成该文件。

发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行.

gdb [exec file] [core file]

进入gdb后, 用bt命令查看backtrace以检查发生程序运行到哪里, 来定位core文件->行.

GDB中键入where,也会看到程序崩溃时堆栈信息(当前函数之前的所有已调用函数的列表(包括当前函数),gdb只显示最近几个)

四、配置

1、可以将core文件统一生成到/corefile目录下,产生的文件名为core-命令名-pid-时间戳

sudo sh -c 'echo "/corefile/core-%e-%p-%t" >/proc/sys/kernel/core_pattern'

%p - insert pid into filename 添加pid

%u - insert current uid into filename 添加当前uid

%g - insert current gid into filename 添加当前gid

%s - insert signal that caused the coredump into the filename 添加导致产生core的信号

%t - insert UNIX time that the coredump occurred into filename 添加core文件生成的unix时间

%h - insert hostname where the coredump happened into filename 添加主机名

%e - insert coredumping executable name into filename 添加命令名

2、/proc/sys/kernel/core_uses_pid可以控制core文件的问价名是否添加PID作为扩展,文件的内容为1,标识添加PID作为扩展,生成的core文件格式为core.XXXX;为0则表示生成的core文件统一命名为core

sudo sh -c 'echo "1" > /proc/sys/kernel/core_uses_pid'

3、在.bash_profile和/etc/profile文件末尾添加

ulimit -c unlimited