When developing under Linux, there is no log if the program suddenly crashes. You can look at the core file. Analyze the cause from the core file, see where the program is hanging through GDB, analyze the variables before and after, and find out the cause of the problem.

Core Dump

When a program abnormally terminates or crashes, the operating system records the memory status of the program and stores it in a file. This behavior is called Core Dump. We can think of core dump as a “snapshot of memory”, but in fact, in addition to memory information, there are also some key program state, such as register information (including program Pointers, stack Pointers, etc.), memory management information, other processor and operating system state and information. Core dump is very helpful for programmers to diagnose and debug programs because core dump files can reproduce errors that are difficult to reproduce, such as pointer exceptions.

Associated Settings

If core dump is not enabled, it is disabled by default. You can run the ulimit -c command to check whether the function is enabled. If the output is 0, the core dump function is disabled. You need to run ulimit -c unlimited to enable the core dump function.

ulimit

Using the ulimit command, you can restrict the access of system users to shell resources. Limits the resources consumed by the shell startup process. The following types of restrictions are supported: The size of the kernel file created, the size of the process data block, the size of the Shell process creation file, the size of the memory lock, the size of the resident memory set, the number of open file descriptors, the maximum size of the allocation stack, CPU time, the maximum number of threads per user, and the maximum virtual memory that the Shell process can use. At the same time, it supports hard and soft resource limits.

Ulimit options are as follows:

-a: Displays the current setting of resource limits. -c <core file upper limit > : sets the maximum number of core files, in blocks.-d< data section size > : the maximum size of the program data section, in KB.-f< file size > : the largest file that the shell can create, in blocks; -h: sets the hard limit of resources, that is, the limit set by the administrator. -m < memory size > : specifies the upper limit of available memory, expressed in KB. -n < file number > : specifies the maximum number of files that can be opened at the same time. -p < buffer size > : specifies the size of the pipeline buffer, in 512 bytes.-s< stack size > : specifies the maximum stack size, in KB. -s: sets the elastic limit of resources. -t <CPU time > : specifies the upper limit of the CPU time, in seconds. -u < number of programs > : indicates the maximum number of programs that a user can start. -v < virtual memory size > : specifies the upper limit of the virtual memory, expressed in KB.Copy the code

Core file name and generation path:

If this is not set, the default generated core file is named core without any other extension names. The new core file generation will overwrite the original core file. You can configure the name and generation path of core files as follows:

  • /proc/sys/kernel/core_uses_pid controls whether to add pid as an extension to the file name of the core file. If the file content is 1, pid is added as the extension name, and the generated core file format is core.xxxx. If the value is 0, the generated core files are named core.

  • Proc/sys/kernel/core_pattern controls the location and file name format of core files.

Here is the list of parameters:

%p -insert pid into filename Add PID % U -insert current uid into filename Add current uid %g -insert current gid into filename Add current GID %s - insert signal that caused the coredump into the filename %t - insert UNIX time that the Coredump occurred into FILENAME Unix time when core files were generated %h - insert hostname where the coredump occurred into FILENAME % e-insert COREDUMPING EXECUTABLE name into filename Add command nameCopy the code

See Core Dump File for more information.

Example:

The code that generates the error is as follows:

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>

#define CORE_SIZE 500 * 1024 * 1024

int main(a){
	struct rlimit rlmt;
	if (getrlimit(RLIMIT_CORE, &rlmt) == - 1) {
		return - 1;
	}
	printf("Before set rlimit core dump current is:%d, max is:%d\n", (int)rlmt.rlim_cur, (int)rlmt.rlim_max);

	rlmt.rlim_cur = (rlim_t)CORE_SIZE;
	rlmt.rlim_max = (rlim_t)CORE_SIZE;

	if (setrlimit(RLIMIT_CORE, &rlmt) == - 1) {
		return - 1;
	}

	if (getrlimit(RLIMIT_CORE, &rlmt) == - 1) {
		return - 1;
	}
	printf("After set rlimit core dump current is:%d, max is:%d\n", (int)rlmt.rlim_cur, (int)rlmt.rlim_max);

	// Write to an area of memory pointed to by a null pointer, a segment error will occur --> generate a core file
	int *null_ptr = NULL;
	*null_ptr = 10;

	return 0;
}
Copy the code

Compile the source file with GCC, plus -g to add debugging information; Execution generates an error, generating a core file.

After executing GDB core, the output information is as follows:

gdb <program> core