linux下core文件调试方法
core,调试
在程序不寻常退出时,内核会在当前工作目录下生成一个core
文件(是一个内存映像,同时加上调试信息)。
使用gdb
来查看core
文件,可以指示出导致程序出错的代码所在文件和行数。
1.core
文件的生成开关和大小限制
a. 使用ulimit -c
命令可查看core
文件的生成开关。
若结果为0
,则表示关闭了此功能,不会生成core
文件。
b. 使用ulimit -c filesize
命令,可以限制core
文件的大小(filesize
的单位为kbyte
)。
若ulimit -c unlimited
,则表示core
文件的大小不受限制。
如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core
文件。在调试此core
文件的时候,gdb
会提示错误。
2.core
文件的名称和生成路径
core
文件生成路径:输入可执行文件运行命令的同一路径下。
若系统生成的core
文件不带其它任何扩展名称,则全部命名为core
。新的core
文件生成将覆盖原来的core
文件。
a. /proc/sys/kernel/core_uses_pid
可以控制core
文件的文件名中是否添加pid
作为扩展。文件内容为1
,表示添加pid
作为扩展名,生成的core
文件格式为core.xxxx
;为0
则表示生成的core
文件统一命名为core
。
可通过以下命令修改此文件:echo "1" > /proc/sys/kernel/core_uses_pid
b. proc/sys/kernel/core_pattern
可以控制core
文件保存位置和文件名格式。
可通过以下命令修改此文件:echo "/corefile/core-%e-%p-%t" > core_pattern
,可以将core
文件统一生成到/corefile
目录下,产生的文件名为:core-命令名-pid-时间戳
.
以下是参数列表:
%p - insert pid into filename
添加pid
%u - insert current uid into filename
添加当前uid
%g - insert current gid into filename
添加当前gid
%s - insert signal that caused the coredump into the filename
添加导致产生core
的信号
%t - insert UNIX time that the coredump occurred into filename
添加core
文件生成时的unix
时间
%h - insert hostname where the coredump happened into filename
添加主机名
%e - insert coredumping executable name into filename
添加命令名
3.core
文件的查看
core
文件需要使用gdb
来查看。
如:gdb ./a.out core-file core.xxxx
使用bt
命令即可看到程序出错的地方。以下两种命令方式具有相同的效果,但是在有些环境下不生效,所以推荐使用上面的命令。
gdb -core=core.xxxx
file ./a.out
bt
b. gdb -c core.xxxx
file ./a.out
bt
4.开发板上使用core
文件调试
如果开发板的操作系统也是linux
,core
调试方法依然适用。
如果开发板上不支持gdb
,可将开发板的环境(依赖库)、可执行文件和core
文件拷贝到PC
的linux
下。
在 PC
上调试开发板上产生的core
文件,需要使用交叉编译器自带的gdb
,并且需要在gdb
中指定solib-absolute-prefix
和 solib-search-path
两个变量,以保证gdb
能够找到可执行程序的依赖库路径。
有一种建立配置文件的方法,不需要每次启动gdb
都配置以上变量,即:在待运行gdb
的路径下建立.gdbinit
。
配置文件内容:
set solib-absolute-prefix YOUR_CROSS_COMPILE_PATH
set solib-search-path YOUR_CROSS_COMPILE_PATH
set solib-search-path YOUR_DEVELOPER_TOOLS_LIB_PATH
handle SIG32 nostop noprint pass
注意:待调试的可执行文件,在编译的时候需要加-g
,core
文件才能正常显示出错信息!
有时候core
信息很大,超出了开发板的空间限制,生成的core
信息会残缺不全而无法使用,可以通过挂载到PC
的方式来规避这一点。
使用core
文件调试程序,看下面的例子:
/*core_dump_test.c*/
#include <stdio.h>
const char *str = "test";
void core_test()
{
str[1] = 'T';
}
int main()
{
core_test();
return 0;
}
编译:gcc –g core_dump_test.c -o core_dump_test
如果需要调试程序的话,使用gcc
编译时加上-g
选项,这样调试core
文件的时候比较容易找到错误的地方。执行:./core_dump_test
段错误,运行core_dump_test
程序出现了“段错误”,但没有产生core
文件。这是因为系统默认core
文件的大小为0
,所以没有创建。可以用ulimit
命令查看和修改core
文件的大小。
执行:ulimit -c
执行:ulimit -c 1000
执行:ulimit -c
-c
指定修改core
文件的大小,1000
指定了core
文件大小。也可以对core
文件的大小不做限制,如:
执行:ulimit -c unlimited
执行:ulimit -c
如果想让修改永久生效,则需要修改配置文件,如 .bash_profile、/etc/profile或/etc/security/limits.conf
。
再次执行:./core_dump_test
段错误 (core dumped
)
执行:ls core.*
可以看到已经创建了一个core.6133
的文件.6133
是core_dump_test
程序运行的进程ID
。
在Linux
下可以用GDB
来调试core
文件。
执行:gdb core_dump_test core.6133
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it
under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
Core was generated by `./core_dump_test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x080482fd in core_test () at core_dump_test.c:7
7 str[1] = 'T';
执行:bt
#0 0x080482fd in core_test () at core_dump_test.c:7
#1 0x08048317 in main () at core_dump_test.c:12
#2 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6
GDB
中键入bt
,就会看到程序崩溃时堆栈信息
当前函数之前的所有已调用函数的列表(包括当前函数),gdb
只显示最近几个,我们很容易找到我们的程序在最后崩溃的时候调用了core_dump_test.c
.第7
行的代码,导致程序崩溃。注意:在编译程序的时候要加入选项-g
。您也可以试试其他命令,如fram、list
等。更详细的用法,请查阅GDB
文档。
什么时候不产生core
文件,在下列条件下不产生core
文件:
a 进程是设置-用户-ID
,而且当前用户并非程序文件的所有者;
b 进程是设置-组-ID
,而且当前用户并非该程序文件的组所有者;
c 用户没有写当前工作目录的许可权;
d 文件太大。
core
文件的许可权(假定该文件在此之前并不存在)通常是用户读/写,组读和其他读。
调试其他环境core
调试其他环境的core
(1). gdb
(2). set solib-search-path libs
输入后TAB
键libs
会取当前目录下的libs****
(3). set solib-absolute-prefix libs
输入Tab
,同2
(4). file libs***/bin/hsserver
(5). core-file core.***
看其他级别的栈:f no
更多推荐
所有评论(0)