Detailed Explanation of Linux Core Dump

LCG Technology SpaceFocus on sharing technical articles on C/C++, Linux applications/drivers, audio and video, QT, and various frameworks.

👇 We sincerely recommend you to follow us👇

  • What scenarios produce Core Dumps
  • How to use Linux Core Dumps
    • Enable core dump functionality
    • Modify the path and format for saving core files
    • Use gdb to debug core files
    • Why some programs cannot produce core dumps?

Linux Core Dump

When a program terminates abnormally or crashes during execution, the operating system records the program’s memory state at that time and saves it in a file. This behavior is called a Core Dump (sometimes translated as “核心转储”).

We can think of a core dump as a “memory snapshot”, but in reality, in addition to memory information, some key program execution states are also dumped, such as register information (including program counter, stack pointer, etc.), memory management information, and other processor and operating system states and information. Core dumps are very helpful for programmers to diagnose and debug programs, as some program errors are difficult to reproduce, such as pointer exceptions, and the core dump file can recreate the scenario when the program failed.

[!attention] If you need more information, be sure to compile the program with the -g option<span>gcc -g source_file.c -o output_file</span>

What Scenarios Produce Core Dumps

As mentioned above, a core dump occurs when a program terminates abnormally or crashes, but it hasn’t been specified what specific scenarios cause the program to terminate abnormally or crash. For example, does using the kill -9 command to kill a process produce a core dump? Experiments have shown that it does not. So what situations will produce it?

In Linux, signals are a mechanism for handling asynchronous events, and each signal has a default action. You can view the signals provided by the Linux system and their default handling in the Linux signal manual page[1]. The default actions mainly include ignoring the signal (Ignore), pausing the process (Stop), terminating the process (Terminate), and terminating and producing a core dump (core). If we use the default actions for signals, the following signals will produce a core dump when they occur:

Signal Action Comment
SIGQUIT Core Quit from keyboard
SIGILL Core Illegal Instruction
SIGABRT Core Abort signal from abort[2]
SIGSEGV Core Invalid memory reference
SIGTRAP Core Trace/breakpoint trap

Of course, this is not limited to the above signals. This is why using Ctrl+Z to suspend a process or Ctrl+C to terminate a process does not produce a core dump, because the former sends a SIGTSTP signal to the process, which has a default action of pausing the process (Stop Process); the latter sends a SIGINT signal to the process, which has a default action of terminating the process (Terminate Process).

Similarly, the kill -9 command sends a SIGKILL signal, which defaults to terminating the process. However, if we use Ctrl+\ to terminate a process, it sends a SIGQUIT signal to the process, which by default will produce a core dump. Other scenarios that can produce a core dump include: calling the abort() function, memory access errors, illegal instructions, etc.

How to Use Linux Core Dumps

Type the command <span>ulimit -c </span> in the terminal, and if the output is 0, it indicates that core dumps are disabled by default, meaning that no core dump file will be generated when the program terminates abnormally.

Enable Core Dump Functionality

(1) Method One: Temporary Effect

  • We can use the command <span>ulimit -c unlimited </span> to enable core dump functionality without limiting the size of the core dump file. If you need to limit the file size, change <span>unlimited</span> to the maximum size you want for the core file, noting that the unit is blocks (KB).

(2) Method Two: Permanent Effect

  • Modify the file <span>/etc/security/limits.conf</span> to add a line:

(If this method is not effective, you can add <span>ulimit -c unlimited</span> in <span>~/.profile</span> or <span>/etc/profile</span>)

# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#   
* soft core unlimited

Modify the Path and Format for Saving Core Files

The default generated core file is saved in the directory where the executable file is located, and the file name is simply core.

(1) Method One: Temporary Effect by modifying <span>/proc/sys/kernel/core_pattern</span> to control the location and filename format of the generated core file. For example, <span>echo "/tmp/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern</span> sets the generated core file to be saved in the “/tmp/corefile” directory, with the filename format “core-command_name-pid-timestamp”.More detailed information can be found in the core manual[3]!

(2) Method Two: Permanent Effect

  • Modify the file <span>/etc/sysctl.conf</span> to add a line:

(If this method is not effective, you can add <span>echo "/tmp/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern</span> in <span>~/.profile</span> or <span>/etc/profile</span>)

# coredump configuration
kernel.core_pattern = /tmp/corefile-%e-%p-%t

Use gdb to Debug Core Files

Once a core file is generated, how do we use it for debugging? In Linux, GDB can be used to debug core files, with the following steps:

  • First, compile the source file using gcc with the -g option to add debugging information;
  • Enable core dump as mentioned above so that a core file can be generated when the program terminates abnormally;
  • Run the program, and after the core dump, use the command <span>gdb <program> core</span> to view the core file, where program is the name of the executable program, and core is the name of the generated core file.

Here is a simple example:

#include <stdio.h>

int func(int *p)
{
  int y = *p;
  return y;
}

int main()
{
  int *p = NULL;
  return func(p);
}

Compile with debugging information, run it, and after the core dump, use gdb to view the core file:

guohailin@guohailin:~$ gcc core_demo.c -o core_demo -g
guohailin@guohailin:~$ ./core_demo
Segmentation fault (core dumped)

guohailin@guohailin:~$ gdb core_demo core_demo.core.24816
...
Core was generated by './core_demo'.
Program terminated with signal 11, Segmentation fault.
#0 0x080483cd in func (p=0x0) at core_demo.c:5
5 int y = *p;
(gdb) where
#0 0x080483cd in func (p=0x0) at core_demo.c:5
#1 0x080483ef in main () at core_demo.c:12
(gdb) info frame
Stack level 0, frame at 0xffd590a4:
eip = 0x80483cd in func (core_demo.c:5); saved eip 0x80483ef
called by frame at 0xffd590c0
source language c.
Arglist at 0xffd5909c, args: p=0x0
Locals at 0xffd5909c, Previous frame's sp is 0xffd590a4
Saved registers:
ebp at 0xffd5909c, eip at 0xffd590a0
(gdb)

From the above, we can see that we can restore the execution scenario of core_demo, and using where allows us to view the current program’s call stack frame, and we can also use commands in gdb to view registers, variables, and other information.

Sometimes we want to dynamically load the executable program and core dump file after starting gdb, in which case we can use the commands <span>file <program></span> and <span>core <core dump file></span> (core-file command abbreviation). The <span>file</span> command is used to read the symbol table information of the executable file, while the <span>core</span> command specifies the location of the core dump file:

(gdb) file /data/nan/a
Reading symbols from /data/nan/a...done.
(gdb) core /var/core/core.a.22268.1402638140
[New LWP 1]
[Thread debugging using libthread_db enabled]
[New Thread 1 (LWP 1)]
Core was generated by `./a'.
Program terminated with signal 11, Segmentation fault.
#0  0x0000000000400cdb in main () at a.c:6
6               *p = 0;

We can see that gdb also shows the location where the program crashed.

Why Some Programs Cannot Produce Core Dumps?

After configuring the conditions for core dumps, if some business programs cannot produce core files, you need to check if the program has set SUID. For example, if the executable file <span>xxx</span> is configured as follows: when user <span>tom</span> executes the <span>xxx</span> command, the operating system finds that this program has the SUID bit set and its owner is <span>root</span>, so the system will create a process with the effective user ID (Effective UID) set to <span>root</span>, not <span>tom</span>.

# Change the file owner to root
chown root:root xxx
# Set the SUID bit (4)
chmod 4755 xxx

By default, Linux prohibits SUID programs from generating core dumps for security reasons

  1. Security Risks:
  • SUID programs run with high privileges (in this case, root privileges)
  • Core files contain memory snapshots at the time of program crashes, which may contain sensitive information (such as passwords, keys, etc.)
  • If ordinary users can trigger SUID programs to crash and obtain core files, they may steal this sensitive information
  • System Default Behavior:
    • **<span>0</span>** (default): Prohibit SUID programs from generating core dumps ❌
    • **<span>1</span>**: Allow generation, but core files may only be readable by root
    • **<span>2</span>**: Allow generation, treated like ordinary programs
    • Check the value of <span>/proc/sys/fs/suid_dumpable</span>:

    (1) Temporarily Allow SUID Programs to Generate Core Dumps:

    # Temporarily enable (will be lost after reboot)
    echo 1 > /proc/sys/fs/suid_dumpable
    # Or allow full dump
    echo 2 > /proc/sys/fs/suid_dumpable
    

    (2) Permanently Modify to Allow SUID Programs to Generate Core Dumps (in /etc/sysctl.conf):

    # Add at the end of the file
    fs.suid_dumpable = 1
    # Then apply
    sysctl -p
    

    References[1]

    Here: http://man7.org/linux/man-pages/man7/signal.7.html

    [2]

    abort: http://man7.org/linux/man-pages/man3/abort.3.html

    [3]

    Here: http://man7.org/linux/man-pages/man5/core.5.html

    END

    This concludes the article. I hope it is helpful to you!

    Give a “like👍”, click “read” and “share“, to give LCG a little encouragement, and also to encourage yourself! This way, new articles will appear in your list as soon as possible.

    Knowledge is like brilliant stars, priceless. Every bit counts. When you touch “like the author“, it injects a strong motivation into me to create better articles, allowing us to sail freely in the boundless ocean of knowledge.

    Leave a Comment