0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用gdb对core文件进行调试

玩转嵌入式 来源:嵌入式大杂烩 作者:杂烩君 2022-10-26 11:12 次阅读

嵌入式Linux开发中,使用gdb对core文件进行调试是一种有效的定位程序崩溃的方法。

有些知识,在没用到之前,可以简单地进行了解。实际用的时候,再去详细地学习。最近我在实际工作中使用了gdb对core文件进行调试,遇到了一些问题,总结出来分享给大家。

本文我们来分享几点:

什么是core文件?

前台进程如何生成core文件?

后台进程如何生成core文件?

如何调试core文件?

崩溃栈有用信息有限的可能原因?

什么是core文件?

在Linux下,一个程序崩溃时,它一般会在指定目录下生成一个core文件。core文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的。

前台进程如何生成core文件?

实际中,我们的程序可以运行于前台,也可以运行于后台。前、后台运行程序,生成core文件的方法有些不同。

前台进程:一般而言,用户在shell中使用./执行的程序都是前台程序,前台程序可由用户自己控制,程序运行过程中可与用户进行交互,其运行优先级相比后台程序稍高,前台程序运行过程中用户可使用ctrl+c来终止。

core文件配置基本命令:

ulimit-c#查看core文件是否打开
ulimit-a#也可以查看core文件是否打开
ulimit-c0#禁止产生core文件
ulimit-cunlimited#设置core文件大小为不限制大小
ulimit-c1024#限制产生的core文件的大小不能超过1024KB

core文件的转储文件目录和命名规则是可以设置的。

通过配置/proc/sys/kernel/core_uses_pid可以控制产生的core文件的文件名中是否添加pid作为扩展;

通过配置/proc/sys/kernel/core_pattern可以设置格式化的core文件保存位置或文件名。

比如:

设置core文件的文件名中是否添加pid作为扩展

echo"1">/proc/sys/kernel/core_uses_pid

设置格式化的core文件保存位置或文件名

echo"/var/core-%e-%p-%t">/proc/sys/kernel/core_pattern

参数%e、%p、%t表示的意思如:

%p-insertpidintofilename添加pid
%u-insertcurrentuidintofilename添加当前uid
%g-insertcurrentgidintofilename添加当前gid
%s-insertsignalthatcausedthecoredumpintothefilename添加导致产生core的信号
%t-insertUNIXtimethatthecoredumpoccurredintofilename添加core文件生成时的unix时间
%h-inserthostnamewherethecoredumphappenedintofilename添加主机名
%e-insertcoredumpingexecutablenameintofilename添加可执行程序名

下面开始进行实操:

查看core文件是否有打开,并设置core文件大小为不限制大小:

b324f568-4851-11ed-a3b6-dac502259ad0.png

设置格式化的core文件保存位置或文件名:

b34cb012-4851-11ed-a3b6-dac502259ad0.png

测试代码:

#include

intmain(intargc,char**argv)
{
printf("==================segmentationfaulttest==================
");

int*p=NULL;
*p=1234;

return0;
}

运行测试程序生成core文件:

b3684ba6-4851-11ed-a3b6-dac502259ad0.png

后台进程如何生成core文件?

后台程序生成core文件的方式与前台程序不一样。这我也是前几天才知道的,我们设备上的程序设置为开机自启动运行于后台,程序崩溃时,竟然没有生成core文件。后来查了些资料才知道后台程序打开core文件的方式不同。

后台进程:后台进程又叫守护进程,是运行在系统后台的一种特殊进程,它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件,后台进程最大的特点就是不受终端控制。一般用作系统服务,比如日志管理进程rsyslogd,数据库服务myspld等,当然也有一些用户程序因需要被放在后台运行,一般被放在/etc/ini.d/文件夹中设置开机自启动。

ulimit命令是有作用范围的,ulimit限制的是当前shell进程以及其派生的子进程,所以通过ulimit修改coresize只是针对在当前shell下启动的子进程,而不能影响其他shell下启动的进程。

所以当我们配置完成生成core dump的参数后,在当前shell直接执行的进程发生崩溃时可以正常生成core,而后台开机自启动的程序则无法生成,而实际总,嵌入式应用程序一般都是开机自启动的,并且发送崩溃的时机也是不可预测的,那么使用这种方式就不能正确的去捕捉coredump文件了。

后台进程要生成core dump文件需在进程代码中开启core dump功能,如:

左右滑动查看全部代码>>>

//公众号:嵌入式大杂烩
#include
#include
#include
#include

#defineSHELL_CMD_CONF_CORE_FILE"echo/var/core-%e-%p-%t>/proc/sys/kernel/core_pattern"
#defineSHELL_CMD_DEL_CORE_FILE"rm-f/var/core*"

staticintenable_core_dump(void)
{
intret=-1;
intresource=RLIMIT_CORE;
structrlimitrlim;

rlim.rlim_cur=1?RLIM_INFINITY:0;
rlim.rlim_max=1?RLIM_INFINITY:0;

system(SHELL_CMD_DEL_CORE_FILE);

if(0!=setrlimit(resource,&rlim))
{
printf("setrlimiterror!
");
return-1;
}
else
{
system(SHELL_CMD_CONF_CORE_FILE);
printf("SHELL_CMD_CONF_CORE_FILE
");
return0;
}

returnret;
}

intmain(intargc,char**argv)
{
enable_core_dump();

printf("==================segmentationfaulttest==================
");

int*p=NULL;
*p=1234;

return0;
}

让程序开机运行于后台:

在开发板/etc/init.d/目录下新建文件S100Test:

#!/bin/sh
cd/home
./test

设置程序开机自启动可参考我们往期文章:《浅析程序开机自启动》

重启设备,程序运行崩溃时可生成core文件:

b47c107c-4851-11ed-a3b6-dac502259ad0.pngb6b58d14-4851-11ed-a3b6-dac502259ad0.png

调试core文件?

把core文件传到pc端,使用arm-linux-gnueabihf-gdb对test程序进行调试:

arm-linux-gnueabihf-gdbtest
core-filecore-test-190-119
b7131498-4851-11ed-a3b6-dac502259ad0.pngb7266ab6-4851-11ed-a3b6-dac502259ad0.png

崩溃栈信息有限?

这个demo比较简单,可以很快定位到问题。实际中,我们的程序会依赖很多动态库,这时候在调试时需要设置库的搜索路径。

这些库需要和板子上的库对应上,最好是用板子里的库。可以把板子里用到的库放到PC上的某个路径,假如放到/home/LinuxZn/lib这个路径。

我们进入gdb时,可以输入如下命令设置及查看库信息:

setsolib-search-path/home/LinuxZn/lib
infosharedlibrary
b7ded1dc-4851-11ed-a3b6-dac502259ad0.png

有时候,加载库信息之后,还是看不到有意义的崩溃栈。

有如下两点需要确认:

应用程序在编译时没有指定-g选项,导致可执行程序没有调试信息。

板子里的libc库和交叉编译器所使用的libc库版本不一致。

如果不一致,可以把交叉编译器所使用的libc库更新到板子里。






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PID控制
    +关注

    关注

    10

    文章

    460

    浏览量

    40091
  • Linux开发
    +关注

    关注

    0

    文章

    33

    浏览量

    6903
  • GDB调试
    +关注

    关注

    0

    文章

    24

    浏览量

    1447

原文标题:分享一种你可能不知道的bug定位方法

文章出处:【微信号:玩转嵌入式,微信公众号:玩转嵌入式】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    QEMU+GDB调试ARM程序

    通过GDB调试代码的便利性无需赘言。我们直接以调试meta-hypervisor为示例进行说明。
    的头像 发表于 10-08 09:17 2911次阅读

    使用GDB调试Linux应用程序

    本篇讲解使用GDB调试Linux应用程序,以下以 `hellowld.c` 为例介绍 GDB调试入门。
    发表于 06-27 15:48 462次阅读

    如何生成core文件?如何调试core文件

    如何生成core文件?如何调试core文件?如何在gdb交互中查看所依赖库是否正确加载?
    发表于 12-23 08:48

    GDB调试命令手册

    GDB调试命令手册,感兴趣的可以下载看看。
    发表于 11-05 16:36 9次下载

    GDB调试命令总结

    程序,开始调试的方式gdb program core //用gdb查看core dump文件,跟
    发表于 04-02 14:31 1150次阅读

    嵌入式Linux的GDB调试环境建立

    remote :2345  注意:你的端口号必须与gdbserver开启的端口号一致,这样才能进行通信。  建立链接后,就可以进行调试了。调试在Host端,跟
    发表于 04-02 14:33 519次阅读

    段错误调试神器 - Core Dump详解

    core大小为无限. 用gdb查看core文件: 下面我们可以在发生运行时信号引起的错误时发生core dump了. 发生
    发表于 04-02 14:34 1165次阅读

    Linux应用的GDB调试的原理及过程分析

    GDB调试是应用程序在开发板上运行,然后在PC机上对开发板上得应用程序进行调试,PC机运行GDB,开发板上运行GDBServer。在应用程序
    发表于 03-05 09:44 3424次阅读
    Linux应用的<b class='flag-5'>GDB</b><b class='flag-5'>调试</b>的原理及过程分析

    实例演示GDB的使用

    GDB简介 GDB(GNU Debugger)是一个强大的命令行调试工具。一般的,在Windows下进行开发,很少操控命令行调试
    的头像 发表于 10-19 09:58 2694次阅读
    实例演示<b class='flag-5'>GDB</b>的使用

    GDB调试原理是什么?

    没有用过,那只能说明你的开发经历还不够坎坷,还需要继续被 BUG吊打。   我们都知道,在使用gcc编译时,可以使用-g选项在可执行文件中嵌入更多的调试信息,那么具体嵌入了哪些调试信息?这些
    的头像 发表于 12-18 15:17 5771次阅读

    嵌入式Linux GDB调试环境搭建与使用

    /跳出函数、设置断点、查看变量等等。Ubuntu资源充足,可以直接用gdb调试程序。嵌入式Linux性能弱,一般PC上运行源码和GDB工具,可执行文件在开发板上运行。PC上通过
    发表于 11-01 17:59 8次下载
    嵌入式Linux <b class='flag-5'>GDB</b><b class='flag-5'>调试</b>环境搭建与使用

    在ubuntu中调试GDB

    编译后会产生 gdbtest 文件 调试命令: gdb xxx 会出现一个 (gdb)的指示符,等待你输入命令,可用的命令如下: 当然不止这些,还有很多,常用的就这几个
    的头像 发表于 07-27 16:31 1053次阅读
    在ubuntu中<b class='flag-5'>调试</b><b class='flag-5'>GDB</b>

    GDB调试工具的原理

    了。 1.2 执行中进程调试 如果想对一个已经执行的进程进行调试,那么就要在gdb这个父进程中调用ptrace(PTRACE_ATTA
    的头像 发表于 11-09 17:04 937次阅读
    <b class='flag-5'>GDB</b><b class='flag-5'>调试</b>工具的原理

    如何使用GDB调试工具

    在对应程序目录中使用下面的命令 gdb test 2、调试已经开始运行的程序进程 调试已经开始运行的程序进程,首先先用top命令查看运行的程序进程的pid如下: 比如我要加载的程序
    的头像 发表于 11-09 17:17 848次阅读
    如何使用<b class='flag-5'>GDB</b><b class='flag-5'>调试</b>工具

    如何使用linux下gdb调试python程序

    GDB: ``` $ sudo apt install gdb ``` 安装完成后,需要安装Python调试符号。这些符号文件包含了Python解释器的
    的头像 发表于 01-31 10:41 2595次阅读