分享一种你可能不知道的bug定位方法

嵌入式大杂烩 嵌入式大杂烩     2022-10-22     593

关键词:

大家好,我是杂烩君。

嵌入式Linux开发中,使用gdb对core文件进行调试是一种有效的定位程序崩溃的方法。这种方法我们在之前的文章中也有简单提过:嵌入式段错误的3种调试方法汇总!

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

本文我们来分享几点:

  • 什么是core文件?

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

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

  • 如何调试core文件?

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

什么是core文件?

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

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

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

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

core文件配置基本命令:

ulimit -c   # 查看core文件是否打开
ulimit -a   # 也可以查看core文件是否打开
ulimit -c 0 # 禁止产生core文件
ulimit -c unlimited  #设置core文件大小为不限制大小
ulimit -c 1024   #限制产生的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 - 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 添加可执行程序名

下面开始进行实操:

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

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

测试代码:

#include <stdio.h>

int main(int argc, char **argv)

    printf("==================segmentation fault test==================\\n");

    int *p = NULL;
    *p = 1234;

    return 0;

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

后台进程如何生成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 <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>

#define SHELL_CMD_CONF_CORE_FILE    "echo /var/core-%e-%p-%t > /proc/sys/kernel/core_pattern"
#define SHELL_CMD_DEL_CORE_FILE     "rm -f /var/core*"

static int enable_core_dump(void)

    int ret = -1;
    int resource = RLIMIT_CORE;
    struct rlimit rlim;

    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("setrlimit error!\\n");
        return -1;
    
    else
    
        system(SHELL_CMD_CONF_CORE_FILE);
        printf("SHELL_CMD_CONF_CORE_FILE\\n");
        return 0;
    

    return ret;


int main(int argc, char **argv)

    enable_core_dump();

    printf("==================segmentation fault test==================\\n");

    int *p = NULL;
    *p = 1234;

    return 0;

让程序开机运行于后台:

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

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

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

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

调试core文件?

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

arm-linux-gnueabihf-gdb test
core-file core-test-190-119

崩溃栈信息有限?

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

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

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

set solib-search-path /home/LinuxZn/lib
info sharedlibrary

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

有如下两点需要确认:

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

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

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

参考:

https://baijiahao.baidu.com/s?id=1661025717994426637&wfr=spider&for=pc
https://blog.csdn.net/lhl_blog/article/details/106542754

以上就是本次的分享,期待你的三连!

猜你喜欢:

嵌入式大杂烩周记 | 第 8 期 AMetal

分享一种修改配置文件的方法

《嵌入式大杂烩周记第 13 期:lz4》

《嵌入式并行多线程处理器,了解一下!》

《分享一种修改配置文件的方法》

《分享几个实用的代码片段(附代码例子)》

《废旧板子再利用:搭建无线调试环境!》

《嵌入式段错误的3种调试方法汇总!》

《简说TCP通信非阻塞接收(附代码例子)》

《嵌入式中,TCP server如何与多个client通信?》

《嵌入式中,TCP通信常用接口的使用封装》

《写国际化的嵌入式代码,时间问题如何处理?》

《Linux命令行万能解压命令》

《嵌入式软件中,总线错误的坑?替大家先踩一步》

《分享嵌入式软件调试方法及几个有用的工具!》

《分享两点提高编程能力的建议!》

《嵌入式开发中常见3个的C语言技巧》

《分享几个嵌入式 C 中的实用技巧》

在公众号聊天界面回复1024,可获取嵌入式资源;回复 m ,可查看文章汇总。

点击阅读原文,查看更多分享

css的三种样式,有一种你肯定不知道

 前言本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。作者LFuser正文新手注意:如果你学习遇到问题找不到人解答,可以点我进裙,里面大佬解... 查看详情

2不会定位bug根本原因的你,该清醒了

...三年后,你能力与应届生一致,工资还比应届生高,公司可能考虑你的位置和薪资(开?还是不开但薪资不涨)。不会发现异常bug,不会发现深层次的bug,定位一些bug,提前发现bug你只会循环迭代版本,执行用例,提交表象bug,... 查看详情

故事板设计模式(分享或不分享)

】故事板设计模式(分享或不分享)【英文标题】:Storyboarddesignpattern(toshareornottoshare)【发布时间】:2015-06-2817:19:23【问题描述】:这可能在很大程度上是优惠的,但我想知道是否有任何理由来决定这种或另一种方式。在使用故... 查看详情

jquery模拟字母顺序排序定位城市列表方法(bug改进)

....com/jquery/3155.htmlbug重庆--长沙不能正常排序.原因是derail有可能会放回两个字符的数组。需要做判断改进    //改动特殊字符-->可能还有问题--返回的是数组有两个字符    var 查看详情

定位bug

...常流程了,才能去判断这个bug到底是哪个环节出的问题,可能出现这样问题的原因是什么,应该怎么处理才是正确 查看详情

为啥苹果手机截图不能分享到微信?

...截图后直接发朋友圈或微信。您好,苹果截图后可以进行分享,不少小伙伴们发现自己在进行分享的时候不知道怎么回事微信分享不了,想要知道为什么分享不了的,就让小编给大家详细的讲讲吧。苹果截图无法微信分享无法分... 查看详情

分享取实际网卡mac地址的一种方法

...块,后来想到了一种歪门邪道的方法,在这里做个笔记和分享。 &nb 查看详情

如何用python实时监控文件?方法有三种你喜欢哪一种?

在业务稳定性要求比较高的情况下,运维为能及时发现问题,有时需要对应用程序的日志进行实时分析,当符合某个条件时就立刻报警,而不是被动等待出问题后去解决,比如要监控nginx的requesttime和request_time... 查看详情

学会有效管理自己知识:思考+总结+分享

...表达的道理又有多少呢?我在反思自己,希望与你共勉!分享:好的学习方法— 查看详情

记一次spring自定义切面不执行bug定位(代码片段)

背景项目中,一个第三方jar包提供的方法无法满足需求,需要对jar包方法进行增强。使用了Spring的自定义切面进行方法的增强。代码如下:@Aspect@ComponentpublicclassSendMessageAspectpublicSendMessageAspect()System.out.println("测试... 查看详情

java应用压测性能问题定位经验分享

什么是压测压测,即压力测试,是确立系统稳定性的一种测试方法,通常在系统正常运作范围之外进行,以考察其功能极限和和可能存在的隐患。压测主要用于检测服务器的承受能力,包括用户承受能力,... 查看详情

分享式商业模型

...像是一个讲商业模式的枯燥文章,其实没那么严肃,只是分享点故事:)。关于商业,我感觉自己几乎一无所知。因为,我曾经唯一做过的生意是一种「合作/分享」式商业模型。它的模式如下:第一步:你有一些人们想要的东西。... 查看详情

经验分享:程序员如何快速定位问题(bug)(代码片段)

让我掉下眼泪的不止内存泄漏让我夜夜不眠的不止你的需求明天还要改多久你攥着我的手让我感到为难的是善变的需求发布总是在半夜回滚是永远的愁错误(Bug)随时的暴漏困扰着我心头作为程序员,以上这些场景你一定都经历过... 查看详情

liunx定位io瓶颈方法

...stat等等,但经常会忽略IO的负载情况),今天给大家详细分享一下如何确认一台服务器的IO负载是否到达了瓶颈,以及可能优化、定位的点。先来看一台典型的IO密集型服务器的cpu统计图:可以看到,CPU总使用率不高,平均1.3%,m... 查看详情

a标签可能会出现的bug

在项目中a标签遇到过的问题发现问题:a标签包装的按钮,如果这个按钮在页面滚动后出现,你点击后,页面会定位到滚动以前的位置,但是我并不想要这种效果。分析问题并尝试: 一开始以为是光标定位问题,用document.getElem... 查看详情

bug定位分析方法(代码片段)

为了能够更好的协助大家定位疑难bug问题,这里总结一些自我的经验给到大家,希望对大家有所帮助对于简单的bug大家轻松定位解决就可以了,但是对于疑难复杂的bug这里我们分为5个核心流程方法,其中包括࿱... 查看详情

chrometransition闪烁bug

...用top实现),虽然不知道原因,但是问题还是要解决的,分享一个能绕开的实现方式。    说到鼠标悬停元素上移,首先想到的是鼠标悬停时元素上移,然后应用transition来实现渐变效果。 &n 查看详情

偶发异常bug,如何高效精准分析排查定位?

...测试人员收到问题的反应:需求没说这样?不是BUG?怎么可能是BUG?这个我们测过的怎么会有问题?肯定是环境问题?肯定是程序偷偷改了东西的?昨天还是好的呢?今天怎么这样了? 作为专业测试,我们应保持大度、精心... 查看详情