1、什么是coredump
Coredump(核心转储)是操作系统在程序异常终止(例如由于段错误或其他严重错误)时创建的一种文件。这个文件包含了程序崩溃时刻进程的内存镜像,通常还包括程序计数器、寄存器内容和堆栈内存等信息,文件比较大。Coredump 文件的主要用途是帮助开发者在程序崩溃后进行调试,以确定导致崩溃的原因。
2、linux常见造成coredump的信号
- SIGQUIT (3):用户通过Ctrl+\发送的退出信号,通常会导致程序终止并生成core dump
- SIGILL (4):执行非法指令时发生,如尝试执行非法的机器语言指令或者损坏的代码,通常会导致程序终止并生成core dump
- SIGTRAP (5):由断点或其他陷阱触发的信号,常在调试过程中使用,会导致程序终止并生成core dump
- SIGABRT (6):由abort()系统调用产生,通常用于处理严重错误(如断言失败),导致程序终止并生成core dump
- SIGFPE (8):发生致命的算术错误,例如除以零或算术溢出等,通常会导致程序终止并生成core dump
- SIGSEGV (11):无效的内存引用或段错误,例如访问未分配的内存,通常会导致程序终止并生成core dump
- SIGBUS (7):硬件故障导致的无效内存访问,如对齐错误等,通常会导致程序终止并生成core dump
- SIGSYS (31):非法的系统调用,通常会导致程序终止并生成core dump。
3、调试 步骤
3.1 生成coredump文件
// 查看core文件储存位置
$ cat /proc/sys/kernel/core_pattern
// 临时更改路径:
$ echo '/path/to/coredumps/core.%e.%p.%h.%t' | sudo tee /proc/sys/kernel/core_pattern
// 这里的/path/to/coredumps/是你希望存放core dump文件的目录。%e、%p、%h、%t是可选的格式化选
// 项,分别代表可执行文件的名称、进程ID、主机名和时间戳。
// 永久更改路径
// 永久更改需要编辑/etc/sysctl.conf文件,或者在/etc/sysctl.d/目录下创建一个新文件。
// 在文件中添加或修改以下行
$ kernel.core_pattern=/path/to/coredumps/core.%e.%p.%h.%t
// 然后运行以下命令来应用更改
$ sudo sysctl -p
注意:不建议永久更改,临时操作完后,即能恢复原来状态
3.2 更改生成文件大小
// 查看当前限制:运行 ulimit -a 会显示所有的资源限制。
$ ulimit -a
// ulimit -c [size]
// size 单位为KB
// 要将 core dump 限制设置为无限制,可以运行:
$ ulimit -c unlimited
3.3 准备崩溃程序
测试程序名:test
// 头文件 widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void do_it();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
// 源文件 widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <stdio.h>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::do_it()
{
//定义一个字符指针变量a,指向地址1.这个地址肯定不是自己可以访问的,但是这行不会产生段错误。
char* p="1";
//视图更改地址1出的值,内核会终止该进程,并把core文件dump出来。
*p='a';
}
// 主程序 main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.do_it();
w.show();
return a.exec();
}
使用debug编译,生成可执行程序:
// 执行该程序,出现段错误,并在相应目录下生成core文件
$ sudo ./test
注意:确认文件是不是core文件方法
3.4 gdb调试崩溃程序
// 使用gdb调试
$ sudo gdb test /path/to/coredumps/core.%e.%p.%h.%t