GDB: coredump

前言:一句话如下使用

gdb [exec_file] [core_file]

# or
gdb -c [core_file] [exec_file]   #-c指定转储的core文件

gdb -c core.5213 spp_uc_frequent_contact_ol_worker

# 进入后输入bt查看调用栈

bt     #显示所有帧栈

bt 10  #显示前面10个帧栈(感觉没啥用)

bt -10 #显示后面10个帧栈(感觉没啥用)

bt full  #显示帧栈以及局部变量

效果如下:

这篇文章主要讲GDB和coredump两个方面。

一、CoreDump

1. coredump简介

  1. core,又称coredump文件,准确来讲是Unix/Linux的记录机制产生的一种保存程序崩溃时现场状态的记录性文件。
  2. 为何需要这种记录机制?原因很简单,程序在在正常执行的时候当然是皆大欢喜,但是如果程序出现致命性错误难道不要保存一些现场信息已被分析使用吗!!Unix/Linux也是如此。Unix/Linux将程序工作的当前状况存储成一个文件,主要包括程序运行时候的内存状态、寄存器状态、堆栈指针、内存管理等现场信息,这就是coredump。可以说表示这种机制也可以表示该机制产生的文件。
  3. 在程序崩溃的一瞬间,内核会抛出当时该程序进程的内存详细情况,存储在core.xxx文件中(xxx为一个数字如core.699)。
  4. 如果硬要翻译的话。(core:内存/核心)、(dump:抛出/扔出)。coredump连起来可以直译为“吐核”。

2. coredump机制的优缺点分析

缺点:伴随着core进程的内存空间越大,生成core文件(将内存现场状态写入磁盘)的时间就越长。

优点:终止是内存、寄存器、各种函数堆栈信息的保留使得开发人员可以进行调试。

注:当然可以设定coredump产生的条件,指定当前回话可以生成的coredump文件大小(后续讲到)。

3. coredump文件的存储路径及名称

之所以说这个问题是因为有时候执行程序出现提示Segmentation fault,但是当前目录下并没有coredump文件。此时,记得check下这里。

对于私有化场景 开启了spp服务的core文件收集但是并没有看到core文件:

——解决办法就是在k8s所有母鸡全部开启core文件收集并指定目录。

(1)查询core文件位置

执行如下指令:

cat /proc/sys/kernel/core_pattern

默认值是core,表示当前目录。否则就是在指定目录下。

(2)更改coredump文件的存储位置

通过下面的命令可以更改coredump文件的存储位置,若你希望把core文件生成到/my/coredata目录下:

echo “/my/coredata”> /proc/sys/kernel/core_pattern

(3)指定内核生成的coredump文件的文件名

通过修改kernel的参数可以指定内核所生成的coredump文件的文件名。例如,使用下面的命令使kernel生成名字为core.filename.pid格式的core dump文件:

echo “/data/coredump/core.%e.%p” >/proc/sys/kernel/core_pattern

这样配置后,产生的core文件中将带有崩溃的程序名、以及它的进程ID。上面的%e和%p会被替换成程序文件名以及进程ID。
 

4、产生coredump文件的条件

ps:这个尤其值得注意。因为通常默认的core文件大小都是0.

(1)查询当前会话能生成的coredump文件的大小——ulimit  -c

        

        ps:通常段错误却不生成core文件的原因就是因为这个0.

(2)设置当前回话允许生成的coredump文件大小

        1)ulimit -c unlimited

        2)ulimit -c [size]

        注:(1)这里的size单位是block,1block=512byte。

                (2)以上设置都只是对当前会话有效,若想系统均有效,需进行如下设置。

3)在etc/profile中加入一下一行:

ulimit -c unlimited

ps:这个特性可以用于避免过大core文件生成的作用。

5、coredump产生的原因

造成程序coredump的原因有很多,这里总结一些常见情况:

(1)内存访问越界

      a) 由于使用错误的下标,导致数组访问越界。

      b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符。

      c) 使用strcpy, strcat, sprintf, strcmp,strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。

(2)多线程程序使用了线程不安全的函数。

应该使用下面这些可重入的函数,它们很容易被用错:

asctime_r(3c) gethostbyname_r(3n) getservbyname_r(3n)ctermid_r(3s) gethostent_r(3n) getservbyport_r(3n) ctime_r(3c) getlogin_r(3c)getservent_r(3n) fgetgrent_r(3c) getnetbyaddr_r(3n) getspent_r(3c)fgetpwent_r(3c) getnetbyname_r(3n) getspnam_r(3c) fgetspent_r(3c)getnetent_r(3n) gmtime_r(3c) gamma_r(3m) getnetgrent_r(3n) lgamma_r(3m) getauclassent_r(3)getprotobyname_r(3n) localtime_r(3c) getauclassnam_r(3) etprotobynumber_r(3n)nis_sperror_r(3n) getauevent_r(3) getprotoent_r(3n) rand_r(3c) getauevnam_r(3)getpwent_r(3c) readdir_r(3c) getauevnum_r(3) getpwnam_r(3c) strtok_r(3c) getgrent_r(3c)getpwuid_r(3c) tmpnam_r(3s) getgrgid_r(3c) getrpcbyname_r(3n) ttyname_r(3c)getgrnam_r(3c) getrpcbynumber_r(3n) gethostbyaddr_r(3n) getrpcent_r(3n)

(3)多线程读写的数据未加锁保护。

对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成coredump

(4)非法指针

      a) 使用空指针

      b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数 组,否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus error而core dump。

(5)堆栈溢出

不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。
 

6、如何判断一个文件是core文件

readelf -h 读取coredump文件头。如下图所示:

二、GDB+coredump

1、使用GDB,需要先从执行文件中读取符号表信息,然后再读取core文件。即

gdb  test  core.2919

原因:core文件中没有符号表信息,无法进行调试。验证如下:objdump -x core.2919 | tail

2、调试过程如下(和使用gdb调试其他程序几乎一样):

从上面可以看出出问题的是第十三行。

当然进入GDB之后也可以直接执行where可以立马找出出错的位置。如下所示:

/*************************************************************************> File Name: test.cpp> Author: ma6174> Mail: ma6174@163.com > Created Time: 2018年12月24日 星期一 19时10分39秒************************************************************************/#include<stdio.h>int main(){int b=1;int *a=NULL;*a=b;return 0;
}

三、演示gdb调试coredump

(1)源程序如下

#include<stdio.h>
void do_it();
int main(){do_it();return 0;
}
void do_it(){//定义一个字符指针变量a,指向地址1.这个地址肯定不是自己可以访问的,但是这行不会产生段错误。char* p=1;//视图更改地址1出的值,内核会终止该进程,并把core文件dump出来。*p='a';
}

(2)必要的准备

        1)确定core文件的生成位置,免得待会儿找不到。(此处采用默认的当前位置)

        2)设置产生条件 ulimit -c unlimited ,免得一直段错误,就是不吐核。

        3)记住编译时要加-g选项,gcc -g -o test1 test1.c

(3)运行test1程序 如下

        

        说明core已经被dump了,查看对于的core文件是core.3177。

        

         注:每一次执行./test1都会生成一个core.xxx文件,他们的记录的信息应该都是一样的。

(4)开始调试

        调试过程非常简单:gdb test1 core.3177。进入后运行where即可列出出错的位置了。

        

参考:

GDB定位coredump_gdb coredump-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/73862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

21_js正则_表单验证

目录 正则 一、 正则的概念 二、创建正则方式 2.1 构造函数去创建正则 2.2 字面量去创建正则 2,3 test方法 三、正则修饰符 四、 正则的方法 lastIndex test方法 exec 五、字符串方法 replace match search split 六、正则表达式的构成 元字符-- 定位符 元字…

矿山自动化监测解决方案

1.行业现状 为贯彻落实《中共中央国务院关于推进安全生产领域改革发展的意见》《“十四五”矿山安全生产规划》&#xff08;应急〔2022〕64号&#xff09;、《国务院安委会办公室关于加强矿山安全生产工作的紧急通知》&#xff08;安委办〔2021〕3号&#xff09;等有关工作部署…

企业级知识库建设:自建与开源产品集成的全景解析 —— 产品经理、CTO 与 CDO 的深度对话

文章目录 一、引言二、主流产品与方案对比表三、自建方案 vs. 开源产品集成&#xff1a;技术路径对比3.1 自建方案3.2 开源产品集成方案 四、结论与个人观点 一、引言 在当今数据驱动的商业环境中&#xff0c;构建高质量的知识库已成为企业数字化转型的关键一环。本博客分别从…

【蓝桥杯】单片机设计与开发,温度传感器DS18B20

一、温度传感器概述 结构图 二、通信过程 三、onewire单总线协议概述 四、单总线的工作原理 黑粗线是单片机发送的&#xff0c;浅的是s18b20回应的 五、温度传感器的应用 六、onewire 七、课后习题

Python 在Word中查找并替换文本

在操作Word文档时&#xff0c;如果想要修正一处反复出现的拼写错误&#xff0c;统一文中前后不一致的术语&#xff0c;或者将文档中所有的旧联系方式更新为新号码。这时我们可以使用 Word中的查找替换功能&#xff0c;快速定位并批量处理文档中的特定文本&#xff0c;提升编辑效…

Python 笔记 (二)

Python Note 2 1. Python 慢的原因2. 三个元素3. 标准数据类型4. 字符串5. 比较大小: 富比较方法 rich comparison6. 数据容器 (支持*混装* )一、允许重复类 (list、tuple、str)二、不允许重复类 (set、dict)1、集合(set)2、字典(dict)3、特殊: 双端队列 deque 三、数据容器的共…

kill子进程后再wait可以吗?

在父进程中先使用 kill 函数终止子进程&#xff0c;之后再使用 wait 函数是可行的&#xff0c;下面从原理、使用示例、注意事项几个方面详细说明。 原理 kill 函数&#xff1a;其作用是向指定进程发送信号。当向子进程发送 SIGTERM&#xff08;通常用于请求进程正常终止&…

ai-api-union项目,适配各AI厂商api

项目地址&#xff1a;alpbeta/ai-api-union 需求&#xff1a;实现兼容各大模型厂商api的流式对话和同步对话接口&#xff0c;本项目现兼容智谱、豆包、通义、通义版deepseek 设计 一个ChatController类对外暴露这两个接口&#xff0c;入参都为ChatRequest请求类&#xff0c;…

【QT】QT样式设计

QT样式设计 一、QT工程中添加资源文件1.资源文件&#xff1a;2. 添加步骤&#xff1a;3. 新增资源文件以及删除现有的资源文件4. 使用资源文件 二、QT中的qss语句(样式设计语句)1. 样式设计2.常见的qss语句示例代码&#xff1a; 一、QT工程中添加资源文件 1.资源文件&#xff…

Megatron-LM中的deepseek-v3实现

Megatron-LM&#xff1a;https://github.com/NVIDIA/Megatron-LM/tree/main 使用此仓库构建的著名的库也有很多&#xff0c;如: Colossal-AI, HuggingFace Accelerate, and NVIDIA NeMo Framework.Pai-Megatron-Patch工具是阿里人工智能平台PAI算法团队研发,ai-Megatron-Patch…

[mlr3] Bootstrap与交叉验证k-fold cross validation

五折交叉验证因其无放回分层抽样和重复验证机制&#xff0c;成为超参数调优的首选&#xff1b; 而Bootstrap因有放回抽样的重复性和验证集的不稳定性&#xff0c;主要服务于参数估计&#xff08;置信区间的计算&#xff09;而非调优。 实际应用中&#xff0c;可结合两者优势&am…

某大麦手机端-抢票

引言 仅供学习研究&#xff0c;欢迎交流 抢票难&#xff0c;难于上青天&#xff01;无论是演唱会、话剧还是体育赛事&#xff0c;大麦网的票总是秒光。作为一名技术爱好者&#xff0c;你是否想过用技术手段提高抢票成功率&#xff1f;本文将为你揭秘大麦手机端抢票的核心技术…

最常使用的现代C++新特性介绍

现代 C泛指的是从 C11 之后的 C标准. 从 C11 开始, C标准委员会实行班车制, 没三年发布一个新版本, 如果一个功能在新版本发布之前已经准备好, 则可以加入该版本中, 否则延后到下一个版本. 语言核心 自 C11 开始, 语言语法层面加了许多语法糖, 还有增加了一些新语法.使得 C语…

SQL Server:当在删除数据库时因为存在触发器而无法删除

当在删除数据库时因为存在触发器而无法删除&#xff0c;你可以通过禁用触发器来解决这个问题。下面为你介绍在 SQL Server 里禁用和启用触发器的方法。 禁用数据库中所有表的触发器 你可以使用系统视图 sys.triggers 来查询数据库里所有的触发器&#xff0c;然后生成禁用这些…

【Linux篇】进程入门指南:操作系统中的第一步

步入进程世界&#xff1a;初学者必懂的操作系统概念 一. 冯诺依曼体系结构1.1 背景与历史1.2 组成部分1.3 意义 二. 进程2.1 进程概念2.1.1 PCB&#xff08;进程控制块&#xff09; 2.2 查看进程2.2.1 使用系统文件查看2.2.2 使⽤top和ps这些⽤⼾级⼯具来获取2.2.3 通过系统调用…

销售易vs纷享销客:制造行业CRM选型深度解析

“以客户为中心”&#xff0c;顾名思义就是指让客户贯穿企业市场、研发、生产、销售、服务全流程&#xff0c;以客户需求为导向进行经营。CRM作为企业数字化建设基础设施&#xff0c;在企业高质量发展进程中扮演着重要角色。在众多CRM解决方案中&#xff0c;腾讯旗下CRM销售易凭…

【JavaScript】九、JS基础练习

文章目录 1、练习&#xff1a;对象数组的遍历2、练习&#xff1a;猜数字3、练习&#xff1a;生成随机颜色 1、练习&#xff1a;对象数组的遍历 需求&#xff1a;定义多个对象&#xff0c;存数组&#xff0c;遍历数据渲染生成表格 let students [{ name: 小明, age: 18, gend…

代码随想录day31 贪心part05

56.合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;in…

《C++11:通过thread类编写C++多线程程序》

关于多线程的概念与理解&#xff0c;可以先了解Linux下的底层线程。当对底层线程有了一定程度理解以后&#xff0c;再学习语言级别的多线程编程就轻而易举了。 【Linux】多线程 -&#xff1e; 从线程概念到线程控制 【Linux】多线程 -&#xff1e; 线程互斥与死锁 语言级别的…

c++位运算总结

在C中&#xff0c;位运算是对二进制位进行操作的运算&#xff0c;主要有以下几种&#xff1a; 1. 按位与&#xff08; & &#xff09;&#xff1a;两个操作数对应位都为1时&#xff0c;结果位才为1&#xff0c;否则为0。例如 3 & 5 &#xff0c; 3 二进制是 0000 0011…