什么是core dump?数组
分析core dump是Linux应用程序调试的一种有效方式,像内核调试抓取ram dump同样,core dump主要是获取应用程序崩溃时的现场信息,如程序运行时的内存、寄存器状态、堆栈指针、内存管理信息、函数调用堆栈信息等。sass
Core dump又称为“核心转储”,是Linux基于信号实现的。Linux中信号是一种异步事件处理机制,每种信号都对应有默认的异常处理操做,默认操做包括忽略该信号(Ignore)、暂停进程(Stop)、终止进程(Terminate)、终止并产生core dump(Core)等。安全
Signal
Value
Action
Comment
SIGHUP
1
Term
Hangup detected on controlling terminal or death of controlling process
SIGINT
2
Term
Interrupt from keyboard
SIGQUIT
3
Core
Quit from keyboard
SIGILL
4
Core
Illegal Instruction
SIGTRAP
5
Core
Trace/breakpoint trap
SIGABRT
6
Core
Abort signal from abort(3)
SIGIOT
6
Core
IOT trap. A synonym for SIGABRT
SIGEMT
7
Term
SIGFPE
8
Core
Floating point exception
SIGKILL
9
Term
Kill signal, cannot be caught, blocked or ignored.
SIGBUS
10,7,10
Core
Bus error (bad memory access)
SIGSEGV
11
Core
Invalid memory reference
SIGPIPE
13
Term
Broken pipe: write to pipe with no readers
SIGALRM
14
Term
Timer signal from alarm(2)
SIGTERM
15
Term
Termination signal
SIGUSR1
30,10,16
Term
User-defined signal 1
SIGUSR2
31,12,17
Term
User-defined signal 2
SIGCHLD
20,17,18
Ign
Child stopped or terminated
SIGCONT
19,18,25
Cont
Continue if stopped
SIGSTOP
17,19,23
Stop
Stop process, cannot be caught, blocked or ignored.
SIGTSTP
18,20,24
Stop
Stop typed at terminal
SIGTTIN
21,21,26
Stop
Terminal input for background process
SIGTTOU
22,22,27
Stop
Terminal output for background process
SIGIO
23,29,22
Term
I/O now possible (4.2BSD)
SIGPOLL
Term
Pollable event (Sys V). Synonym for SIGIO
SIGPROF
27,27,29
Term
Profiling timer expired
SIGSYS
12,31,12
Core
Bad argument to routine (SVr4)
SIGURG
16,23,21
Ign
Urgent condition on socket (4.2BSD)
SIGVTALRM
26,26,28
Term
Virtual alarm clock (4.2BSD)
SIGXCPU
24,24,30
Core
CPU time limit exceeded (4.2BSD)
SIGXFSZ
25,25,31
Core
File size limit exceeded (4.2BSD)
SIGSTKFLT
16
Term
Stack fault on coprocessor (unused)
SIGCLD
18
Ign
A synonym for SIGCHLD
SIGPWR
29,30,19
Term
Power failure (System V)
SIGINFO
29
A synonym for SIGPWR, on an alpha
SIGLOST
29
Term
File lock lost (unused), on a sparc
SIGWINCH
28,28,20
Ign
Window resize signal (4.3BSD, Sun)
SIGUNUSED
31
Core
Synonymous with SIGSYS
什么状况下会产生core dump呢?多线程
如下状况会出现应用程序崩溃致使产生core dump:异步
内存访问越界 (数组越界、字符串无\n结束符、字符串读写越界)
多线程程序中使用了线程不安全的函数,如不可重入函数
多线程读写的数据未加锁保护(临界区资源须要互斥访问)
非法指针(如空指针异常或者非法地址访问)
堆栈溢出
怎么获取core dump呢?socket
Linux提供了一组命令来配置core dump行为:函数
1. ulimit –c 查看core dump机制是否使能,若为0则默认不产生core dump,可使用ulimit –c unlimited使能core dump工具
2. cat /proc/sys/kernel/core_pattern 查看core文件默认保存路径,默认状况下是保存在应用程序当前目录下,可是若是应用程序中调用chdir()函数切换了当前工做目录,则会保存在对应的工做目录ui
3. echo “/data/xxx/” > /proc/sys/kernel/core_pattern 指定core文件保存路径和文件名,其中core_file可使用如下通配符:spa
%% 单个%字符
%p 所dump进程的进程ID
%u 所dump进程的实际用户ID
%g 所dump进程的实际组ID
%s 致使本次core dump的信号
%t core dump的时间 (由1970年1月1日计起的秒数)
%h 主机名
%e 程序文件名
4. ulimit –c [size] 指定core文件大小,默认是不限制大小的,若是自定义的话,size值必须大于4,单位是block(1block = 512bytes)
怎么分析core dump?
咱们首先编写一个程序,人为地产生core dump并获取core dump文件。
程序如上图,咱们经过除零操做产生core dump
编译运行产生了浮点数异常,从而引起core dump (注:编译时必须添加-g参数,表示添加调试信息,这样才可使用gdb进行调试)
当前目录下产生了core文件,使用file命令查看core文件类型
发现core文件类型为ELF格式,使用readelf查看ELF文件头部信息以下
经过Type字段能够看到,该文件为core文件
前面咱们讲到core dump能够查看应用程序崩溃时的现场信息,这里,咱们须要gdb命令辅助实现,使用gdb test core(即test可执行文件和core文件)
“Program terminated with signal 8, Arithmetic exception”表示应用程序是由于接收到Linux内核发出的Signal 8信号量而终止执行,Signal 8是SIGFPE,即浮点数异常。同时打印出了出问题的代码行result = a/b。
经过bt –n (backtrace)命令能够显示函数调用栈信息,n表示显示的调用栈层数,不指定则打印完整调用栈。由于test.c调试程序不涉及函数调用,因此咱们只能看到main函数的栈信息,若是程序是在main函数的字函数中出错,则能够打印更多的调用栈信息。
经过disassemble命令能够打印出错时的汇编代码片断,其中箭头指向的是出错的指令,即PC寄存器指向的地址,PC寄存器存放的是下一条执行指令。不少人会很困惑,由于一般程序执行的时候,PC寄存器指向的指令是待执行指令,就会怀疑gdb定位到的出错指令的准确性。其实,CPU确实是执行过这一条指令,可是CPU发现这条指令发生的异常,这个时候就会进入异常处理流程,gdb经过回溯调用栈准确地回到这一条指令执行前的状态,因此PC寄存器的值是彻底可信的。
能够看到调用了div指令作除法操做,被除数是-0x8(%ebp),指当前栈基址向下偏移8个字节所在内存单元的数值,EBP是栈基址寄存器。同时咱们能够看到前面经过movl $0x0, -0x8(%ebp)将0保存到该内存单元,证实被除数为0。
如上所示,gdb默认使用AT&T汇编语言格式打印汇编语句,能够经过set disassembly-flavor intel设置为intel汇编语言格式。
经过list命令能够查看当前指令附近的代码,前提是gdb工具能够找到源代码