记录一次gdb查找core dumped错误并解决
在项目LinuxServerMonitor实现过程中,出现了很多问题,有一个问题是,项目编译成功之后,运行时却没能正确运行,终端打印了如下错误:
Segmentation fault (core dumped)
出现了错误,就要解决错误,首先我查找了代码中的逻辑问题,并结合gpt进行了进一步的优化,编译之后运行仍然报错。之前学习过使用gdb进行core dumped文件定位错误,但一直没有真正的实践过。于是就准备通过gdb来找到错误。
一、开启debug模式
使用CMake进行项目编译时,默认是不开启debug模式的,所以需要在项目的顶层Cmakelists.txt文件中开启debug模式,如下:
# 开启调试模式(默认关闭优化)
set(CMAKE_BUILD_TYPE Debug)
# 强制添加调试符号(即使在Release模式也生效)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0") # -O0 关闭优化,确保调试时代码与源码对应
二、安装gdb
因为我是在docker环境中配置的开发环境,在创建镜像时没有安装gdb,所以需要在Dockerfile中添apt-get update
apt-get install gdb
,然后重新创建镜像和容器;为了方便,我是直接在容器中安装了:
apt-get update
apt-get install gdb
三、使用gdb找出错误
上述准备好后,重新编译项目,并使用gbd运行编译出的可执行文件:
gdb ./display # 启动gdb调试
(gdb) run # 启动程序
# 程序崩溃后,输入以下命令获取调用栈
(gdb) backtrace # 简写 bt,显示函数调用栈,定位错误发生的函数和行号
(gdb) frame N # 切换到第N个栈帧(N是bt输出的编号),查看该帧的变量和代码
(gdb) print var # 打印变量var的值,排查是否有无效值(如空指针)
终端中打印了如下错误:
root@DESKTOP-AGG7M97:/work/build/bin# ./display
QStandardPaths: runtime directory '/run/user/1000/' is not owned by UID 0, but a directory permissions 0755 owned by UID 1000 GID 1000
主机名:xuwenke
ASSERT failure in QList<T>::operator[]: "index out of range", file /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h, line 575
Aborted (core dumped)
root@DESKTOP-AGG7M97:/work/build/bin# gdb ./display
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.3) 12.1
Copyright (C) 2022 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 "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://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 <RET> for more, q to quit, c to continue without paging--
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./display...
(gdb) run
Starting program: /work/build/bin/display
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff2a00640 (LWP 516)]
QStandardPaths: runtime directory '/run/user/1000/' is not owned by UID 0, but a directory permissions 0755 owned by UID 1000 GID 1000
[New Thread 0x7ffff213d640 (LWP 517)]
[New Thread 0x7ffff193c640 (LWP 518)]
[New Thread 0x7ffff113b640 (LWP 519)]
主机名:xuwenke
[New Thread 0x7ffff093a640 (LWP 520)]
[Detaching after fork from child process 521]
ASSERT failure in QList<T>::operator[]: "index out of range", file /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h, line 575
Thread 1 "display" received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737270923648) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
(gdb) backtrace
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737270923648) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=6, threadid=140737270923648) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=140737270923648, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3 0x00007ffff64ea476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007ffff64d07f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007ffff69afba3 in QMessageLogger::fatal(char const*, ...) const () from /lib/x86_64-linux-gnu/libQt5Core.so.5
#6 0x00007ffff69af052 in qt_assert_x(char const*, char const*, char const*, int) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
#7 0x000055555556cdd6 in QList<QString>::operator[] (this=0x5555556f28d0, i=5) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:575
#8 0x000055555556ef10 in monitor::QCpuLoadModel::headerData (this=0x5555556f2860, section=5, orientation=Qt::Horizontal, role=0) at /work/display/src/QCpuLoadModel.cpp:38
#9 0x00007ffff7cf3511 in QHeaderView::sectionSizeFromContents(int) const () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#10 0x00007ffff7ce4648 in QHeaderView::sizeHint() const () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#11 0x00007ffff7d337fd in QTableView::updateGeometries() () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#12 0x00007ffff7d29b28 in QTableView::columnCountChanged(int, int) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x00007ffff6c107c8 in ?? () from /lib/x86_64-linux-gnu/libQt5Core.so.5
#14 0x00007ffff7ce3eb3 in QHeaderView::sectionCountChanged(int, int) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#15 0x00007ffff7ce81af in QHeaderView::initializeSections(int, int) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#16 0x00007ffff7cec395 in QHeaderView::initializeSections() () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#17 0x00007ffff7cf114e in QHeaderView::reset() () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#18 0x00007ffff7cf0e16 in QHeaderView::setModel(QAbstractItemModel*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#19 0x00007ffff7d334d0 in QTableView::setModel(QAbstractItemModel*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#20 0x000055555557074e in monitor::QMonitorMainWidget::initCpuMonitorWidget (this=0x7fffffffe430) at /work/display/src/QMonitorMainWidget.cpp:66
#21 0x0000555555570223 in monitor::QMonitorMainWidget::QMonitorMainWidget (this=0x7fffffffe430, name="xuwenke", parent=0x0) at /work/display/src/QMonitorMainWidget.cpp:11
#22 0x0000555555569960 in main (argc=1, argv=0x7fffffffe608) at /work/display/display.cpp:42
根据调用栈(backtrace
)信息:
#7 QList<QString>::operator[] (this=0x5555556f28d0, i=5) // 尝试访问索引5
#8 monitor::QCpuLoadModel::headerData (section=5, ...) // 在headerData函数中
QCpuLoadModel
是自定义的表格模型(继承自QAbstractTableModel
),用于提供表格的表头和数据。headerData
函数的作用是返回指定列(section
)的表头文本,此处section=5
表示尝试获取第 6 列的表头,但存储表头的QList<QString>
中没有足够的元素(可能只有≤5 列的表头),导致越界。
根据信息修改错误即可。
记录一次gdb查找core dumped错误并解决
http://47.92.222.121:8090/archives/2bVFxPls