core文件分析
来源:互联网 发布:高仿球鞋的淘宝店 编辑:程序博客网 时间:2024/06/18 00:06
刚开通博客,想写博客很久了,今天终于开通了。先把之前写的学习笔记贴上来吧。
在程序运行出现segmentfault后,我们会通过gdb来调试core文件定位问题,下面我们来分析下core文件是什么?
首先需要明确的一点就是core文件也是ELF格式的,ELF的格式如下:
ELF文件参与程序的链接和运行,从链接的角度看有上面左边所示的Linking View,从程序运行的角度看为右边所示的Execution View(执行视图)。Core的ELF文件格式是按照执行视图的格式组织的。
下面是core文件的ELF头信息
以内核代码elf_core_dump函数为入口分析core文件怎么生成的:
elf_core_dump-àfill_note_info-àfill_elf_header
static void fill_elf_header(struct elfhdr *elf, int segs,
u16 machine, u32 flags, u8 osabi)
{
memset(elf, 0, sizeof(*elf));
memcpy(elf->e_ident, ELFMAG, SELFMAG);
elf->e_ident[EI_CLASS] = ELF_CLASS;
elf->e_ident[EI_DATA] = ELF_DATA;
elf->e_ident[EI_VERSION] = EV_CURRENT;
elf->e_ident[EI_OSABI] = ELF_OSABI;
elf->e_type = ET_CORE;
elf->e_machine = machine;
elf->e_version = EV_CURRENT;
elf->e_phoff = sizeof(struct elfhdr);
elf->e_flags = flags;
elf->e_ehsize = sizeof(struct elfhdr);
elf->e_phentsize = sizeof(struct elf_phdr);
elf->e_phnum = segs;
return;
这里填入的ELF头信息就是用readelf –h读取到的。下面我们看下生成的core文件
、
上面表格中是core文件的ELF头的详细信息,分别用不同的颜色表明了不同的成员值。
成员
值
含义
e_ident
"\177ELF"
magic
0x1
ELF32
0x1
2's complement, little endian
0x1
1 (current)
0
UNIX - System V
0
e_type
4
ELF类型,ET_CORE表示为core文件
e_machine
0x28
ELF文件的平台属性
e_version
1
e_entry
0
ELF程序的入口虚拟地址
e_phoff
0x34
程序头表的偏移,程序头从0x34开始,紧跟在ELF头后面
e_shoff
0
e_flags
0
e_ehsize
0x34
ELF文件头本身的大小,52字节
e_phentsize
0x20
每个程序头占用的大小为32字节
e_phnum
0xa1
程序头表的个数,161个
e_shentsize
0
段描述符的大小
e_shnum
0
段描述符的个数
e_shstrndx
0
从上面信息可知,core文件程序头表从0x34位置开始,每个程序头表的大小为32字节
下面看下core文件程序头表的信息
截图只是程序头表的部分信息,因为有161个程序头表这里无法全部显示。
typedef struct elf32_phdr{
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
分析下core文件中第一个程序头表的信息,第一个程序头表的偏移是0x34
上面表格中是第一个程序头表的详细信息,分别用不同的颜色表明了不同的成员值。
成员
值
含义
p_type
0x4
段的类型,这里为PT_NOTE
p_offset
0x1454
段的位置相对于文件开始的偏移
p_vaddr
0
段在内存中的首字节地址
p_paddr
0
p_filesz
0x3904
段在文件映像栈的字节数
p_memsz
0
段在内存映像中的字节数
p_flags
0
p_align
0
从上面的程序头表信息可知,第一个段类型为NOTE段,偏移为0x1454,大小为0x3904。
PT_NOTE类型的段用于存放线程信息和寄存器信息。由于PT_NOTE段是辅助信息,不存在与内存中。
那么PT_NOTE段信息是怎么存储的呢?
去内核中看下相应代码fill_note_info函数
fill_note_info函数代码片段:
//首先将所有的线程加入到info-> thread_list
for (ct = current->mm->core_state->dumper.next;
ct; ct = ct->next) {
ets = kzalloc(sizeof(*ets), GFP_KERNEL);
if (!ets)
return 0;
ets->thread = ct->task;
list_add(&ets->list, &info->thread_list);
}
//遍历链表,调用elf_dump_thread_status保存线程的信息
list_for_each(t, &info->thread_list) {
int sz;
ets = list_entry(t, struct elf_thread_status, list);
sz = elf_dump_thread_status(signr, ets);
info->thread_status_size += sz;
}
接着分析elf_dump_thread_status函数
elf_dump_thread_status函数代码:
static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
{
int sz = 0;
struct task_struct *p = t->thread;
t->num_notes = 0;
fill_prstatus(&t->prstatus, p, signr); //获取线程的状态,包括signal和pid等
elf_core_copy_task_regs(p, &t->prstatus.pr_reg); //获取线程的寄存器信息
fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
&(t->prstatus)); //将信息存入memelfnote的notes数组中
t->num_notes++;
sz += notesize(&t->notes[0]);
…
return sz;
}
上面就是填充PT_NOTE段的主要代码流程,回过头来我们看下PT_NOTE段的数据结构:
/* Note header in a PT_NOTE section */
typedef struct elf32_note {
Elf32_Word n_namesz; /* Name size */
Elf32_Word n_descsz; /* Content size */
Elf32_Word n_type; /* Content type */
} Elf32_Nhdr;
struct elf_note_info {
struct memelfnote *notes;
struct elf_prstatus *prstatus; /* NT_PRSTATUS */
struct elf_prpsinfo *psinfo; /* NT_PRPSINFO */
struct list_head thread_list;
elf_fpregset_t *fpu;
int thread_status_size;
int numnote;
};
下面分析core文件的PT_NOTE段信息:
上面的寄存器信息正好与gdb看到的寄存器信息一致
上面只是分析了PT_NOTE段的一部分,我们定位coredump的问题也不需要这样脑神费力的分析二进制core文件。
- Linux core 文件分析
- core文件分析
- core文件分析
- dbx分析core文件
- Core文件的分析
- Core文件分析
- core文件分析
- Core文件分析
- Core文件的分析
- 浅谈Core文件分析
- core文件分析
- core文件的分析
- UNIX下core文件的分析
- 用gdb工具分析core文件
- 用gdb工具分析core文件
- Linux下core文件的演示分析
- linux 抓堆栈 core文件分析
- Linux下core文件的演示分析
- 常见的HTTP状态码
- P269 3
- ubuntu开启 SSH服务
- httpwatch详解
- git, github使用
- core文件分析
- linux之MySQL(Structured Query Language)结构化查询语言
- 认识自己——我所丧失的能力2
- 获取远程设备IP地址
- ubuntu如何修改超级用户密码
- android---线性布局
- 模式识别:k-均值聚类算法的研究与实现
- ios UITableView separatorColor 默认颜色
- java处理图片--图片的缩放,旋转和马赛克化