GDB调试 core dump 文件与栈溢出分析
文章目录
- 调试源码地址
- 打开 Core dump (核心转储)
- 段错误调试
- coredump1-section
- coredump2-section
调试源码地址
打开 Core dump (核心转储)
Core dump操作系统在程序异常终止(如崩溃、 segmentation fault 等)时,将程序当时的内存状态、寄存器信息、堆栈数据等关键信息保存到一个文件中的机制
首先再Ubuntu上咱们要先打开Core dump
通过ulimit -c这个命令可以看到当前core文件的大小是 0
在这个环境下我们编译一下coredump1-section里的会照成段错误的代码
int main()
{int *p = 0;*p = 10;// 试图对空指针进行解引用操作并赋值return 0;
}
可以看到生成了一个可执行文件,此时运行会报错Segmentation fault
并且可以看到没有生成任何core dump文件
此时可以通过命令ulimit -c unlimited设置core domp文件的大小为无限制
可以看到在生成段错误的时候后面还跟上了Segmentation fault (core dumped)
并且生成了core dump文件
可以通过命令
echo -e “%e-%p-%t” > /proc/sys/kernel/core_pattern
对core dump文件进行改名,默认都是只生成core命名的文件
段错误调试
打开自动生成core dump文件以后我们就可以开始进行调试啦
coredump1-section
通过命令 gdb + 可执行文件 + 对应文件生成的core dump文件名 即可开始调试
gbd ./coredump1-section coredump1-secti-14407-1754905207
运行后我们可以看到程序停在了12行
通过 gdb的命令 p p
(第一个p的意思是print 第二个p是指针)
可以看到p指针为空指针,那此时进行赋值肯定是有问题的
coredump2-section
接着我们看看第二个例子
void set_value(char* str,int num)
{str[num-1]='\0';
}
string get_file_list(int total_num,int size)
{string res;for(int i=0;i<total_num;i++){char *str = (char*)alloca(size);set_value(str,size);res = res + string(str);}return res;
}
int main(int argc,char** argv)
{string str = get_file_list(atoi(argv[1]),atoi(argv[2]));cout << "get file list completed" << endl;return 0;
}
一个简单的通过alloca申请空间并自动释放的例子
第一个参数表示生成多少个空间(调用多少次alloc)
第二个参数表示每次生成的空间的大小
通过图片可以看到当程序传参为
100 100
1000 1000
的时候都没出问题,但是参数为10000 1000的时候发生了段错误
会是空间分配失败导致的吗?
通过计算可得 10000 * 1000 / 1024 = 9537(M)(八字节对齐)
仅仅9兆,怎么可能会分配失败呢
调试一下看看
gdb ./coredump2-section coredump2-secti-15999-1754906708
可以看到,程序在19行的时候被段错误的信号中断了
通过 bt得知我们目前就在get_file_list函数栈里
通过i locals (这里的 i 表示Info)可以看到当前栈帧的变量
可以看到在 i (for循环里的变量)等于8314的时候str产生了不正常的内存访问
i = 8314
8314 * 1000(传参进来决定每块内存的大小) / 1024 = (约)8 M
通过命令也能看到我们的内存也还有很多,所以不可能是内存分配不够导致的
那我们就智能往上怀疑了因为19行的函数里什么都没有,这时就要看看alloca()函数的手册了
这时就能发现alloca分配的其实是栈空间!
通过命令!ulimit -a可以看到我们的栈空间大小只有8192kb
而8314 * 1000 /1024 = 8119
加上其他变量的空间,自然就爆栈了