使用GDB调试(上篇:配置、分析core文件)

在Linux系统中配置生成用于GDB分析的core dump(核心转储)文件,可以按照以下步骤进行:

步骤 1: 核心转储使能设置
首先,你需要确认系统的核心转储设置是否符合要求。可以通过以下命令检查当前设置:

bashCopy Code
ulimit -c
  1.临时配置

  这个命令会显示核心转储文件的最大大小。如果输出为 0,则表示核心转储功能被禁用。你可以使用以下命令临时修改为不限制大小:

  bashCopy Code
    ulimit -c unlimited

  2.永久配置系统打开生成核心转储文件

永久性配置: 如果希望永久性地修改核心转储设置,可以编辑 /etc/security/limits.conf 文件,添加如下内容:

Copy Code
*        hard    core    unlimited
这会使得所有用户的核心转储文件大小限制为无限制。

    格式是<domain>        <type>  <item>  <value>
		
		#<domain> can be:
		# - a user name
		# - a group name, with @group syntax
		# - the wildcard *, for default entry
		# - the wildcard %, can be also used with %group syntax,
		# for maxlogin limit
		#
		#<type> can have the two values:
		# - "soft" for enforcing the soft limits
		# - "hard" for enforcing hard limits
		#
		#<item> can be one of the following:
		# - core - limits the core file size (KB)
		# - data - max data size (KB)
		# - fsize - maximum filesize (KB)
		# - memlock - max locked-in-memory address space (KB)
		# - nofile - max number of open file descriptors
		# - rss - max resident set size (KB)
		# - stack - max stack size (KB)
		# - cpu - max CPU time (MIN)
		# - nproc - max number of processes
		# - as - address space limit (KB)
		# - maxlogins - max number of logins for this user
		# - maxsyslogins - max number of logins on the system
		# - priority - the priority to run user process with
		# - locks - max number of file locks the user can hold
		# - sigpending - max number of pending signals
		# - msgqueue - max memory used by POSIX message queues (bytes)
		# - nice - max nice priority allowed to raise to values: [-20, 19]
		# - rtprio - max realtime priority
		#
		#<domain> <type> <item> <value>

 

步骤 2: 核心文件存放位置
核心转储文件默认情况下会存放在进程的当前工作目录下,通常以 core 为文件名前缀。你可以通过修改 /proc/sys/kernel/core_pattern 文件来自定义核心转储文件的存放位置和命名规则。

例如,通过以下命令查看当前的核心转储文件设置:

	bashCopy Code
	cat /proc/sys/kernel/core_pattern
默认情况下,可能会显示类似于 /var/core/core.%e.%p.%h.%t 的设置,其中 %e 表示可执行文件名,%p 表示进程ID,%h 表示主机名,%t 表示时间戳。你可以根据需要自定义这个模式,确保目录存在并且有合适的权限。

  /var/core/core.%e.%p.%h.%t,这个模式使用了一些特殊变量:

	%e:可执行文件名。
	%p:进程ID。
	%h:主机名。
	%t:时间戳。
	%s:线程ID。
	临时修改:

	echo "/tmp/core.%e.%p.%h.%t" > /proc/sys/kernel/core_pattern

永久修改:

要永久修改核心转储文件的存放位置,你需要编辑系统的配置文件,通常是 			  /etc/sysctl.conf 或 /etc/sysctl.d/coredump.conf,然后sysctl --system或重启系统以确保修改生效

里面有这配置项

	kernel.core_pattern = /new/path/core.%e.%p.%t

 

比如某嵌入式开发板的

	/etc/sysctl.d/10-default.conf文件就有以下配置

	kernel.core_pattern = /tmp/core.%e.%p.%t.%s

对于10-default.conf文件名,内核参数通常会根据文件名的数字前缀顺序加载,因此较高数字的文件(如99-xxx.conf)会在较低数字的文件(如10-xxx.conf)之后加载。这种顺序控制对于参数之间的依赖关系和优先级很重要

 

Ubuntu20的是用脚本配置

在启动脚本etc/init.d/apport中:

  echo "|$AGENT -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E" > /proc/sys/kernel/core_pattern

cat /proc/sys/kernel/core_pattern后可以看到
  |/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E

 

这个配置文件/proc/sys/kernel/core_pattern指定了系统在出现核心转储(core dump)时,将核心转储的信息传递给apport工具,配置完了sysctl -p或重启生效

|/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E
。具体参数的含义如下:

	-p%p: 进程号(PID)
	-s%s: 信号号
	-c%c: CPU 核心号
	-d%d: 当前工作目录
	-P%P: 父进程的 PID
	-u%u: 用户 ID
	-g%g: 用户组 ID
	--: 分隔符,之后是核心文件的路径 %E
所以,当系统发生核心转储时,这个配置会将相关的信息传递给apport工具,用于处理和记录核心转储信息。Apport(应用程序错误报告)是一个用于处理和报告应用程序崩溃、错误和异常的工具。它主要用于Ubuntu及其衍生发行版中,用来捕获程序崩溃时的核心转储(core dump)和其他相关信息,然后生成错误报告并向开发者或维护团队发送。

 

可以在自启动脚本中,加入这两句命令也达到永久配置效果

	ulimit -c unlimited
	
	echo "/new/path/core.%e.%p.%t" > /proc/sys/kernel/core_pattern

 

 

步骤 3: 测试核心转储功能
为了验证配置是否生效,可以创建一个简单的程序,例如 test.c:

cCopy Code
#include <stdio.h>
#include <stdlib.h>

void segfault() {
    char *ptr = NULL;
    *ptr = 'a';  // 引发段错误
}

int main() {
    segfault();
    return 0;
}
编译并运行该程序:

bashCopy Code
gcc test.c -o test
./test
如果一切配置正确,会在程序运行时生成一个名为 core 的文件(或者根据你设置的模式生成的文件),你可以用 GDB 进行后续分析:

bashCopy Code
gdb ./test core

在这里插入图片描述
在这里插入图片描述
如果不加-g选项进行编译时,就会提示no debug信息,解开core文件后,看到的信息相对比较少,这里是只有函数信息

加入-g编译后
在这里插入图片描述
在这里插入图片描述
解开core文件后,看到的信息比较多,可以定位到代码的这一行

当有依赖库时,可以使用以下方式运行

先运行gdb

set auto-load safe-path / 加载自动加载的文件时,只从根目录开始寻找并加载,对于安全性很重要,因为它限制了 GDB 在加载文件时的搜索路径
set solib-search-path /lib /usr/lib 允许你设置一个或多个目录路径,告诉 GDB 在这些路径下搜索共享库文件.也可以使用冒号连接/lib:/usr/lib

set solib-absolute-prefix /lib /usr/lib 设置共享库文件所在的绝对路径前缀
file /bin/test_g 设置对应coredump的可执行文件(应用)
core-file tmp/core.test_g.7475.549.1722910610 设置对应coredump文件

可以写成脚本,解析coredump文件

gdb_parse.sh

#!/bin/bash
# File: gdb_parse.sh
# Brief: A bash script to quickly run arm-gdb on core files for the Gen GM12 project
# ./gdb_parse.sh  /bin/test_g /tmp/core.test_g.2396.1662184593
#可以导入环境变量
#source ./env_init.sh  

if [ $# -ne 2 ]; then
    echo "Invalid arguments"
    echo "usage: $0 <Binary Path> <Core-file Path>"
    exit
fi

BINARY=$1
CORE_FILE=$2
#配置gdb路径,如果是arm的,可以配置绝对路径。导入环境后,也可以配置相对路径

ARM_GDB=xxx/xxx/xxx/xxxx/gdb

function gdb_check
{
    printOut "Check if xxxx/gdb  exists."
    if [ -f "$ARM_GDB" ];then
        echo -e "Found $ARM_GDB \n"
    else
       echo -e "$ARM_GDB not found!exit gdb \n"
       exit
    fi
}

function gdb_parse
{
    echo -e "Start GDB\n"
  $ARM_GDB << GDB_SHELL
  set auto-load safe-path /
  set solib-search-path /lib:/usr/lib
  file $BINARY
  core-file $CORE_FILE
  bt full
  GDB_SHELL
}
gdb_check
gdb_parse

还可以使用以下的命令进一步分析

1.分析堆栈信息
一旦 GDB 加载了 core 文件,它会显示程序崩溃时的堆栈信息。可以使用 bt 命令查看完整的堆栈回溯:

(gdb) bt
#0  0x0000555555555206 in main () at crash_example.c:5
这里显示了程序在 crash_example.c 文件的第 5 行崩溃。通过查看堆栈信息,可以了解到程序是如何到达崩溃点的。

2.查看变量状态
可以使用 print 命令查看变量的当前状态。例如,假设我们想查看某个变量的值:

(gdb) print some_variable
这将显示 some_variable 的当前值。

3.分析内存状态
可以查看内存中特定地址的内容。例如,查看某个地址的内容:

(gdb) x/10xg 0x7fffffffde60  // 查看地址0x7fffffffde60处的10个64位长字
这在分析特定内存区域时非常有用。

4.查看源代码和行号
list: 查看当前位置附近的源代码。
(gdb) list
list <function_name>: 查看特定函数的源代码。
(gdb) list main

5.查看内存和寄存器状态
info registers: 查看当前寄存器的值。
(gdb) info registers
x/<n><fmt> <address>: 以不同格式查看内存中的数据。
(gdb) x/4xw 0x7fffffffe080  // 查看地址0x7fffffffe080处的四个字(每个字为32位)

6.管理线程和进程
info threads: 查看当前线程的信息。
(gdb) info threads
thread <id>: 切换到特定的线程。
(gdb) thread 2
  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值