GDB调试的三种方式:
1. 目标板直接使用GDB进行调试。
2. 目标板使用gdbserver,主机使用xxx-linux-gdb作为客户端。
3. 目标板使用ulimit -c unlimited,生成core文件;然后主机使用xxx-linux-gdb ./test ./core。
1. gdb调试
2. gdb+gdbserver远程调试
3. core dump离线分析
在目标板上执行ulimit -c unlimited,执行应用程序。
程序出错后,会在当前目录下生成core文件。
将core文件拷出后,再PC上执行xxx-linux-gdb ./test ./core进行分析。
3.1 加载库文件
在运行xxx-linux-gdb ./test ./core之后,可能存在库文件关联不上的情况。
使用info sharedlibrary,查看库加载情况。
From To Syms Read Shared Object Library No xxx.so No /lib/libdl.so.2 No /lib/libpthread.so.0 0x2ab6ec00 0x2ac09ba4 Yes xxx/lib/libstdc++.so.6 No /lib/libm.so.6 0x2acec460 0x2acf626c Yes xxx/lib/libgcc_s.so.1 No /lib/libc.so.6 No /lib/ld.so.1
可以通过set solib-search-path和set solib-absolute-prefix来设置,对应库所在的路径。
From To Syms Read Shared Object Library 0x2aaca050 0x2aacc8d0 Yes xxx.so 0x2aad0ad0 0x2aad17ac Yes (*) xxx/lib/libdl.so.2 0x2aad8a50 0x2aae7434 Yes (*) xxx/lib/libpthread.so.0 0x2ab6ec00 0x2ac09ba4 Yes xxx/lib/libstdc++.so.6 0x2ac4b3d0 0x2acb1988 Yes xxx/lib/libm.so.6 0x2acec460 0x2acf626c Yes xxx/lib/libgcc_s.so.1 0x2ad17b80 0x2adf699e Yes xxx/lib/libc.so.6 0x2aaa89e0 0x2aabf66c Yes (*) xxx/lib/ld.so.1 (*): Shared library is missing debugging information.
可以看出相关库文件都已经加载,只是部分库文件没有调试信息。
3.2 查看backtrace
查看coredump的backtrace通过bt即可,更全的信息通过bt full。
产看函数调用栈的几个函数
bt:显示所有的函数调用栈帧的信息,每个帧一行。
bt n:显示栈定的n个帧信息。
bt -n:显示栈底的n个帧信息。
bt full:显示栈中所有帧的完全信息如:函数参数,本地变量。
bt full n:用法同上。
bt full -n
(gdb) bt #0 0x2ad71f1e in memcpy () from xxx/lib/libc.so.6 #1 0x2ad71ac0 in memmove () from xxx/lib/libc.so.6 #2 0x0011f36c in std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<unsigned char> (__first=0x34dfb008 "\377\330\377", <incomplete sequence \340>, __last=0x34eeea2c "", ... #3 0x0011ee22 in std::__copy_move_a<false, unsigned char*, unsigned char*> (__first=0x34dfb008 "\377\330\377", <incomplete sequence \340>, __last=0x34eeea2c "", __result=0x2b2013c0 "\377\330\377", <incomplete sequence \340>) at xxxinclude/c++/6.3.0/bits/stl_algobase.h:386 #4 0x0011e7e2 in std::__copy_move_a2<false, __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >, unsigned char*> (__first=..., __last=..., __result=0x2b2013c0 "\377\330\377", <incomplete sequence \340>) at xxx/bits/stl_algobase.h:424 #5 0x0011dfd2 in std::copy<__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >, unsigned char*> (__first=..., __last=..., __result=0x2b2013c0 "\377\330\377", <incomplete sequence \340>) at xxx/6.3.0/bits/stl_algobase.h:456 #6 0x0011c948 in xxx #7 0x00133e08 in xxx #8 0x2aada31e in start_thread () from xxx/libc/lib/libpthread.so.0 #9 0x005a11b4 in ?? ()
3.3 Core Dump核心转存储文件目录和命名规则
默认情况下core文件存在应用当前路径下,为了区分可以进行设置。
区分core主要通过/proc/sys/kernel/core_uses_pid和/proc/sys/kernel/core_pattern进行设置。
/proc/sys/kernel/core_uses_pid:可以控制产生的core文件的文件名中是否添加pid作为扩展,如果添加则文件内容为1,否则为0。
proc/sys/kernel/core_pattern:可以设置格式化的core文件保存位置或文件名,比如原来文件内容是core-%e
echo "/tmp/core-%e-%p" > 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 添加命令名
当然,你可以用下列方式来完成:
sysctl -w kernel.core_pattern=/tmp/core-%e-%p
3.4 ulimit的使用
功能说明:控制shell程序的资源。
语 法:ulimit [-aHS][-c <core文件上限>][-d <数据节区大小>][-f <文件大小>][-m <内存大小>][-n <文件数目>][-p <缓冲区大小>][-s <堆叠大小>][-t <CPU时间>][-u <程序数目>][-v <虚拟内存大小>]
补充说明:ulimit为shell内建指令,可用来控制shell执行程序的资源。
参 数:
-a 显示目前资源限制的设定。
-c <core文件上限> 设定core文件的最大值,单位为区块。
-d <数据节区大小> 程序数据节区的最大值,单位为KB。
-f <文件大小> shell所能建立的最大文件,单位为区块。
-H 设定资源的硬性限制,也就是管理员所设下的限制。
-m <内存大小> 指定可使用内存的上限,单位为KB。
-n <文件数目> 指定同一时间最多可开启的文件数。
-p <缓冲区大小> 指定管道缓冲区的大小,单位512字节。
-s <堆叠大小> 指定堆叠的上限,单位为KB。
-S 设定资源的弹性限制。
-t <CPU时间> 指定CPU使用时间的上限,单位为秒。
-u <程序数目> 用户最多可开启的程序数目。
-v <虚拟内存大小> 指定可使用的虚拟内存上限,单位为KB。
参考文档:
《Linux环境下段错误的产生原因及调试方法小结》《linux应用调试技术之GDB和GDBServer》《gdbServer + gdb 调试》