核心文件是否有通用格式?
Is there a generic format for core files?
我注意到无论我使用哪种编译器(gcc、llvm、clang、icc 等),如果我得到一个核心转储,我几乎总是可以将它扔到 GDB(或者可能是其他调试器)中,但我大部分时间都反射性地使用 GDB)而不用担心 program/library 是如何编译的。为什么是这样?是否有通用格式来描述如何创建核心转储?是否有任何 compiler/debugger 组合不遵循此格式?
核心转储文件是由操作系统内核编写的,而不是由编译器或调试器编写的。这就是为什么例如每个 Linux 调试器都支持相同的格式。
Linux 核心转储使用 ELF 格式。内核端实现在elf_core_dump()
in fs/binfmt_elf.c
.
但是,像 Crashpad 这样的崩溃报告系统会写出自己的核心转储等价物以供远程收集。这些转储要小得多,只能包含一个堆栈跟踪地址列表,并在不同的操作系统中使用它们自己的自定义格式。不过,您需要将这些作为库明确集成到您的应用程序中。
核心转储格式特定于每个操作系统的默认格式,最常见的格式是 ELF。
用户空间核心文件有很多 segments/program headers.
两种类型的program/segment header被转储到一个核心文件中
- PT_NOTE
- PT_LOAD
PT_NOTE 段由一个或多个 Elf_Note 条目组成。
PT_LOAD程序中的入口header描述了进程的VMAs(Virtual Memory Area)
Linux 和 FreeBSD 都在 PT_NOTE 段中存储有关进程的大部分数据。
在 FreeBSD 上,您可以从核心文件中读取音符片段,如下所示
$ readelf --notes hello.core | grep -v "description data:"
Displaying notes found at file offset 0x00000200 with length 0x00001d04:
Owner Data size Description
FreeBSD 0x00000078 NT_PRPSINFO (prpsinfo structure)
FreeBSD 0x000000e0 NT_PRSTATUS (prstatus structure)
FreeBSD 0x00000200 NT_FPREGSET (floating point registers)
FreeBSD 0x00000018 NT_THRMISC (thrmisc structure)
FreeBSD 0x00000444 NT_PROCSTAT_PROC (proc data)
FreeBSD 0x00000aec NT_PROCSTAT_FILES (files data)
FreeBSD 0x00000724 NT_PROCSTAT_VMMAP (vmmap data)
FreeBSD 0x00000038 NT_PROCSTAT_GROUPS (groups data)
FreeBSD 0x00000006 NT_PROCSTAT_UMASK (umask data)
FreeBSD 0x000000d4 NT_PROCSTAT_RLIMIT (rlimit data)
FreeBSD 0x00000008 NT_PROCSTAT_OSREL (osreldate data)
FreeBSD 0x0000000c NT_PROCSTAT_PSSTRINGS (ps_strings data)
FreeBSD 0x00000114 NT_PROCSTAT_AUXV (auxv data)
NT_PRPSINFO - "struct prpsinfo" is dumped
NT_PRSTATUS - "struct prstatus" & "struct __reg64" is dumped
NT_FPREGSET - "struct __fpreg64" is dumped
NT_THRMISC - "struct thrmisc" is dumped
NT_PROCSTAT_* - Refer this for proc stat data see libprocstat
下面的文章有更多关于 FreeBSD 支持的核心转储的详细信息
我注意到无论我使用哪种编译器(gcc、llvm、clang、icc 等),如果我得到一个核心转储,我几乎总是可以将它扔到 GDB(或者可能是其他调试器)中,但我大部分时间都反射性地使用 GDB)而不用担心 program/library 是如何编译的。为什么是这样?是否有通用格式来描述如何创建核心转储?是否有任何 compiler/debugger 组合不遵循此格式?
核心转储文件是由操作系统内核编写的,而不是由编译器或调试器编写的。这就是为什么例如每个 Linux 调试器都支持相同的格式。
Linux 核心转储使用 ELF 格式。内核端实现在elf_core_dump()
in fs/binfmt_elf.c
.
但是,像 Crashpad 这样的崩溃报告系统会写出自己的核心转储等价物以供远程收集。这些转储要小得多,只能包含一个堆栈跟踪地址列表,并在不同的操作系统中使用它们自己的自定义格式。不过,您需要将这些作为库明确集成到您的应用程序中。
核心转储格式特定于每个操作系统的默认格式,最常见的格式是 ELF。
用户空间核心文件有很多 segments/program headers.
两种类型的program/segment header被转储到一个核心文件中
- PT_NOTE
- PT_LOAD
PT_NOTE 段由一个或多个 Elf_Note 条目组成。
PT_LOAD程序中的入口header描述了进程的VMAs(Virtual Memory Area)
Linux 和 FreeBSD 都在 PT_NOTE 段中存储有关进程的大部分数据。
在 FreeBSD 上,您可以从核心文件中读取音符片段,如下所示
$ readelf --notes hello.core | grep -v "description data:"
Displaying notes found at file offset 0x00000200 with length 0x00001d04:
Owner Data size Description
FreeBSD 0x00000078 NT_PRPSINFO (prpsinfo structure)
FreeBSD 0x000000e0 NT_PRSTATUS (prstatus structure)
FreeBSD 0x00000200 NT_FPREGSET (floating point registers)
FreeBSD 0x00000018 NT_THRMISC (thrmisc structure)
FreeBSD 0x00000444 NT_PROCSTAT_PROC (proc data)
FreeBSD 0x00000aec NT_PROCSTAT_FILES (files data)
FreeBSD 0x00000724 NT_PROCSTAT_VMMAP (vmmap data)
FreeBSD 0x00000038 NT_PROCSTAT_GROUPS (groups data)
FreeBSD 0x00000006 NT_PROCSTAT_UMASK (umask data)
FreeBSD 0x000000d4 NT_PROCSTAT_RLIMIT (rlimit data)
FreeBSD 0x00000008 NT_PROCSTAT_OSREL (osreldate data)
FreeBSD 0x0000000c NT_PROCSTAT_PSSTRINGS (ps_strings data)
FreeBSD 0x00000114 NT_PROCSTAT_AUXV (auxv data)
NT_PRPSINFO - "struct prpsinfo" is dumped
NT_PRSTATUS - "struct prstatus" & "struct __reg64" is dumped
NT_FPREGSET - "struct __fpreg64" is dumped
NT_THRMISC - "struct thrmisc" is dumped
NT_PROCSTAT_* - Refer this for proc stat data see libprocstat
下面的文章有更多关于 FreeBSD 支持的核心转储的详细信息