linux 调试系列(二)coredump段错误查找使用详解

《linux 调试系列(一)coredump环境配置》
《linux 调试系列(二)coredump段错误查找使用详解》


一、 背景

这一节,通过一个样例,详细介绍怎么使用coredump来定位程序段错误。
构造两个常用错误,缓冲区溢出和非法指针引用。

二、非法指针样例程序

  • 测试程序
#include <stdio.h>
#include <string.h>

/** 
 * [buf_overflow 缓冲区溢出]
 * @author	hayson <haixing9@qq.com>
 * @date	2023-03-24 08:28
 */
void buf_overflow(){
	char data[8] = {0x0};
    strcpy(data, "hello world! hello world! hello world!hello world!hello world!hello world!");
}

/** 
 * [illegal_pointer 非法指针引用]
 * @author	hayson <haixing9@qq.com>
 * @date	2023-03-24 08:28
 * @param                     [description]
 */
void illegal_pointer(){
	char *data = NULL;
	strcpy(data, "hello world! hello world! hello world!hello world!hello world!hello world!");
}

int main(int argc, char** argv){

	int input = 0;
	if(argc == 2)
		input = atoi(argv[1]);
	if(input)
		buf_overflow();
	else
		illegal_pointer();
	
    return 0;
}

  • 编译

编译记得带上-g调试信息

gcc -o test test.c -g 

三、调试程序

非法指针测试

  1. 运行程序,生成coredump文件
$ ./test_core 
Segmentation fault (core dumped)
$ ls
core.test_core.7568  Makefile  src  test_core

我们能看到生成了core.test_core.756文件。
2. gdb 运行调试定位
首先gdb运行程序载入程序函数符号表

gdb ./test_core 
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test_core...

然后继续在gdb环境内输入core-file 命令载入刚刚的coredump文件。

(gdb) core-file core.test_core.7568 
[New LWP 7568]
Core was generated by `./test_core'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000aaaadb3908d4 in illegal_pointer () at src/test_illegal.c:22
22              strcpy(data, "hello world! hello world! hello world!hello world!hello world!hello world!");
(gdb) quit

以上信息,我们可以看到进程收到了一个SIGSEGV信号,段错误退出了,在22行,SIGSEGV信号的默认处理动作是终止进程,并进行coredump,这就是我们程序退出的全部原因

缓冲区溢出测试

  1. 运行程序,生成coredump文件
$ ./test_core 1
*** stack smashing detected ***: terminated
Aborted (core dumped)
$ ls
core.test_core.7568  core.test_core.7623  Makefile  src  test_core

core.test_core.7623即core文件
2. gdb 运行调试定位

$ gdb test_core 
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test_core...
(gdb) core-file core.test_core.7623 
[New LWP 7623]
Core was generated by `./test_core 1'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) 

我们能看到程序收到了SIGABRT信号aborted,但并没有真正指向错误处。
继续查询栈内容

 (gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x0000ffffbe9daaac in __GI_abort () at abort.c:79
#2  0x0000ffffbea27f40 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0xffffbeae7ff0 "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:155
#3  0x0000ffffbea9a4c8 in __GI___fortify_fail (msg=msg@entry=0xffffbeae7fd8 "stack smashing detected") at fortify_fail.c:26
#4  0x0000ffffbea9a49c in __stack_chk_fail () at stack_chk_fail.c:24
#5  0x0000aaaade5508b0 in buf_overflow () at src/test_illegal.c:12
#6  0x0000aaaade550950 in main (argc=1819438967, argv=0x656821646c726f77) at src/test_illegal.c:31
(gdb) 

到这里,我们就能看出,错误是一个__stack_chk_fail,字面堆栈检测错误,继续往下看

 0x0000aaaade5508b0 in buf_overflow () at src/test_illegal.c:12

这里就明确指出来了出错位置,这是一个典型的缓冲区使用不当造成的栈溢出。

信号类型说明

在这里插入图片描述

处理动作一项中的字母含义如下
A 缺省的动作是终止进程。
B 缺省的动作是忽略此信号,将该信号丢弃,不做处理。
C 缺省的动作是终止进程并进行内核映像转储(core dump),内核映像转储是指将进程数据在内存的映像和进程在内核结构中的部分内容以一定格式转储到文件系统,并且进程退出执行,这样做的好处是为程序员 提供了方便,使得他们可以得到进程当时执行时的数据值,允许他们确定转储的原因,并且可以调试他们的程序。

D 缺省的动作是停止进程,进入停止状况以后还能重新进行下去。
E 信号不能被捕获。
F 信号不能被忽略。

工程

最后,附上源码工程github地址:

git clone https://github.com/hayson/coredump_sample.git

参考

Linux实用gdb结合coredump定位崩溃进程
【Linux】GDB用法详解(5小时快速教程)
Linux程序coredump地址显示问号的调试方法 - 基于map文件

《Linux 信号的详细介绍和举例说明》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值