Is a Core Dump Executable by Itself

Is a core dump executable by itself?

In older unix variants it was the default to include the text as well as data in the core dump but it was also given in the a.out format and not ELF. Today's default behavior (in Linux for sure, not 100% sure about BSD variants, Solaris etc.) is to have the core dump in ELF format without the text sections but that behavior can be changed.

However, a core dump cannot be executed directly in any case without some help. The reason for that is that there are two things missing from a simple core file. One is the entry point, the other is code to restore the CPU state to the state at or just before the dump occurred (by default also the text sections are missing).

In AIX there used to be a utility called undump but I have no idea what happened to it. It doesn't exist in any standard Linux distribution I know of. As mentioned above (@WumpusQ) there's also an attempt at a similar project for Linux mentioned in above comments, however this project is not complete and doesn't restore the CPU state to the original state. It is, however, still good enough in some specific debugging cases.

It is also worth mentioning that there exist other ELF formatted files that cannot be executes as well which are not core files. Such as object files (compiler output) and .so (shared object) files. Those require a linking stage before being run to resolve external addresses.

Find executable that a core dump was generated against

See this question to get the git hash.

Then, change your build procedure (e.g. your Makefile) to include it. For instance, generate a one line C file with

  git log --pretty=format:'const char program_git_hash[] = "%H";' \
-n 1 > _prog_hash.c

then link your program with _prog_hash.c and remove that file after linking.
You could add timestamping information with e.g.

 date +'const char program_timestamp="%c";%n' >> _prog_hash.c

Then you could use gdb or strings on the binary executable to find it.

You may want to declare extern const char program_git_hash[]; in some header file, and perhaps display it (e.g. when passing the --version option to your program)

Find which program caused a core dump file

You can simply use the file program to identify them:

E.g

# file /var/core/core
/var/core/core: ELF 64-bit MSB core file SPARCV9 Version 1, from 'crs_stat.bin'

relationship between virtual memory and core dump


I know that the core dump is a memory dump of an executable file,

No. A core dump in gdb (gcore indicates you're using this) is usually in ELF format, so there's an extensive header definining what maps to what.

I'm not quite sure how much use GDB/linux makes of address space mangling when dumping cores, but you cannot assume file offset x will map to memory offset x -- because the virtual address space can span a huge address space, of which it only uses a few pages. (eg. a 64bit process can have a virtual address space that's much much bigger than your hard drive, whilst it might only have actually reserved memory that's far smaller, and even of that, not all pages need actually be allocated).

However, GDB can read these headers and if you ask it to print things (e.g. using the print or x command), it will give you the right thing.

If you want to read a core dump file, the right thing to do hence is to use GDB's capabilities to do so. Luckily, there's libgdb, which does exactly that for your C/C++ application. It basically let's you talk with GDB as if you were a user sitting in front of the gdb shell. Hence, figure out how to do what you want in GDB, and then use libgdb to do it programmatically.

If you want to do it lowlevel (don't do that, it's a hassle, and GDB is really what you want to use, actually) you can directly use the Binary File Descriptor Library to parse and represent the core dump. It's an essential part of GDB, and it'll be hard to get it to run with your own C++ program without re-implementing a lot of GDB routines.

What is a core dump file in Linux? What information does it provide?

It's basically the process address space in use (from the mm_struct structure which contains all the virtual memory areas), and any other supporting information*a, at the time it crashed.

For example, let's say you try to dereference a NULL pointer and receive a SEGV signal, causing you to exit. As part of that process, the operating system tries to write your information to a file for later post-mortem analysis.

You can load the core file into a debugger along with the executable file (for symbols and other debugging information, for example) and poke around to try and discover what caused the problem.


*a: in kernel version 2.6.38, fs/exec.c/do_coredump() is the one responsible for core dumps and you can see that it's passed the signal number, exit code and registers. It in turn passes the signal number and registers to a binary-format-specific (ELF, a.out, etc) dumper.

The ELF dumper is fs/binfmt_elf.c/elf_core_dump() and you can see that it outputs non-memory-based information, like thread details, in fs/binfmt_elf.c/fill_note_info(), then returns to output the process space.

Where the heck is that core dump?

So, today I learnt:

  • ulimit resets after reopening the shell.
  • I did a big mistake in my .zshrc - zsh nested and reopened itself after typing some commands.

After fiddling a bit with this I also found solution to the second problem. Making a shell script:

ulimit -c 750000
./a.out
gdb ./a.out ./core
ulimit -c 0
echo "profit"

How do I get a coredump from a setcap executable?

I have two answers after more research.

  1. You can change the system behaviour in its entirety. This isn't really suitable beyond a one user development machine but it does the trick:

    echo 1 > /proc/sys/fs/suid_dumpable

    Tested, works.

  2. You can change the behaviour of the specific program by calling prctl() in it:

    prctl(PR_SET_DUMPABLE, 1);

    In this way, the privileged program determines for itself that it should be dumpable, and the system as a whole is not affected.

    I've not tried this one.

(Mac) leave core file where the executable is instead of /cores?

Hmm - maybe you can edit /etc/sysctl.conf and help yourself you specifying the core_pattern?

kernel.core_pattern=/cores/core.%e.%p.%h.%t

Maybe that would help you find out more about which process was responsible for the dump

Core dumped, but core file is not in the current directory?

Read /usr/src/linux/Documentation/sysctl/kernel.txt.

core_pattern is used to specify a core dumpfile pattern name.

  • If the first character of the pattern is a '|', the kernel will treat
    the rest of the pattern as a command to run. The core dump will be
    written to the standard input of that program instead of to a file.

Instead of writing the core dump to disk, your system is configured to send it to the abrt (meaning: Automated Bug Reporting Tool, not "abort") program instead. Automated Bug Reporting Tool is possibly not as documented as it should be...

In any case, the quick answer is that you should be able to find your core file in /var/cache/abrt, where abrt stores it after being invoked. Similarly, other systems using Apport may squirrel away cores in /var/crash, and so on.



Related Topics



Leave a reply



Submit