gdb查coredump问题流水账

 

1,前言

如果c++发生了coredump,该怎么办。写c++项目很是头疼的是碰到c++的coredump,程序终止的时候留的信息很有限,不知道怎么查找问题。

 

 

2,GDB介绍

一直想了解GDB是怎么使用的却没怎么深入了解,只是简单熟悉了gdb的简单使用命令,比如辅助来打断点,熟悉代码调用栈的作用。

(1),gdb启动调试

如果需要调试可执行文件,gdb exefilename.out 进入调试模式来跑,静态方式。

如果需要对某个正在运行中的进程进行调试,则 gdb -p pid,或者 gdb attach pid 的方式

 

(2),gdb设置断点

break(b) linenum 是 针对当前文件的第几行进行断点,如果多个文件要到其他文件下断点,使用 b filename:linenum 则是到指定文件名下断点

break(b) function;     break(b) class::function;    break(b) class::function(type, type)  都是在函数入口进行断点

info b 可以查看当前所有标记了的断点

delete bnumber  可以删除指定的断点,其中bnumber是断点号,delete则是删掉所有的断点

disable/enable bnumber 可以禁用/启用指定的断点

 

(3),gdb打印

p variable 打印当前的变量,区分不同的格式 p /x a 是按照十六进制的方式来输出a变量; p /d a 是按照十进制的方式来输出a变量

在打印数组时,可以设置打印数组的个数 set print elements 0 (不限制打印数量)

选择打印数组的范围   print *(arr + start_index)@num 是打印数组arr从第start index起的num个数组元素的内容

x address 打印地址内容,x/nfu address,其中n是输出单元个数,f输出格式(如x是16进制,类似print格式),u是表明一个单元的长度(如b是一个byte,h是两个byte,w是四个byte,g是八个byte)

举个例子的是 x /16xb arr 的方式是在arr地址开始以16进制打印16个字节

 

(4),gdb调试命令

backtrace(bt) 显示当前执行的堆栈信息, bt full 加个full则显示所有参数信息

step(s) 调入下一步的单步调试命令,有函数会进入函数调用

next(n) 单步跟踪,有函数则不会进入函数调用

frame(f) n 是切换当前的栈帧,n是对应的bt里面的栈帧的序号

info(i) frame 打印当前的栈帧信息

info(i) locals 打印当前栈帧的局部变量

info registers 打印寄存器信息(除了浮点数寄存器)  info all-registers 打印所有寄存器信息 

info threads 打印当前正在运行的线程信息

watch expression ,可以是整型变量,也可以是指针变量, 

info watch 则可以查看所有的观察点

list 则可以展示源代码,disassemble func 查看函数执行的汇编码

 

 

3,gdb调试coredump步骤

(1),如果程序coredump没有产生coredump文件,需要设置系统设置的core dump文件大小,命令:ulimit -c number 

 

(2),对生成的coredump文件,用gdb进去,命令: gdb coredump exefile.out

 

(3),查看当前的栈信息,info locals 可以打印所有的局部变量的信息

可以发现一个AClass类的局部变量, 怀疑是内存写坏了的问题,打印该类的指针: p AClassPoint  输出该类的地址为 0xff1234

然后 x /16xg 0xff1234 可以看看该类的内存信息

因为 AClass 是一个虚类,发现打印的首地址是 0x0000b ,显然该地址不是一个正确的指向虚函数的虚表地址

那么,可以推断为该类的内存地址被写坏 

 

(4),分析内存地址被写坏的可能性

典型的错误有 悬空指针裸写,数组越界写坏,被free后使用,等等情况

 

posted @ 2024-01-21 12:12  zhang--yd  阅读(42)  评论(0编辑  收藏  举报