Linux操作系统是一款开源的,使用极其广泛的操作系统。在我们进行软件开发或是系统维护的过程中,难免会遇到一些问题,此时就需要进行调试了。在Linux系统中,一种非常常见的调试方法就是通过分析core文件来进行问题排查,本文就将详细介绍如何通过Linux命令进行分析core文件以进行调试。
创新互联建站是一家专业从事成都网站建设、做网站、网页设计的品牌网络公司。如今是成都地区具影响力的网站设计公司,作为专业的成都网站建设公司,创新互联建站依托强大的技术实力、以及多年的网站运营经验,为您提供专业的成都网站建设、营销型网站建设及网站设计开发服务!
一、什么是core文件
在Linux系统中,当一个进程崩溃时,系统就会生成一个称为core文件的文件。core文件包含了进程崩溃时的内存状态、寄存器状态、程序指针等信息,通常会非常的大(通常情况下都是进程崩溃原因的关键提示)。这些信息都可以被用来定位问题的位置和原因。
二、如何生成core文件
要生成core文件,我们需要做两件事情。我们需要确保系统在进程崩溃时可以生成core文件。我们需要使用gdb来调试进程,这样我们才能够使用gdb来分析core文件。
1.系统生成core文件的方式
我们可以通过ulimit命令来查看当前系统允许生成core文件的大小,如果为0则表明系统不会生成core文件。
“`
$ ulimit -c
“`
我们可以通过修改/etc/security/limits.conf文件来确保系统对于某个用户,允许生成core文件。
打开limits.conf文件,并添加以下两行内容:
“`
username soft core unlimited
username hard core unlimited
“`
其中,username表示用户名,soft表示软限制,hard表示硬限制,core表示core文件,unlimited表示无限制。添加完成后,保存并退出文件即可。此时我们可以通过以下命令来检查修改是否生效:
“`
$ ulimit -a
“`
2.使用gdb调试进程生成core文件
首先我们需要编译程序时加入-g选项,这样程序就会包含调试信息。
“`
$ gcc -g mn.c -o mn
“`
接着我们可以通过以下命令启动gdb并附加到进程中:
“`
$ gdb mn
(gdb) run
“`
等待程序运行并崩溃后,会收到以下提示:
“`
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400537 in func ()
(gdb) bt
“`
此时我们可以通过输入bt命令来查看调用堆栈。我们还可以通过设置core文件的大小来确保可以生成core文件。
“`
$ ulimit -c unlimited
“`
设置完成后再次运行程序,等待程序崩溃,此时我们就可以看到在程序运行所在目录下会生成一个名为core的文件,这就是我们要分析的文件。
三、分析core文件
我们可以通过以下命令来分析core文件:
“`
$ gdb mn core
“`
其中,mn为程序的可执行文件,core为要分析的core文件。运行完成后,命令行会提示:
“`
Reading symbols from mn…(no debugging symbols found)…done.
[New LWP 14066]
Core was generated by `./mn’.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000000000400537 in func ()
“`
此时我们可以通过bt命令来查看调用堆栈:
“`
(gdb) bt
“`
除了可以查看调用堆栈外,我们还可以通过以下命令来查看代码:
“`
(gdb) list
“`
同时,我们还可以通过以下命令来查看变量的值:
“`
(gdb) print variable
“`
我们可以通过以下命令来跳转到某一行代码:
“`
(gdb) jump line_number
“`
这样,我们就可以通过分析core文件来定位程序崩溃的原因和位置。
Linux系统中,通过分析core文件来进行调试可以说是非常方便、快速的一种调试方法,可以帮助我们快速定位程序的问题,快速解决问题。上面就是我在使用Linux系统时,通过的方法。希望本文对你有所帮助。
相关问题拓展阅读:
dump文件可以在程序crash时,方便我们查看程序crash的地方和上下文信息。在window下,要能生成dump文件,需要自己编写相应的代码。不过现在网上可以找到相应的代码,只要把它下载后然后加到自己的工程中去,就可以了!
在linux下面就简单的许多。只要打开相应的开关,linux会自动在程序crash时生成相应的core文件。这个文件和window下的dump文件类似。
下面是简单的一些步骤:
1.查看当前是否已经打开了此开关
通过命令:ulimit -c 如果输出为 0
,则代表没有打开。如果为unlimited则已经打开了,就没必要在做打开。
2.通过命令打开
ulimit -c unlimited .然后通过步骤1,可以监测是否打开成功。
3.如果你要取消,很简单:ulimit -c 0 就可以了
通过上面的命令修改后,一般都只是对当前会话起作用,当你下次重新登录后,还是要重新输入上面的命令,所以很麻烦。我们可以把通过修改
/etc/profile文件 来使系统每次自动打开。步骤如下:
1.首先打开/etc/profile文件
一般都可以在文件中找到 这句语句:ulimit -S -c 0 /dev/null
2&1.ok,根据上面的例子,我们只要把那个0 改为
unlimited 就ok了。然后保存退出。
2.通过source /etc/profile 使当期设置生效。
3.通过ulimit -c 查看下是否已经打开。
其实不光这个命令可以加入到/etc/profile文件中,一些其他我们需要每次登录都生效的都可以加入到此文件中,因为登录时linux都会加载此文件。比如一些环境变量的设置。
还有一种方法可以通过修改/etc/security/limits.conf文件来设置,这个方法没有试过,也是网上看到。不过上面两种就可以了!
最后说一下生成core
dump文件的位置,默认位置与可执行程序在同一目录下,文件名是core.***,其中***是一个数字。core
dump文件名的模式保存在/proc/sys/kernel/core_pattern中,缺省值是core。通过以下命令可以更改core
dump文件的位置(如希望生成到/tmp/cores目录下)
echo “/tmp/cores/core”
/proc/sys/kernel/core_pattern
设置完以后我们可以做个测试,写个程序,产生一个异常。然后看到当前目录会有个core*的文件。然后我们可以
gdb core。* 程序 进行调试。
经过分析发现系统默启扒唯认的core文件生成路径是/var/logs,但/var/logs目录并非此蚂系统自带的,系统初始安装默认自带的是/var/log,最终导致该系悄培统出现core dump后并没能生成core文件,因此如何查询和修改系统默认的core dump文件生产路径呢?方法如下:一. 查询core dump文件路径: 方法1:# cat /proc/sys/kernel/core_pattern方法2:# /in/sysctl kernel.core_pattern二. 修改core dump文件路径: 方法1:临时修改:修改/proc/sys/kernel/core_pattern文件,但/proc目录本身是动态加载的,每次系统重启都会重新加载,因此这种方法只能作为临时修改。/proc/sys/kernel/core_pattern例:echo ‘/var/log/%e.core.%p’ > /proc/sys/kernel/core_pattern方法2:永久修改:使用sysctl -w name=value命令。例:/in/sysctl -w kernel.core_pattern=/var/log/%e.core.%p为了更详尽的记录core dump当时的系统状态,可通过以下参数来丰富core文件的命名:%% 单个%字符
一般这种情况都是因为数组越界访问,空指针或是野指针读写造成的。程序小的话还比较好办,对着源代码仔细检查就能解决。但是对于代码量较大的程序,里边包含N多函数调用,N多数组指针访问,这时想定位问题就不是很容易了(此时牛人依然可以通过在适当位置打printf加二分查找的方式迅速定位:P)。懒人的颤晌含话还是直接GDB搞起吧。 神马是Core Dump文件偶尔就能听见某程序员同学抱怨“擦,又出Core了!”。简单来说,core dump说的是操作系统执行的一个动作,当某个进程因为一些原因意外终止(crash)的时候,操作系统会将这个进程当时的内存信息转储(dump)到磁盘上1。产生的文件就是core文件了,一般会以core.xxx形式命名。 如何产生Core Dump 发生doredump一般都是在进程收到某个信号的时候,Linux上谨中现在大概有60多个信号,可以使用 kill -l 命令全部列出来。sagi@sagi-laptop:~$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX针对特定的信号,应用程序可以写对应的信号处理函数。如果不指定,则采取默认的处理方式, 默认处理是coredump的信号如下:3)SIGQUIT 4)SIGILL 6)SIGABRT 8)SIGFPE 11)SIGSEGV 7)SIGBUS 31)SIGSYS 5)SIGTRAP 24)SIGXCPU 25)SIGXFSZ 29)SIGIOT 我们看到SIGSEGV在其中,一般数组越界或是访问空指针都会产生这个信号。另外虽然默认是这样的,但是你也可以写自己的信号处理函数改变默认行为,更多信号相关可以看参考茄笑链接33。 上述内容只是产生coredump的必要条件,而非充分条件。要产生core文件还依赖于程序运行的shell,可以通过ulimit -a命令查看,输出内容大致如下:sagi@sagi-laptop:~$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheng priority (-e) 20 file size (blocks, -f) unlimited pending signals (-i)max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q)real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited 看到之一行了吧,core file size,这个值用来限制产生的core文件大小,超过这个值就不会保存了。我这里输出是0,也就是不会保存core文件,即使产生了,也保存不下来==! 要改变这个设置,可以使用ulimit -c unlimited。 OK, 现在万事具备,只缺一个能产生Core的程序了,介个对C程序员来说太容易了。#include ; #include ; int crash() { char *xxx = “crash!!”; xxx = ‘D’; // 写只读存储区! return 2; } int foo() { return crash(); } int main() { return foo(); } 上手调试 上边的程序编译的时候有一点需要注意,需要带上参数-g, 这样生成的可执行程序中会带上足够的调试信息。编译运行之后你就应该能看见期待已久的“Segment Fault(core dumped)”或是“段错误 (核心已转储)”之类的字眼了。看看当前目录下是不是有个core或是core.xxx的文件。祭出linux下经典的调试器GDB,首先带着core文件载入程序:gdb exefile core,这里需要注意的这个core文件必须是exefile产生的,否则符号表会对不上。载入之后大概是这个样子的:sagi@sagi-laptop:~$ gdb coredump core Core was generated by ./coredump’. Program terminated with signal 11, Segmentation fault. #0 0x080483a7 in crash () at coredump.c:8 8 xxx = ‘D’; (gdb)我们看到已经能直接定位到出core的地方了,在第8行写了一个只读的内存区域导致触发Segment Fault信号。在载入core的时候有个小技巧,如果你事先不知道这个core文件是由哪个程序产生的,你可以先随便找个代替一下,比如/usr/bin/w就是不错的选择。比如我们采用这种方法载入上边产生的core,gdb会有类似的输出:sagi@sagi-laptop:~$ gdb /usr/bin/w core Core was generated by ./coredump’. Program terminated with signal 11, Segmentation fault. #0 0x080483a7 in ? () (gdb)可以看到GDB已经提示你了,这个core是由哪个程序产生的。 GDB 常用操作 上边的程序比较简单,不需要另外的操作就能直接找到问题所在。现实却不是这样的,常常需要进行单步跟踪,设置断点之类的操作才能顺利定位问题。下边列出了GDB一些常用的操作。 启动程序:run设置断点:b 行号|函数名删除断点:delete 断点编号禁用断点:disable 断点编号启用断点:enable 断点编号单步跟踪:next 也可以简写 n单步跟踪:step 也可以简写 s打印变量:print 变量名字设置变量:set var=value查看变量类型:ptype var顺序执行到结束:cont顺序执行到某一行: util lineno打印堆栈信息:btlinux 命令调试分析core文件的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux 命令调试分析core文件,Linux命令分析core文件以进行调试,linux 下如何打开core dump文件开关,如何查询和修改Linux操作系统生成core dump文件的默认路径?,如何使用GDB调试Coredump文件的信息别忘了在本站进行查找喔。
创新互联服务器托管拥有成都T3+级标准机房资源,具备完善的安防设施、三线及BGP网络接入带宽达10T,机柜接入千兆交换机,能够有效保证服务器托管业务安全、可靠、稳定、高效运行;创新互联专注于成都服务器托管租用十余年,得到成都等地区行业客户的一致认可。
分享名称:Linux命令分析core文件以进行调试(linux命令调试分析core文件)
转载源于:http://www.mswzjz.com/qtweb/news18/177518.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联