当前位置:首页>Linux>不懂 Core Dump,别说你懂 Linux 程序崩溃排查

不懂 Core Dump,别说你懂 Linux 程序崩溃排查

  • 2026-06-29 12:52:28
不懂 Core Dump,别说你懂 Linux 程序崩溃排查

在 Linux 程序开发与运维中,程序崩溃是最常见也最棘手的问题——段错误、野指针、内存越界、栈溢出等底层异常,往往毫无征兆地导致服务闪退,日志中仅留下寥寥数语,常规排查手段根本无从下手。很多开发者自诩熟悉 Linux 程序调试,却在面对偶现崩溃、无日志报错的场景时束手无策,核心原因就是没吃透 Core Dump 这一核心排障工具。

Core Dump 作为程序崩溃瞬间的“内存快照”,能完整留存进程崩溃时的代码段、堆栈数据、寄存器状态与函数调用链路,是还原崩溃现场、定位根因的关键。不懂 Core Dump,就只能在崩溃问题前徘徊,无法触及底层故障本质;掌握 Core Dump 的开启、配置与分析方法,才能轻松破解各类疑难崩溃,真正吃透 Linux 程序崩溃排查的核心逻辑,筑牢后台开发与运维的技术根基。

一、初识 Core Dump

面试题写作模版

1.1 Core Dump 是什么?

Core Dump,中文常称为 “核心转储”,简单来说,它就是程序崩溃瞬间的 “内存快照” 。当程序因为各种异常情况,比如我们前面提到的段错误、野指针、内存越界、栈溢出等问题而异常终止时,操作系统会将此时进程的一系列关键信息保存到一个文件中,这个文件就是 Core Dump 文件。coredump 文件格式如图所示:

Core Dump 文件本质遵循标准 ELF 文件格式,整体由 ELF 头、程序头表、NOTE 段 和 LOAD 段 四部分组成,完整保存了进程崩溃时的关键运行信息,为问题定位提供核心依据。其中 ELF 头是 Core Dump 的文件描述头部,定义了文件类型、架构、程序头表偏移等基础元信息;程序头表用于描述文件中各个段的布局、加载地址和长度,是内核和调试工具解析 Core Dump 的索引;NOTE 段存储崩溃相关的关键元数据,包括进程崩溃原因、信号信息、进程 ID、时间戳等辅助信息;LOAD 段则是真正保存进程运行时内存镜像的核心区域。

具体来讲,LOAD 段中包含了进程崩溃时的代码段,也就是程序运行的实际指令集合,这些指令是程序功能实现的基础,通过分析代码段,可以了解程序在崩溃那一刻正在执行哪些操作。同时,LOAD 段还完整保存了堆栈数据,堆栈在程序运行中起着至关重要的作用,函数调用、局部变量存储等都依赖于堆栈,通过堆栈数据,我们能够清晰地看到函数的调用顺序和层次关系,从而追踪程序的执行路径。

NOTE 段与 LOAD 段共同记录了崩溃时的寄存器状态,寄存器是 CPU 内部的高速存储单元,保存着程序运行时的关键数据,如程序计数器(PC),它指示着下一条要执行的指令地址;栈指针(SP),用于管理堆栈的操作等,了解寄存器状态,能让我们深入知晓 CPU 在崩溃瞬间的工作状态。依托代码段、堆栈数据与寄存器信息,Core Dump 中的函数调用链路也被完整留存,它清晰地展示了从程序入口到崩溃点之间,各个函数是如何被调用的,这对于定位问题的根源非常关键。

可以说,Core Dump 文件就像是一份详细的程序崩溃现场报告,它将程序崩溃瞬间的所有关键信息都完整地保存下来,为我们后续分析问题提供了丰富的数据支持。

1.2 为什么 Core Dump 如此关键?

为了更直观地理解 Core Dump 的重要性,我们不妨对比一下没有 Core Dump 时排查问题的困难程度。当程序崩溃且没有 Core Dump 文件时,开发者往往只能对着那寥寥无几的日志信息干瞪眼,完全不知道从何下手。很多时候,只能凭借经验去盲目猜测可能的原因,然后对代码进行各种修改,反复进行测试。然而,这种方式效率极低,因为很多底层异常导致的崩溃是偶现的,很难通过简单的测试去复现问题。就像前面提到的电商平台后端服务崩溃的案例,如果没有 Core Dump,开发团队和运维团队可能会花费大量的时间去排查问题,不断地尝试各种可能的解决方案,但最终可能还是一无所获。

而当有了 Core Dump 之后,情况就完全不同了。我们可以借助调试工具,比如 GDB(GNU Debugger),加载 Core Dump 文件进行深入分析。通过分析,我们能够快速定位到崩溃发生的具体函数,查看函数调用栈,了解函数之间的调用关系,从而判断程序的执行流程是否正确。还可以查看崩溃时变量的状态,比如某个指针是否为空,数组是否越界访问等,这些信息都能帮助我们迅速找到问题的根源。有了 Core Dump,就像是在黑暗中找到了一盏明灯,让我们能够快速、准确地定位问题,极大地提高了排查问题的效率,节省了大量的时间和精力。

1.3 从内核看 coredump 文件生成过程

coredump 文件生成过程包含以下几个步骤:

  • 步骤 1:程序触发致命信号,程序执行非法操作(如段错误、总线错误、除零或主动中止)时,会触发 CPU 硬件异常并由操作系统内核向进程发送相应信号。
  • 步骤 2:内核处理信号并终止进程,内核在向目标进程递送信号后会立即冻结该进程以保持状态稳定,随后按照默认处理方式终止该进程并生成核心转储文件。
  • 步骤 3:写入 Coredump 文件,内核会在进程工作目录创建核心转储文件(通常命名为 core 或 core.<pid>),完整记录崩溃时的进程虚拟地址空间、CPU 寄存器状态、线程信息、信号详情及相关元数据。
  • 步骤 4:资源清理与进程终止,在 Coredump 文件成功写入后,内核会回收该进程占用的所有剩余资源(包括内存、文件描述符、信号量等),并最终将该进程完全从系统中移除。

我们可以通过下面这张图来直观理解 coredump 文件的生成过程:

(1)信号处理阶段——do_signal 函数。当进程从内核态返回用户态之前,内核会仔细检查进程的信号队列,查看是否存在未处理的信号。这就好比一个快递员在送完所有快递后,会检查自己的包裹清单,看看是否有遗漏的快递。如果发现有未处理的信号,内核就会调用 do_signal 函数来处理这些信号。

do_signal 函数在整个 coredump 文件生成过程中扮演着关键的角色,它主要调用 get_signal_to_deliver 函数来获取需要处理的信号,并根据信号的类型和相关设置进行后续处理。下面是一段简化的 do_signal 函数代码示例(基于 Linux 内核源码,实际代码更为复杂,这里仅为展示关键逻辑):

staticvoid fastcall do_signal(struct pt_regs *regs){    siginfo_t info;int signr;    struct k_sigaction ka;    sigset_t *oldset;// 调用 get_signal_to_deliver 函数获取信号    signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) {// 处理信号的逻辑// 这里可能会根据信号类型进行不同操作,比如生成 coredump 文件等    }}

在这段代码中,get_signal_to_deliver 函数的返回值 signr 表示获取到的信号。如果 signr 大于 0,说明获取到了有效的信号,接下来就会进入处理信号的逻辑。在实际的内核代码中,这个处理过程涉及到复杂的信号处理机制,包括信号的屏蔽、恢复,以及根据信号类型执行相应的操作。

(2)获取信号阶段——get_signal_to_deliver 函数。get_signal_to_deliver 函数的主要任务是从进程的信号队列中获取一个信号,并根据信号的类型进行不同的操作。它就像是从一个装满各种信号 “包裹” 的仓库中,挑选出需要处理的 “包裹”。

这个函数会遍历进程的信号队列,检查每个信号的状态和属性。对于一些特殊的信号,比如 SIGKILL(用于强制终止进程),会直接在内核态进行处理,不会生成 coredump 文件。而对于那些会导致进程异常退出并生成 coredump 文件的信号,如 SIGSEGV(段错误信号)、SIGABRT(异常终止信号)等,get_signal_to_deliver 函数会进行相应的处理,为生成 coredump 文件做准备。

下面是一段 get_signal_to_deliver 函数的关键代码分析(同样是简化后的代码,用于展示核心逻辑):

intget_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,struct pt_regs *regs, void *cookie){    sigset_t *mask = &current->blocked;int signr = 0;// 循环从信号队列中获取信号while ((signr = dequeue_signal(mask, &current->pending)) ||           (signr = dequeue_signal(mask, &current->shared_pending))) {        struct sigpending *pending;        struct sigqueue *q;// 获取信号对应的 sigqueue        q = find_signal_queue(signr, &current->pending);if (!q)            q = find_signal_queue(signr, &current->shared_pending);// 填充信号信息        *info = q->info;        *return_ka = current->sigaction[signr - 1];// 处理与 coredump 相关的信号逻辑if (should_generate_coredump(signr)) {// 进行生成 coredump 文件的前期准备工作            prepare_coredump();        }// 其他信号处理逻辑return signr;    }return0;}

在这段代码中,通过 dequeue_signal 函数从进程的私有信号队列 current->pending 和共享信号队列 current->shared_pending 中获取信号。如果获取到信号,就会找到对应的 sigqueue,填充信号信息到 info 和 return_ka 中。对于那些需要生成 coredump 文件的信号(通过 should_generate_coredump 函数判断),会调用 prepare_coredump 函数进行前期准备工作,例如初始化一些与 coredump 生成相关的数据结构、检查系统配置等 。

(3)内存信息记录阶段——当内核确定要生成 coredump 文件后,就会开始根据进程当时的内存信息来生成这个文件。这一步就像是给进程的内存状态拍一张 “照片”,然后把这张 “照片” 保存到 coredump 文件中。coredump 文件本质上是一个 ELF 格式的文件,它主要包含两种类型的 segment:PT_NOTE 和 PT_LOAD。

PT_NOTE 类型的 segment 记录了解析 memory 区域的关键信息。它被分成了多个 elf_note 结构,其中 NT_PRSTATUS 类型记录了复位前 CPU 的寄存器信息,这些信息对于分析程序崩溃时的 CPU 状态非常重要,就像是记录了相机拍摄瞬间的各种参数设置;NT_TASKSTRUCT 记录了进程的 task_struct 信息,包含了进程的各种属性和状态;还有一个自定义的 VMCOREINFO 结构记录了内核的一些关键信息,比如内核版本、编译选项等,这些信息为分析提供了更多的上下文。

PT_LOAD 类型的 segment 则用于记录进程的内存内容,每个 segment 对应一段内存区域,记录了这段内存对应的物理地址、虚拟地址、长度以及访问权限(读、写、执行等)。这些信息是通过遍历进程中的每个虚拟内存区域(VMA,Virtual Memory Area)来设置的,然后将 VMA 的内容写入到 coredump 文件中。例如,进程的堆、栈、数据段等都会在 PT_LOAD 类型的 segment 中有所体现,它们就像是照片中的各种物体,展示了程序运行时的内存布局情况。

通过这一系列的步骤,内核就完成了 coredump 文件的生成,为后续的程序调试和问题分析提供了重要的依据。

二、Core Dump 的生成机制

面试题写作模版

2.1 触发 Core Dump 的常见信号

在程序运行过程中,当遭遇一些异常情况时,操作系统会向进程发送特定信号,其中部分信号能触发 Core Dump,帮我们记录程序崩溃瞬间的关键信息 。

SIGSEGV 信号,也就是非法内存访问信号,是触发 Core Dump 的常见原因之一。当程序尝试访问未分配的内存、访问已释放的内存,或是越界访问数组等,就会触发这个信号。比如下面这段 C 语言代码:

#include <stdio.h>intmain(){int arr[10];// 访问数组越界,会触发 SIGSEGV 信号,进而引发 Core Dump    arr[100] = 10return0;}

在这个例子里,数组 arr 的有效下标范围是 0 到 9,而代码中尝试访问 arr[100],这显然超出了数组边界,访问了非法内存区域,从而触发 SIGSEGV 信号,使程序崩溃并生成 Core Dump 文件 。

SIGABRT 信号也常触发 Core Dump。调用 abort 函数,或者断言失败时,就会产生这个信号。例如:

#include <stdio.h>#include <assert.h>intmain(){int num = 0;// 断言失败,会触发 SIGABRT 信号assert(num != 0); // 主动调用 abort 函数,同样会触发 SIGABRT 信号    abort(); return0;}

在上述代码中,assert(num != 0)这句断言,由于 num 的值为 0,断言条件不成立,会触发 SIGABRT 信号;而 abort()函数被调用时,也会立即向进程发送 SIGABRT 信号,导致程序异常终止并生成 Core Dump 文件 。还有 SIGFPE 信号,即致命算术运算错误信号。像除零错误、溢出等算术运算错误,都会引发这个信号。看下面的示例:

#include <stdio.h>intmain(){int a = 10;int b = 0;// 除零操作,会触发 SIGFPE 信号int result = a / b; return0;}

这里 a / b 进行除零运算,违反了数学规则,触发 SIGFPE 信号,程序崩溃并生成 Core Dump,方便我们排查算术运算错误。

2.2 快速配置,一键开启Core Dump(简单提一下,后面详解讲解)

要让程序崩溃时顺利生成 Core Dump 文件,系统配置很关键。首先,得设置 Core 文件大小上限,这可以用 ulimit -c 命令来实现。比如在终端输入 ulimit -c 1024,这就把 Core 文件大小上限设为 1024KB 了 。如果想不限制 Core 文件大小,让程序能完整记录崩溃时的所有信息,就设置成 ulimit -c unlimited。像一些大型程序,崩溃时产生的信息较多,只有不限制大小,才能保证关键信息不丢失 。

程序运行目录的写权限也很重要。因为默认情况下,Core 文件会生成在程序运行目录,如果这个目录没有写权限,就无法生成 Core 文件。比如用普通用户运行程序,而程序运行目录的所有者是 root,且没有给普通用户写权限,就会出现这种情况。这时,要么修改目录权限,让程序运行用户有写权限,要么调整 Core 文件生成路径 。

另外,/proc/sys/kernel/core_pattern 这个文件也影响 Core 文件的生成。它决定了 Core 文件的生成路径和命名规则。默认值一般是 core,表示在当前目录生成名为 core 的文件。要是想修改生成路径和命名规则,可以通过修改这个文件内容来实现。比如想把 Core 文件生成到/data/core 目录下,文件名包含程序名、进程 ID 和时间戳,就可以执行 echo "/data/core/core.%e.%p.%t" > /proc/sys/kernel/core_pattern。这样,当程序崩溃时,就会在/data/core 目录下生成类似 core.my_program.1234.1619234567 的文件,方便管理和查找 。

三、引发 Core Dump 的常见原因

面试题写作模版

3.1 内存访问错误

(1)空指针或野指针解引用:在 C/C++ 等语言中,空指针是指未指向任何有效内存地址的指针,野指针则是指向一块已经释放或者从未被初始化的内存区域的指针。当对空指针或野指针进行解引用操作时,就相当于在访问一块无效的内存,这会触发 SIGSEGV 信号,导致程序崩溃并生成 Core Dump。比如在下面这段 C++ 代码中:

#include <iostream>intmain(){int *ptr = nullptr;    *ptr = 10// 解引用空指针,会触发 SIGSEGV 信号return0;}

运行这段代码,程序会因为访问空指针而接收到 SIGSEGV 信号,进而产生 Core Dump。

(2)缓冲区溢出:当我们向一个数组或缓冲区写入超出其大小的数据时,就会发生缓冲区溢出。这不仅会覆盖相邻的内存区域,破坏其他数据的完整性,还可能导致程序执行到非法的内存地址,引发 SIGSEGV 信号,最终造成 Core Dump。以下面的 C 语言代码为例:

#include <stdio.h>intmain(){char buffer[10];// 试图向 buffer 中写入长度为 15 的字符串,会导致缓冲区溢出    strcpy(buffer, "123456789012345"); return0;}

这里使用 strcpy 函数向长度为 10 的 buffer 数组中写入长度为 15 的字符串,会造成缓冲区溢出,程序很可能会崩溃并生成 Core Dump。

3.2 信号未正确处理

在程序运行过程中,会收到各种各样的信号。其中一些关键信号,如果没有被程序捕获并进行特殊处理,它们的默认行为就是终止进程并生成 Core Dump 。

  • (1)SIGSEGV前面已经多次提到,这个信号代表段错误,主要是由于非法内存访问引发的。像访问空指针、数组越界、使用已释放的内存等操作,都会让程序收到 SIGSEGV 信号,若不捕获处理,就会导致 Core Dump。
  • (2)SIGABRT:通常由程序调用 abort 函数,或者断言(assert)失败时触发。比如在下面的代码中:
    #include <stdio.h>#include <assert.h>intmain(){int num = 0;assert(num > 0); // 断言失败,触发 SIGABRT 信号return0;}

由于 num 的值为 0,断言 assert(num > 0)失败,程序会收到 SIGABRT 信号,若未捕获此信号,就会产生 Core Dump。

(3)SIGFPE:该信号表示发生了致命的算术运算错误,例如除零操作。如下代码:

#include <stdio.h>intmain(){int a = 10;int b = 0;int c = a / b; // 除零操作,触发 SIGFPE 信号return0;}

这段代码进行了除零运算,会触发 SIGFPE 信号,在未捕获处理的情况下,程序会终止并生成 Core Dump。

3.3 资源限制与配置问题

在 Linux 系统中,ulimit -c 用于设置 Core 文件大小的上限。如果这个值被设置为 0(默认情况下可能如此),那么即使程序崩溃触发了 Core Dump 的生成条件,也不会产生 Core 文件。只有将 ulimit -c 设置为一个大于 0 的值,或者设置为 unlimited(不限制大小),程序崩溃时才有可能生成 Core Dump 文件。比如,在终端中执行 ulimit -c 1024,表示将 Core 文件大小上限设置为 1024KB ,若程序崩溃产生的 Core 文件大小超过这个限制,可能无法完整生成。

当程序崩溃需要生成 Core Dump 文件时,如果磁盘空间不足,文件无法成功写入,也就无法生成有效的 Core Dump 文件。假设磁盘剩余空间只有 10MB,而程序崩溃时产生的 Core 文件预计大小为 20MB,那么就无法生成该 Core 文件,这会给我们后续调试程序带来困难。

程序必须对生成 Core Dump 文件的目标路径具有写权限。例如,若程序尝试在/var/core 目录下生成 Core 文件,但该程序运行的用户对/var/core 目录没有写权限,就无法成功生成 Core Dump 文件。只有确保程序对目标路径有正确的读写权限,才能顺利生成 Core 文件,以便后续分析调试。

3.4 多线程问题

在多线程环境下,程序的执行流程变得更加复杂,一些潜在的问题可能导致 Core Dump。

(1)竞态条件:当多个线程同时访问和修改共享资源,并且没有进行适当的同步控制时,就会出现竞态条件。这可能导致数据的不一致性,甚至程序崩溃并生成 Core Dump。比如,多个线程同时对一个全局变量进行读写操作,没有加锁保护:

#include <iostream>#include <thread>int sharedVariable = 0;voidincrement(){for (int i = 0; i < 1000; ++i) {        sharedVariable++; // 多个线程同时访问和修改,没有同步    }}intmain(){    std::thread thread1(increment);    std::thread thread2(increment);    thread1.join();    thread2.join();    std::cout << "Final value of sharedVariable: " << sharedVariable << std::endl;return0;}

在这段代码中,sharedVariable 是共享资源,increment 函数被两个线程同时调用,由于没有加锁等同步机制,可能会出现竞态条件,导致程序运行结果不确定,甚至可能引发 Core Dump。

(2)死锁:当两个或多个线程相互等待对方释放资源,形成一种僵持的状态,就发生了死锁。死锁会使程序无法继续执行,最终可能导致 Core Dump。以下是一个简单的死锁示例:

#include <iostream>#include <thread>#include <mutex>std::mutex mutex1;std::mutex mutex2;voidthreadFunction1(){    mutex1.lock();    std::this_thread::sleep_for(std::chrono::milliseconds(100));    mutex2.lock(); // 等待 mutex2,而 mutex2 被 threadFunction2 持有    mutex2.unlock();    mutex1.unlock();}voidthreadFunction2(){    mutex2.lock();    std::this_thread::sleep_for(std::chrono::milliseconds(100));    mutex1.lock(); // 等待 mutex1,而 mutex1 被 threadFunction1 持有    mutex1.unlock();    mutex2.unlock();}intmain(){    std::thread thread1(threadFunction1);    std::thread thread2(threadFunction2);    thread1.join();    thread2.join();return0;}

在这个例子中,threadFunction1 和 threadFunction2 相互等待对方持有的锁,形成死锁,程序会陷入停滞,最终可能崩溃产生 Core Dump。

3.5 动态内存管理错误

(1)双重释放:在 C/C++ 中,当对一块已经释放的内存再次调用释放函数(如 free 或 delete)时,就会发生双重释放。这是一种未定义行为,可能导致程序崩溃并生成 Core Dump。例如:

#include <stdio.h>#include <stdlib.h>intmain(){int *ptr = (int *)malloc(sizeof(int));    free(ptr);    free(ptr); // 双重释放,会导致未定义行为,可能引发 Core Dumpreturn0;}

这段代码中,ptr 指向的内存被释放了两次,这是非常危险的操作,极有可能导致程序出现异常,进而产生 Core Dump。

(2)内存泄漏:虽然内存泄漏本身不会直接导致 Core Dump,但随着程序的长时间运行,不断泄漏的内存会逐渐耗尽系统资源。当系统没有足够的内存供程序使用时,程序就可能会崩溃并生成 Core Dump。比如在下面的 C++ 代码中:

#include <iostream>voidmemoryLeakFunction(){while (true) {int *ptr = newint// 不断分配内存,但没有释放    }}intmain(){    memoryLeakFunction();return0;}

memoryLeakFunction 函数中不断使用 new 分配内存,却没有使用 delete 释放,随着循环的进行,内存会不断被消耗,最终可能导致程序因内存不足而崩溃,生成 Core Dump。

3.6 程序逻辑错误

(1)无限递归:当一个函数不断调用自身,没有终止条件时,就会发生无限递归。每一次递归调用都会在栈上分配新的空间,随着递归深度的增加,栈空间会被耗尽,导致栈溢出,进而引发 Core Dump。例如:

#include <stdio.h>voidrecursiveFunction(){    recursiveFunction(); // 无限递归,会导致栈溢出}intmain(){    recursiveFunction();return0;}

在这段代码中,recursiveFunction 函数没有任何终止条件,会一直递归调用自身,最终导致栈溢出,程序崩溃并生成 Core Dump。

(2)未捕获异常:在 C++ 等支持异常处理的语言中,如果程序抛出了异常,但没有在合适的地方捕获并处理它,异常会向上层传递。如果最终没有被捕获,程序就会异常终止,可能生成 Core Dump。例如:

#include <iostream>voidfunctionThatThrows(){throw1// 抛出异常}intmain(){try {        functionThatThrows();    } catch (...) {// 这里没有捕获到异常,异常会继续向上传递    }return0;}

在这段代码中,functionThatThrows 函数抛出了一个异常,但在 main 函数中没有被正确捕获,异常会导致程序异常终止,有很大概率生成 Core Dump。

3.7 硬件问题

虽然相对较少见,但硬件问题也可能引发 Core Dump。

  • 内存故障:当计算机的物理内存出现故障时,程序在访问内存时可能会出现错误。比如内存中的某些存储单元损坏,导致读取或写入数据时出现异常,这可能触发 SIGSEGV 等信号,进而使程序崩溃并生成 Core Dump。
  • CPU 异常:CPU 出现硬件故障或者过热等异常情况时,也可能影响程序的正常执行。例如,CPU 在执行指令时发生错误,无法正确处理程序的请求,这可能导致程序崩溃,生成 Core Dump 文件 。不过,这类由硬件问题导致的 Core Dump,排查起来相对困难,需要结合硬件检测工具来确定具体原因。

四、快速配置 Core Dump

面试题写作模版

4.1 检查与设置 ulimit 限制

在 Linux 系统中,默认情况下,可能会将 core 文件大小限制为 0,这就导致程序崩溃时不会生成任何转储文件 。所以,我们首先要做的就是检查并调整这个限制。这里就要用到 ulimit 命令,它是 Linux 系统中用于设置用户进程资源限制的重要工具。

临时设置 core 文件大小限制为无限制,可以在当前终端中执行 ulimit -c unlimited 。执行这个命令后,当前终端会话中,程序崩溃时生成的 core 文件大小将不再受限。例如,当我们在排查一个出现段错误的程序时,先执行 ulimit -c unlimited,然后再运行程序,就有可能生成完整的 core 文件,为我们后续分析问题提供数据支持。

要验证设置是否生效,可以执行 ulimit -c 。如果输出为 unlimited,那就说明我们的设置已经成功生效了;如果输出还是 0,那就需要检查一下命令是否正确执行,或者是否有其他因素影响了设置。

如果希望这个设置永久生效,我们可以将 ulimit -c unlimited 添加至用户 shell 配置文件,比如~/.bashrc 或~/.profile 。添加完成后,执行 source ~/.bashrc(如果是添加到~/.bashrc 文件中),这样下次登录时,这个设置就会自动生效。比如,对于一个长期运行的服务,我们希望它每次崩溃时都能生成 core 文件,就可以通过这种方式进行永久设置。

4.2 配置 /proc/sys/kernel/core_pattern

/proc/sys/kernel/core_pattern 是一个非常关键的内核参数,它决定了 core 文件的命名规则和保存路径 。默认情况下,core 文件可能仅生成为 “core”,并且位于进程工作目录。这样的设置很容易导致 core 文件被覆盖或难以定位,给我们后续的分析工作带来很大的困难。

我们可以通过一些命令来查看和设置这个参数。首先,查看当前模式,可以执行 cat /proc/sys/kernel/core_pattern ,通过这个命令,我们就能知道当前 core 文件的命名规则和保存路径是怎样的。

如果想要临时设置为带时间戳和 PID 的格式,可以执行 echo '/tmp/core.%e.%p.%t' | sudo tee /proc/sys/kernel/core_pattern 。在这个命令中,/tmp/core.%e.%p.%t 是我们设置的新的命名规则和保存路径。其中,%e 表示程序名,%p 表示 PID(进程 ID),%t 表示时间戳。这样设置后,生成的 core 文件会保存在/tmp 目录下,文件名包含程序名、PID 和时间戳,这能让我们更方便地识别和管理 core 文件。例如,当我们有多个程序同时运行,并且都可能产生 core 文件时,通过这种命名方式,就能清楚地知道每个 core 文件是由哪个程序在什么时间产生的。

需要注意的是,在设置新的保存路径时,一定要确保目标目录存在且可写 。比如我们设置的/tmp 目录,它是系统中默认存在且具有可写权限的目录。但如果我们设置的是其他自定义目录,就需要先创建这个目录并赋予它可写权限。可以执行 sudo mkdir -p /tmp/coredumps && sudo chmod 1777 /tmp/coredumps ,mkdir -p 用于创建目录,如果目录已经存在则不会报错;chmod 1777 用于设置目录权限,使所有用户都可以读写和执行这个目录。

4.3 启用相关内核参数(kernel.core_uses_pid 与 kernel.suid_dumpable )

接下来,我们要启用两个重要的内核参数,分别是 kernel.core_uses_pid 和 kernel.suid_dumpable 。

kernel.core_uses_pid 这个参数控制是否在 core 文件名中包含 PID 。在很多情况下,包含 PID 能让我们更方便地识别不同进程生成的 core 文件。比如,当系统中有多个相同程序的进程在运行时,通过 PID 就能准确区分每个进程对应的 core 文件。启用这个参数的命令是 echo 1 | sudo tee /proc/sys/kernel/core_uses_pid ,执行这个命令后,生成的 core 文件名中就会包含 PID。我们可以通过执行 cat /proc/sys/kernel/core_uses_pid 来验证变更,如果输出为 1,就说明设置成功了。

kernel.suid_dumpable 参数则用于控制是否允许对 setuid 程序生成 core dump 。在一些安全策略中,可能会禁用这个功能,导致特权程序崩溃时不生成转储。为了确保特权程序崩溃时也能生成 core 文件,我们可以执行 echo 2 | sudo tee /proc/sys/kernel/suid_dumpable (值 2 表示在满足 dumpable 标志时允许)。同样,我们可以通过执行 cat /proc/sys/kernel/suid_dumpable 来验证变更,确认输出为 2,就说明设置生效了。

4.4 systemd 服务中配置 Core Dump

在现代的 Linux 系统中,很多服务都是由 systemd 管理的。对于这些由 systemd 管理的服务,它们的资源限制独立于用户 shell,所以我们需要通过 systemd 单位文件显式启用 core dump 。

假设我们要为一个名为 servicename.service 的服务启用 core dump,首先要编辑对应服务的覆盖配置,执行 sudo systemctl edit servicename.service (将 servicename 替换为实际服务名)。这会打开一个编辑器,在编辑器中添加以下内容:

[Service]LimitCORE=infinityMemoryLimit=infinity

在这段配置中,LimitCORE=infinity 表示将 core 文件大小限制设置为无限,这样就能确保生成完整的 core 文件;MemoryLimit=infinity 表示将服务的内存限制也设置为无限,避免因为内存限制而影响 core 文件的生成。添加完配置后,我们需要重载配置并重启服务,执行 sudo systemctl daemon-reload 和 sudo systemctl restart servicename.service 。通过这两个命令,新的配置就会生效,当这个服务崩溃时,就会按照我们的配置生成 core 文件。

4.5 验证 Core Dump 是否正常生成

完成上述一系列配置后,我们还需要验证 Core Dump 是否能够正常生成 。这一步非常重要,它能帮助我们确认整个配置链路是否有效,是否存在遗漏或冲突。我们可以通过创建一个故意崩溃的测试程序来进行验证。首先,创建一个测试 C 文件 crash.c ,内容如下:

intmain(){char *p = NULL;return *p;}

在这段代码中,我们定义了一个空指针 p,然后尝试解引用这个空指针,这会导致程序发生段错误并崩溃,这正是我们想要的效果。

接下来,编译这个测试程序,执行 gcc -g -o crash crash.c 。这里的-g 选项用于在编译时生成调试信息,这些调试信息在后续使用 gdb 分析 core 文件时非常重要,它能帮助我们更准确地定位问题。

编译完成后,运行这个测试程序并触发段错误,执行./crash 。程序运行后,会因为段错误而崩溃。这时,我们检查 ls -l /tmp/core.*是否出现新生成的 core 文件 。如果一切配置正确,应该能在/tmp 目录下看到以 core.开头的文件,这个文件就是我们生成的 core 文件。

最后,我们使用 gdb 加载验证,执行 gdb ./crash /tmp/core.crash.* ,进入 gdb 调试环境后,输入 bt 查看回溯信息 。bt 命令用于查看函数调用栈,通过这个命令,我们可以看到程序崩溃时的函数调用关系,从而判断程序的执行流程是否正确,进一步确认 Core Dump 是否正常生成以及配置是否有效。如果能够正确显示函数调用栈信息,那就说明我们的 Core Dump 配置成功,能够正常生成和分析 core 文件了。

五、Core Dump 崩溃溯源

5.1 使用 GDB 加载 Core Dump 文件

当我们成功生成了 Core Dump 文件后,接下来就需要使用 GDB 来加载并分析这个文件,从而找出程序崩溃的原因 。GDB 是 GNU 开源组织开发的一个强大的调试工具,它可以帮助我们深入了解程序在崩溃瞬间的各种状态信息。

使用 GDB 加载程序与 core 文件的命令格式非常简单,就是 gdb <可执行程序> <core 文件> 。例如,我们有一个名为 myprogram 的可执行程序,以及它崩溃时生成的 core.12345 文件,那么我们就可以在终端中执行 gdb myprogram core.12345 来启动 GDB 并加载这两个文件。执行这个命令后,GDB 会读取可执行程序的符号表信息以及 core 文件中的内存映像、寄存器状态等调试信息,为我们后续的分析工作做好准备。

在这里,有一点需要特别强调,那就是在编译程序时加上-g 选项对 GDB 分析的重要性 。-g 选项的作用是在可执行文件中加入源文件信息,包括变量名、行号等符号表信息。当我们使用 GDB 加载带有-g 选项编译生成的可执行程序和 core 文件时,GDB 就能够准确地将内存地址映射到源代码中的具体行号和变量名,从而让我们更直观、更准确地定位问题。

比如,当我们使用 bt 命令查看函数调用栈时,如果程序是用-g 选项编译的,GDB 就能清晰地显示出每个函数调用的源文件和行号,让我们一目了然地知道程序在崩溃时的执行路径。相反,如果没有-g 选项,GDB 在分析时就只能显示出内存地址,这对于我们定位问题来说,难度就会大大增加,就像在黑暗中摸索一样,很难找到问题的关键所在。

5.2 GDB 调试核心命令与技巧

在使用 GDB 分析 Core Dump 文件时,有一些常用的命令是我们必须要掌握的,这些命令就像是我们在黑暗中探索的工具,能够帮助我们快速、准确地找到问题的根源 。

(1)bt / bt full:这两个命令的作用是打印崩溃时的函数调用栈 。bt 命令会显示出从当前函数到最外层函数的调用顺序,以及每个函数调用的内存地址。而 bt full 命令则会显示更详细的信息,除了函数调用栈,还会打印出每个栈帧中的局部变量值。例如,当我们执行 bt 命令后,可能会得到如下输出:

#00x08048567in func3()#1  0x080484e2 in func2()#2  0x08048476 in func1()#3  0x080483d9 in main()

从这个输出中,我们可以清晰地看到程序在崩溃时,是从 main 函数开始,依次调用了 func1、func2 和 func3 函数,最终在 func3 函数中出现了问题。如果我们执行 bt full 命令,就可以看到每个函数栈帧中的局部变量值,这对于我们分析函数内部的逻辑错误非常有帮助。比如,如果在 func3 函数中有一个局部变量 x,我们可以通过 bt full 命令查看在崩溃时 x 的值是否正确,从而判断是否是因为这个变量的值异常导致了程序崩溃。

(2)frame N:这个命令用于切换到怀疑的帧 。在使用 bt 命令查看函数调用栈后,我们可以根据栈帧的编号,使用 frame N 命令(其中 N 是栈帧的编号,从 0 开始)切换到我们怀疑出现问题的栈帧。例如,如果我们怀疑 func2 函数中存在问题,而 func2 函数对应的栈帧编号是 1,那么我们就可以执行 frame 1 命令切换到这个栈帧。切换到指定栈帧后,我们就可以使用其他命令,如 print 命令查看该栈帧中的变量值,或者使用 list 命令查看该栈帧对应的源代码,进一步分析问题。

(3)print:print 命令用于查看指针和关键变量值 。通过这个命令,我们可以查看程序在崩溃时,某个变量的值是多少,或者某个指针指向的内存地址中的内容是什么。例如,如果我们怀疑程序崩溃是因为一个指针为空指针导致的,我们可以使用 print 命令查看这个指针的值。假设这个指针变量名为 ptr,我们可以执行 print ptr 命令,如果输出为 0x0,那就说明这个指针确实为空指针,很可能就是导致程序崩溃的原因。print 命令还支持一些表达式,比如我们可以执行 print *ptr + 1,这会先解引用指针 ptr,然后将其值加 1 后输出,这对于我们分析一些复杂的数据结构非常有用。

(4)list:list 命令用于查看源码上下文 。当我们使用 bt 命令定位到可能出现问题的函数,或者使用 frame 命令切换到怀疑的栈帧后,我们可以使用 list 命令查看该函数或栈帧对应的源代码。list 命令默认会显示当前行附近的 10 行代码,这能帮助我们了解程序在崩溃时的执行环境,判断程序的执行逻辑是否正确。比如,我们执行 list 命令后,会看到类似如下的输出:

54int result = func2(a, b);55if (result < 0) {56// 处理错误情况57return -1;58      }59return result;60  }6162intmain(){63int a = 10;64int b = 5;

从这个输出中,我们可以看到在崩溃时,程序正在执行 func1 函数中的第 54 行代码,调用了 func2 函数。通过查看这些代码,我们就可以进一步分析 func2 函数的调用是否正确,以及 result 变量的值是否符合预期,从而找出程序崩溃的原因。

5.3 实操排障:从内核快照到修复代码

下面通过一个复杂的实际案例,看看如何利用 GDB 分析 Core Dump 文件,一步步定位问题并修复代码 。

假设我们有一个多线程的文件处理程序,在高并发场景下频繁崩溃 。获取到 Core Dump 文件后,用 GDB 加载:gdb /usr/local/bin/file_processing_program /data/core/core.file_processing_program.1234.1619234567 。

先用 bt 命令查看调用栈,发现崩溃发生在一个处理文件读写的函数 process_file 里,并且有多个线程都在调用这个函数 。这让我们怀疑可能是多线程环境下的资源竞争问题 。

切换到不同线程的栈帧,用 print 命令查看相关变量值 。发现多个线程同时访问一个文件描述符,并且没有进行适当的同步操作 。进一步分析代码逻辑,确认是在文件读写过程中,没有加锁保护共享资源,导致数据不一致,最终引发程序崩溃 。

找到问题根源后,我们在 process_file 函数中,对文件读写操作加锁,确保同一时间只有一个线程能访问文件 。修改后的代码如下:

#include <pthread.h>#include <stdio.h>#include <stdlib.h>// 定义文件操作锁pthread_mutex_t file_mutex;voidprocess_file(constchar *filename){// 加锁    pthread_mutex_lock(&file_mutex);     FILE *file = fopen(filename, "r");if (file == NULL) {        perror("Failed to open file");// 解锁        pthread_mutex_unlock(&file_mutex); return;    }// 文件处理逻辑char buffer[1024];while (fgets(buffer, sizeof(buffer), file) != NULL) {// 处理每一行数据    }    fclose(file);// 解锁    pthread_mutex_unlock(&file_mutex); }void *thread_function(void *arg) {constchar *filename = (constchar *)arg;    process_file(filename);return NULL;}intmain(){// 初始化文件操作锁    pthread_mutex_init(&file_mutex, NULL);     pthread_t thread1, thread2;constchar *filename1 = "file1.txt";constchar *filename2 = "file2.txt";// 创建线程    pthread_create(&thread1, NULL, thread_function, (void *)filename1);    pthread_create(&thread2, NULL, thread_function, (void *)filename2);// 等待线程结束    pthread_join(thread1, NULL);    pthread_join(thread2, NULL);// 销毁文件操作锁    pthread_mutex_destroy(&file_mutex); return0;}

重新编译并部署程序,经过高并发测试,程序再也没有因为资源竞争问题崩溃,成功解决了线上程序崩溃的难题 。通过这个案例可以看出,利用 GDB 分析 Core Dump 文件,结合调试命令和技巧,能有效定位和解决复杂的程序崩溃问题 。

end

如果这篇文章对你有所启发,欢迎点赞、在看,转发三连。星标⭐账号,还可以第一时间收到推送,感谢你的收看,我们下期再见~

往期干货推荐

【专栏模块嵌入式Linux
专栏模块】性能优化
专栏模块】面试八股文
专栏模块项目实战
【硬核干货缺了这些,别说你懂 Linux内核
硬核干货】缺了这些,别说你懂 Linux C/C++
【学习思维导图】Linux内核源码自主学习路线

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-04 08:10:44 HTTP/2.0 GET : https://f.mffb.com.cn/a/490241.html
  2. 运行时间 : 0.116241s [ 吞吐率:8.60req/s ] 内存消耗:4,890.16kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=25cc10098c57ea18d4a7aa6e032b9498
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000708s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000884s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000296s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000287s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000513s ]
  6. SELECT * FROM `set` [ RunTime:0.000221s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000585s ]
  8. SELECT * FROM `article` WHERE `id` = 490241 LIMIT 1 [ RunTime:0.000852s ]
  9. UPDATE `article` SET `lasttime` = 1783123844 WHERE `id` = 490241 [ RunTime:0.022328s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000349s ]
  11. SELECT * FROM `article` WHERE `id` < 490241 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000522s ]
  12. SELECT * FROM `article` WHERE `id` > 490241 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000425s ]
  13. SELECT * FROM `article` WHERE `id` < 490241 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.008709s ]
  14. SELECT * FROM `article` WHERE `id` < 490241 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000785s ]
  15. SELECT * FROM `article` WHERE `id` < 490241 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001401s ]
0.117848s