用GDB调试core文件

用GDB调试core文件

1、先让你的项目编译的时候就按debug的方式构建

image-20250330224132968

2、重新编译你的程序

image-20250330224235139

3、运行程序让它生成core文件,这个默认是关闭的,需要手动开启

image-20250330224330782

这个默认是关闭的,需要手动开启,先查看core dump是否被禁用了,0就是禁用了

ulimit -c

image-20250330224445670

开启

ulimit -c unlimited

4、查看core文件生成的位置

cat /proc/sys/kernel/core_pattern

image-20250330224815270

表明 core dump 不是直接写入文件,而是被 apport 处理了。apport 是 Ubuntu 的崩溃报告工具,它会拦截 core dump 并生成自己的崩溃日志,而不会在当前目录下生成 core 文件。

可以临时禁用apport

sudo systemctl stop apport
echo "core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern

5、调试core文件

image-20250330225124214

gdb ./main core

image-20250330225322733

查看完整堆栈情况

bt full

image-20250330225750550

bt full 显示崩溃发生在:

#0  0x000073e589ac5046 in operator() (__closure=0x56c4997c7e80) at /code/CHAT/Utils/DataBaseManager/DBManager.cpp:58

这个 operator() 是一个 std::function<void(MYSQL_RES*)> 绑定的 Lambda,在 DBManager::excuteQuery 里被调用了。

这里的关键点是这里:

image-20250330230035510

M_functor 里 _M_object 是 0x0,意味着 Lambda 可能在 std::function<void(MYSQL_RES*)> 里被调用时已经 指向了一个空对象。

_M_invoker 指向 0x73e589ad6b67,但 _M_functor._M_object == 0x0,说明 std::function<void(MYSQL_RES*)> 可能已经被析构或未初始化。

这个时候我们可以检查一下,看看这个玩意是不是真的已经指向空对象了

p callback

image-20250330230245385

结果确实如此

image-20250330230308651

6、将函数修改为专为异步而生的future对象

image-20250402201619214

重新修改运行发现问题解决了

image-20250402201643503

之前的问题我还是认为是生命周期有问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值