1、core文件简介
Core,又称之为Core Dump文件,是Unix/Linux操作系统的一种机制。OS在出Core的同时,虽然会终止掉当前进程,但是也会保留下第一手的现场数据,OS仿佛是一架被按下快门的相机,而照片就是产出的Core文件。里面含有当进程被终止时内存、CPU寄存器等信息,可以供后续开发人员进行调试。
由此,可以利用这个特性,打开core文件生成开关之后,在应用程序出现异常崩溃时,系统生成应用程序运行镜像,开发人员可以拿这个镜像来调试定位崩溃原因。
2、打开core文件生成开关
用以下命令来阻止系统生成core文件:
ulimit -c 0
ulimit -c 1024则是限制产生的core文件的大小不能超过1024kb。
ulimit -cunlimited则是产生的core文件的大小没有上限。
一般我们用ulimit -c unlimited来使能 core文件。
注意:ulimit是系统内建命令,不在系统环境变量$PATH所定义的路径下,不能用TAB键联想。
下面的命令可以检查生成core文件的选项是否打开:
ulimit -a
该命令将显示所有的用户定制,其中选项-a代表“all”。也可以修改系统文件来调整core选项。
在Hi3536上:
# ulimit-a
-f: filesize (blocks) unlimited
-t: cputime (seconds) unlimited
-d: dataseg size (kb) unlimited
-s: stacksize (kb) 2048
-c: corefile size (blocks) unlimited #如果打开core文件生成开关,在这里可以看到
-m:resident set size (kb) unlimited
-l: lockedmemory (kb) 64
-p:processes 1359
-n: filedescriptors 1024
-v:address space (kb) unlimited
-w:locks unlimited
-e:scheduling priority 0
-r: real-time priority 0
3、使用core文件
在core文件所在目录下键入:
gdb -c core
它会启动GNU的调试器,来调试core文件,并且会显示生成此core文件的程序名,中止此程序的信号等等
如果你已经知道是由什么程序生成此core文件的,比如MyServer崩溃了生成core.12345,那么用此指令调试:
gdb -c core MyServer
以下怎么办就该去学习gdb的使用了
也可以:
gdb[exec file] [core file]
如:
gdb ./test test.core
在进入gdb后, 用bt命令或者where命令,查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件->行.
4、一个小方法来测试产生core文件
直接输入指令: kill -11 [pid] 杀掉相应的进程,即可生成core文件。
注意:生成的core文件的路径一般是运行该程序的路径,如果没有设置生成的文件名的规则的话,默认是 core.
5、举例
Hi3536上
# ulimit -a
-f: file size(blocks) unlimited
-t: cpu time(seconds) unlimited
-d: data seg size(kb) unlimited
-s: stack size(kb) 2048
-c:core file size (blocks) unlimited
-m: resident setsize (kb) unlimited
-l: locked memory(kb) 64
-p: processes 1359
-n: filedescriptors 1024
-v: address space(kb) unlimited
-w: locks unlimited
-e: schedulingpriority 0
-r: real-timepriority 0
# ps
PID USER VSZ STAT COMMAND
……
1852 root 2796 S -sh
1867 root 5696 S tcpdump
1886 root 2660 S sleep 10
1887 root 3124 R ps
13700 root 2796 S -/bin/sh
#
#
#
# kill -11 1867
# [512369.175584]device eth0 left promiscuous mode
在另外一个终端上
# tcpdump
……
19:18:49.774144 IP208.208.88.160.62327 > 208.208.88.110.23: Flags [.], ack 37811400, win 2789,options [nop,nop,TS[|tcp]>
19:18:49.774160 IP208.208.88.110.23 > 208.208.88.160.62327: Flags [P.], ack 1, win 227,options [nop,nop,TS[|tcp]>
19:18:49.774283 IP208.208.88.160.62327 > 208.208.88.110.23: Flags [.], ack 37811641, win 2789,options [nop,nop,TS[|tcp]>
Segmentationfault (core dumped)
生成core文件
# ls -lh
drwxr-xr-x 2 0 Jan 1 1970 ActiveX
drwxrwxrwx 2 0 Jan 25 01:04 bin
-rw------- 1 1.1M Feb 24 19:18 core
drwxrwxrwt 5 2.9K Jan 1 1970 dev
drwxrwxrwx 3 0 Jan 25 01:03 driverfile
drwxrwxrwt 5 360 Jan 1 1970 etc
drwxrwxrwx 2 0 Jan 25 01:03 home
lrwxrwxrwx 1 10 Jan 25 01:04 init -> /sbin/init
drwxrwxrwx 3 0 Dec 5 11:56 lib
lrwxrwxrwx 1 12 Jan 25 01:04 linuxrc -> /bin/busybox
drwxrwxrwx 2 0 Jan 25 01:03 mnt
drwxrwxrwx 2 0 Jan 25 01:03 opt
dr-xr-xr-x 64 0 Jan 1 1970 proc
drwxrwxrwx 2 0 Jan 25 01:04 root
drwxrwxrwx 2 0 Jan 25 01:04 sbin
dr-xr-xr-x 13 0 Jan 1 1970 sys
drwxrwxrwx 2 0 Jan 25 01:04 sysres
drwxrwxrwt 2 40 Jan 1 1970 tmp
drwxrwxrwx 7 0 Jan 25 01:04 usr
drwxrwxrwt 7 140 Feb 24 04:00 var
-rwxrwxrwx 1 211 Jan 25 01:03 zlog.conf
生成的core文件在根目录下,core大小要比进程占用的虚拟内存大两倍。
注意的问题:
在Linux下要保证程序崩溃时生成Coredump要注意这些问题:
一、要保证存放Coredump的目录存在且进程对该目 录有写权限。存放Coredump的目录即进程的当前目录,一般就是当初发出命令启动该进程时所在的目录。但如果是通过脚本启动,则脚本可能会修改当前目录,这时进程真正的当前目录就会与当初执行脚本所在目录不同。这时可以查看”/proc/<进程pid>/cwd“符号链接的目标来确定进程 真正的当前目录地址。通过系统服务启动的进程也可通过这一方法查看。
二、若程序调用了seteuid()/setegid()改变 了进程的有效用户或组,则在默认情况下系统不会为这些进程生成Coredump。很多服务程序都会调用seteuid(),如MySQL,不论你用什么用 户运行mysqld_safe启动MySQL,mysqld进行的有效用户始终是msyql用户。如果你当初是以用户A运行了某个程序,但在ps里看到的 这个程序的用户却是B的话,那么这些进程就是调用了seteuid了。为了能够让这些进程生成coredump,需要将/proc/sys/fs/suid_dumpable文件的内容改为1(一般默认是0)。
三、这个一般都知道,就是要设置足够大的Core文件大小限制 了。程序崩溃时生成的Core文件大小即为程序运行时占用的内存大小。但程序崩溃时的行为不可按平常时的行为来估计,比如缓冲区溢出等错误可能导致堆栈被破坏,因此经常会出现某个变量的值被修改成乱七八糟的,然后程序用这个大小去申请内存就可能导致程序比平常时多占用很多内存。因此无论程序正常运行时占用 的内存多么少,要保证生成Core文件还是将大小限制设为unlimited为好。
四、在代码里不要注册
1、core文件简介
Core,又称之为Core Dump文件,是Unix/Linux操作系统的一种机制。OS在出Core的同时,虽然会终止掉当前进程,但是也会保留下第一手的现场数据,OS仿佛是一架被按下快门的相机,而照片就是产出的Core文件。里面含有当进程被终止时内存、CPU寄存器等信息,可以供后续开发人员进行调试。
由此,可以利用这个特性,打开core文件生成开关之后,在应用程序出现异常崩溃时,系统生成应用程序运行镜像,开发人员可以拿这个镜像来调试定位崩溃原因。
2、打开core文件生成开关
用以下命令来阻止系统生成core文件:
ulimit -c 0
ulimit -c 1024则是限制产生的core文件的大小不能超过1024kb。
ulimit -c unlimited则是产生的core文件的大小没有上限。
一般我们用ulimit -c unlimited来使能 core文件。
注意:ulimit是系统内建命令,不在系统环境变量$PATH所定义的路径下,不能用TAB键联想。
下面的命令可以检查生成core文件的选项是否打开:
ulimit -a
该命令将显示所有的用户定制,其中选项-a代表“all”。也可以修改系统文件来调整core选项。
在Hi3536上:
# ulimit -a
-f: file size (blocks) unlimited
-t: cpu time (seconds) unlimited
-d: data seg size (kb) unlimited
-s: stack size (kb) 2048
-c: core file size (blocks) unlimited #如果打开core文件生成开关,在这里可以看到
-m: resident set size (kb) unlimited
-l: locked memory (kb) 64
-p: processes 1359
-n: file descriptors 1024
-v: address space (kb) unlimited
-w: locks unlimited
-e: scheduling priority 0
-r: real-time priority 0
3、使用core文件
在core文件所在目录下键入:
gdb -c core
它会启动GNU的调试器,来调试core文件,并且会显示生成此core文件的程序名,中止此程序的信号等等
如果你已经知道是由什么程序生成此core文件的,比如MyServer崩溃了生成core.12345,那么用此指令调试:
gdb -c core MyServer
以下怎么办就该去学习gdb的使用了
也可以:
gdb [exec file] [core file]
如:
gdb ./test test.core
在进入gdb后, 用bt命令或者where命令,查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件->行.
4、一个小方法来测试产生core文件
直接输入指令: kill -11 [pid] 杀掉相应的进程,即可生成core文件。
注意:生成的core文件的路径一般是运行该程序的路径,如果没有设置生成的文件名的规则的话,默认是 core.
5、举例
Hi3536上
# ulimit -a
-f: file size (blocks) unlimited
-t: cpu time (seconds) unlimited
-d: data seg size (kb) unlimited
-s: stack size (kb) 2048
-c: core file size (blocks) unlimited
-m: resident set size (kb) unlimited
-l: locked memory (kb) 64
-p: processes 1359
-n: file descriptors 1024
-v: address space (kb) unlimited
-w: locks unlimited
-e: scheduling priority 0
-r: real-time priority 0
# ps
PID USER VSZ STAT COMMAND
……
1852 root 2796 S -sh
1867 root 5696 S tcpdump
1886 root 2660 S sleep 10
1887 root 3124 R ps
13700 root 2796 S -/bin/sh
#
#
#
# kill -11 1867
# [512369.175584] device eth0 left promiscuous mode
在另外一个终端上
# tcpdump
……
19:18:49.774144 IP 208.208.88.160.62327 > 208.208.88.110.23: Flags [.], ack 37811400, win 2789, options [nop,nop,TS[|tcp]>
19:18:49.774160 IP 208.208.88.110.23 > 208.208.88.160.62327: Flags [P.], ack 1, win 227, options [nop,nop,TS[|tcp]>
19:18:49.774283 IP 208.208.88.160.62327 > 208.208.88.110.23: Flags [.], ack 37811641, win 2789, options [nop,nop,TS[|tcp]>
Segmentation fault (core dumped)
生成core文件
# ls -lh
drwxr-xr-x 2 0 Jan 1 1970 ActiveX
drwxrwxrwx 2 0 Jan 25 01:04 bin
-rw------- 1 1.1M Feb 24 19:18 core
drwxrwxrwt 5 2.9K Jan 1 1970 dev
drwxrwxrwx 3 0 Jan 25 01:03 driverfile
drwxrwxrwt 5 360 Jan 1 1970 etc
drwxrwxrwx 2 0 Jan 25 01:03 home
lrwxrwxrwx 1 10 Jan 25 01:04 init -> /sbin/init
drwxrwxrwx 3 0 Dec 5 11:56 lib
lrwxrwxrwx 1 12 Jan 25 01:04 linuxrc -> /bin/busybox
drwxrwxrwx 2 0 Jan 25 01:03 mnt
drwxrwxrwx 2 0 Jan 25 01:03 opt
dr-xr-xr-x 64 0 Jan 1 1970 proc
drwxrwxrwx 2 0 Jan 25 01:04 root
drwxrwxrwx 2 0 Jan 25 01:04 sbin
dr-xr-xr-x 13 0 Jan 1 1970 sys
drwxrwxrwx 2 0 Jan 25 01:04 sysres
drwxrwxrwt 2 40 Jan 1 1970 tmp
drwxrwxrwx 7 0 Jan 25 01:04 usr
drwxrwxrwt 7 140 Feb 24 04:00 var
-rwxrwxrwx 1 211 Jan 25 01:03 zlog.conf
生成的core文件在根目录下,core大小要比进程占用的虚拟内存大两倍。
注意的问题:
在Linux下要保证程序崩溃时生成Coredump要注意这些问题:
一、要保证存放Coredump的目录存在且进程对该目 录有写权限。存放Coredump的目录即进程的当前目录,一般就是当初发出命令启动该进程时所在的目录。但如果是通过脚本启动,则脚本可能会修改当前目 录,这时进程真正的当前目录就会与当初执行脚本所在目录不同。这时可以查看”/proc/<进程pid>/cwd“符号链接的目标来确定进程 真正的当前目录地址。通过系统服务启动的进程也可通过这一方法查看。
二、若程序调用了seteuid()/setegid()改变 了进程的有效用户或组,则在默认情况下系统不会为这些进程生成Coredump。很多服务程序都会调用seteuid(),如MySQL,不论你用什么用 户运行mysqld_safe启动MySQL,mysqld进行的有效用户始终是msyql用户。如果你当初是以用户A运行了某个程序,但在ps里看到的 这个程序的用户却是B的话,那么这些进程就是调用了seteuid了。为了能够让这些进程生成core dump,需要将/proc/sys/fs /suid_dumpable文件的内容改为1(一般默认是0)。
三、这个一般都知道,就是要设置足够大的Core文件大小限制 了。程序崩溃时生成的Core文件大小即为程序运行时占用的内存大小。但程序崩溃时的行为不可按平常时的行为来估计,比如缓冲区溢出等错误可能导致堆栈被 破坏,因此经常会出现某个变量的值被修改成乱七八糟的,然后程序用这个大小去申请内存就可能导致程序比平常时多占用很多内存。因此无论程序正常运行时占用 的内存多么少,要保证生成Core文件还是将大小限制设为unlimited为好。
四、linux的前31个信号中,有将近一半的信号的默认动作就是dump,生成core文件,假如在代码中恰好注册了这些信号,并且自定义了信号处理函数,那么,如果代码中出现错误产生了这些信号,就不会再生成core文件。比如常用的11(SIGSEGV),一旦代码里监听了这个信号,那么内存访问异常的时候就不会有core文件生成。