【转】GDB调试程序及分析core

Ubuntu C++ 使用gdb+core分析软件崩溃原因 core 叫做核心转储,它是进程运行过程中突然崩溃那一刻的内存快照.操作系统在程序发生异常并且异常 在进程内部又没有被捕获的情况下,会把进程此刻内存、寄存器状态、运行堆栈等信息转储保存在一个core文件里. 阅读详情

使用 GDB 调试程序

GDB是UNIX下面的程序调试工具, 可以调试多种类型程序, 主要可以完成以下四个功能:

  1. 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
  2. 可让被调试的程序在指定的调置的断点处停住。(断点可以是条件表达式)
  3. 当程序被停住时,可以检查此时程序中所发生的事。
  4. 动态的改变程序的执行环境。

简单的调试例子

测试程序如下:

#include <stdio.h>
int func(int n)
{
    int sum=0,i;
    for(i=0; i<n; i++)
    {
        sum+=i;
    }
    return sum;
}
void main()
{
    int i; long result = 0;
    for(i=1; i<=100; i++)
    {
        result += i;
    }
    printf(“result[1-100] = %d \n”, result );
    printf(“result[1-250] = %d \n”, func(250) );
}

编译生成执行文件(要调试C/C++的程序,在编译时必须要把调试信息加到可执行文件中:-g 选项):

gcc -g C++_GDB_test.cpp -o C++_GDB_test.o

一个简单的调试过程如下:

$ gdb C++_GDB_test.o
GNU gdb (GDB) 7.10.1
......
done.
(gdb) l                    ----> l(list), 列出源码
6	*/
7
8	#include <stdio.h>
9	int func(int n)
10	{
11	    int sum=0,i;
12	    for(i=0; i<n; i++)
13	    {
14	        sum+=i;
15	    }
(gdb)                      ----> 直接回车表示重复上一次命令
16	    return sum;
17	}
18	int main()
19	{
20	    int i; long result = 0;
21	    for(i=1; i<=100; i++)
22	    {
23	        result += i;
24	    }
25	    printf("result[1-100] = %ld\n", result );
(gdb)
26	    printf("result[1-250] = %d\n", func(250));
27	}
(gdb) br 20                 ----> 设置断点,在源程序 20 行处
Breakpoint 1 at 0x100000edf: file C++_GDB_test.cpp, line 20.
(gdb) br func               ----> 设置断点,在函数func()入口处
Breakpoint 2 at 0x100000e97: file C++_GDB_test.cpp, line 11.
(gdb) info br               ----> 查看断点信息
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000100000edf in main() at C++_GDB_test.cpp:20
2       breakpoint     keep y   0x0000000100000e97 in func(int) at C++_GDB_test.cpp:11
(gdb) r                     ----> r(run) 运行程序
Starting program: .../C++_Code/C++_GDB_test.o
Breakpoint 1, main () at C++_GDB_test.cpp:20  ----> 在断点处停住
20	    int i; long result = 0;
(gdb) n                     ----> n(next)单条语句执行
21	    for(i=1; i<=100; i++)
(gdb) n
23	        result += i;
(gdb) n
21	    for(i=1; i<=100; i++)
(gdb) c                     ----> c(continue)继续运行程序到下一个断点
Continuing.
result[1-100] = 5050        ----> 程序输出

Breakpoint 2, func (n=250) at C++_GDB_test.cpp:11
11	    int sum=0,i;
(gdb) n
12	    for(i=0; i<n; i++)
(gdb) br 14 if i==50        ----> 设置条件断点
Breakpoint 3 at 0x100000eb1: file C++_GDB_test.cpp, line 14.
(gdb) c
Continuing.

Breakpoint 3, func (n=250) at C++_GDB_test.cpp:14
14	        sum+=i;
(gdb) p i                   ----> p(print): 打印变量i的值
$1 = 50
(gdb) p sum                 ----> p: 打印变量sum的值
$2 = 1225
(gdb) bt                    ----> 查看函数堆栈
#0  func (n=250) at C++_GDB_test.cpp:14
#1  0x0000000100000f36 in main () at C++_GDB_test.cpp:26
(gdb) finish                ----> 退出函数
Run till exit from #0  func (n=250) at C++_GDB_test.cpp:14
0x0000000100000f36 in main () at C++_GDB_test.cpp:26
26	    printf("result[1-250] = %d\n", func(250));
Value returned is $6 = 31125
(gdb) c
Continuing.
result[1-250] = 31125
[Inferior 1 (process 8845) exited normally]   ----> 程序退出,调试结束 
(gdb) q 

core dump 调试

当程序异常退出时,操作系统把程序当前的内存状况存储在一个core文件中,该文件包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等。通过分析这个文件,我们可以定位到程序异常退出的时候对应的堆栈调用等信息,找出问题所在并进行及时解决。

首先要确定当前会话的 ulimit –c,若为0,则不会产生对应的coredump,需要进行修改和设置,ulimit –c [size](注意,这里的size如果太小,则可能不会产生对应的core文件)。

ulimit  -c unlimited  (可以产生core dump 且不受大小限制)

core文件默认的存储位置为当前进程的工作目录(一般就是可执行文件所在的目录)。当程序出现段错误(试图访问或者修改不属于自己的内存地址时)时,就会产生 core dump,方便我们进行调试。下面是一些常见的段错误:

  • 内存访问越界:由于使用错误的下标,导致数组访问越界。
  • 非法指针访问:比如写 nullptr
  • 栈溢出:使用了大的局部变量

下面是个简单的例子:

#include <iostream>
using namespace std;

void test(){
    int *p = nullptr;
    *p = 1;             // Segment Fault
}
int main() {
    test();
    return 0;
}

然后编译运行程序,用 GDB 查看其产生的 Core Dump 文件:

$ g++ -g demo.cpp -o demo.o -std=c++11
$ ulimit -c
0
$ ulimit -c unlimited
$ ./demo.o
[1]    15193 segmentation fault (core dumped)  ./demo.o
$ ~ ls
core  demo.cpp  demo.o
➜  ~ gdb demo.o core
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
......
Core was generated by './demo.o'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000000004006dd in test () at demo.cpp:6
6	    *p = 1;
(gdb) bt
#0  0x00000000004006dd in test () at demo.cpp:6
#1  0x00000000004006ee in main () at demo.cpp:9

调试参数

gdb调试中需要用到的命令

  • file [filename]:装入想要调试的可执行文件
  • kill [filename]:终止正在调试的程序
  • break [file:]function:在(file文件的)function函数中设置一个断点
  • clear:删除一个断点,这个命令需要指定代码行或者函数名作为参数
  • run [arglist]:运行您的程序 (如果指定了arglist,则将arglist作为参数运行程序)
  • bt Backtrace:显示程序堆栈信息
  • x:查看内存
  • print expr:打印表达式的值
  • continue:继续运行您的程序 (在停止之后,比如在一个断点之后)
  • list:列出产生执行文件的源代码的一部分
  • next:单步执行 (在停止之后); 跳过函数调用(与step相对应,step会进入函数内部)
  • set:设置变量的值。例如:set nval=54 将把54保存到nval变量中;设置输入参数也可以通过这个命令(例如当三个入参分别为a、b、c的话,set args a b c)
  • watch:使你能监视一个变量的值而不管它何时被改变
  • finish:继续执行,直到当前函数返回
  • ignore:忽略某个断点制定的次数。例:ignore 4 23 忽略断点4的23次运行,在第24次的时候中断
  • info [name]:查看name信息
  • xbreak:在当前函数的退出的点上设置一个断点
  • whatis:显示变量的值和类型
  • ptype:显示变量的类型
  • shell:使你能不离开 gdb 就执行 UNIX shell 命令
  • help [name]:显示GDB命令的信息,或者显示如何使用GDB的总体信息
  • quit:退出gdb.

命令行参数

有时候,我们需要调试的程序需要有命令行参数,可以通过下面两种方式设置调试的程序的命令行参数:

  • gdb命令行的 –args 参数
  • gdb环境中 set args命令。

高级的用法

比如为了搞清楚柔性数组的内存分布特征,我们可以用下面的程序来验证:

#include <stdlib.h>
#include <string.h>

struct line {
   int length;
   char contents[0]; // C99:char contents[]; 没有指定数组长度
};

int main(){
    int this_length=10;
    struct line *thisline = (struct line *)
                     malloc (sizeof (struct line) + this_length);
    thisline->length = this_length;
    memset(thisline->contents, 'a', this_length);
    return 0;
}

然后用下面的调试过程来理解柔性数组的内存分布:

参考

使用gdb调试程序详解
GDB中应该知道的几个调试方法
Codesign gdb on Mac OS X Yosemite
详解 coredump
C++编译器无法捕捉到的8种错误
What is a segmentation fault?

一篇文章轻松学会使用gdb调试程序的core文件(调试全过程) 阅读详情

相关推荐

GDB调试core dump

如何通过core dump文件来定位错误代码

Sison_w的博客 1350

gdb调试core时打印出当时变量的内容------有时可以主动制造core来看变量值

有时候, 在特殊需要时, 我们可以让程序主动core掉, 来查看当时的内容。 本文来玩玩这个: #include using namespace std; class Point { public: int x; int y; }; int main() { int a = 1; int b = 2; Point M; M.x = 3; M.y = 4; int *p

认知 行动 坚持 1万+

Linux 使用gdb调试core文件

当程序运行过程中出现Segmentation fault (core dumped)错误时,程序停止运行,并产生core文件。core文件是程序运行状态的内存映象。

一名想做出点成就的后端~ 1903

关于gdb

GDB全称GDB Debugger。GDB具备各种调试功能,使用GDB的调试人员可以查看及修改程序的内部变量值。

weixin_45778504的博客 1195

使用GDB工具分析core文件的方法

在软件开发过程中,我们经常会遇到程序崩溃或异常退出的情况。这时,一个非常有用的工具就是GDB(GNU调试器),它可以帮助我们分析core文件并找出导致程序崩溃的原因。本文将介绍如何使用GDB工具来分析core文件。欢迎点赞收藏,谢谢

笔者从事电信媒体开发多年,愿意将多年的开发经验分享给同行 6717

数据结构实验1 集合的交、并、差

姓名:Far_Rainbow 学号: 202505000X 专业: 软件工程 年级:2020级 实验名称:实验1 集合的交、并、差 实验内容: (1)实验目的 通过该实验,让学生复习巩固C语言中的循环结构、循环控制条件、分支结构和数组/链表、函数的调用等有关内容,体会到用数组存储集合时,需要记录集合元素的个数,否则输出结果会出现数据越界现象。 (2)实验内容 通过键盘,分别输入两个数据元素类型为正整数的集合A和B,以负数输入为结束条件,输出两个集合的交、并、差。 (3)实验要求 从程序完善性上考虑,集合元

Far_Rainbow的博客 2177

设备GDB调试

设备GDB调试

mayue_web的博客 4517

一文告诉你:如何在trae中编译运行STM32程序,并让AI帮你修改代码

本文详细介绍了如何将STM32程序从Keil迁移到国产免费工具Trae,并利用AI进行代码修改的全过程。

水滴爬呀爬 4884

Linux下gdb调试工具的详解及Core文件分析

Linux下gdb调试工具的详解及Core文件分析。

jackiendsc的博客 2333

深度解析:LPDDR5 采样 Mask 背后的秘密 —— 从 Jitter 到 BER 全面剖析

在 LPDDR5 中,CK/DQS 信号相当于“指挥棒”,而数据(DQ)要在时钟节拍里被准确采样。Crosspoint Mask 区域横轴:时间 (Time)纵轴:电压 (Vref)👉 只要采样点落在这个区域内,数据就是正确的。否则就会出错。BERPBERPMask 就像高速公路的收费站口,如果车(采样点🚗)在车道内,顺利通过;一旦跑偏,就撞护栏。LPDDR5 的速率极高,UI 非常短,Mask 区域成为核心指标各种 Jitter、Noise 会不断压缩 Mask。

weixin_43199439的博客 354

2023华为OD机试真题B卷 Python 实现【最长的元音子串长度】

定义当一个字符串只有元音字母(a,e,i,o,u,A,E,I,O,U)组成,称为元音字符串,现给定一个字符串,请找出其中最长的元音字符串,并返回其长度,如果找不到请返回0, 字符串中任意一个连续字符组成的子序列称为该字符串的子串

MISAYAONE的博客 902

linux下使用gdb调试core文件

一、GDB简介 GDB是GNU开源组织发布的一个强大的UNIX下调试程序工具,GDB主要帮助你完成下面四个方面的功能: 1、启动你的程序,可以按照你自定义的要求随心所欲的运行程序。 2、可以让调试程序在你所指定的位置的断点处停止。 3、当程序停止时,可以检查此时你的程序中所发生的事情。 4、动态的改变你程序的执行环境。 二、core文件简介 1、core文件 当程序运行过程中出现Segmentation fault (core dumped)错误时,程序停止运行...

A_L_A_N 1万+

【报错解决】OpenClaw 报错 `openclaw: command not found`:全局命令未加入系统 PATH 的深度排查与修复指南

在国产AI工具链开发中,OpenClaw作为关键命令行工具常出现command not found报错。本文深度分析该问题的根源——Linux环境变量PATH未包含用户级安装目录(~/.local/bin)。通过四种解决方案(临时PATH修改、永久配置、软链接、虚拟环境处理)和排错Checklist,揭示"命令存在却找不到"的本质是路径配置问题,特别适用于Docker/国产Linux/非root环境。文中强调理解Linux工具链机制对国产AI开发的重要性,并指出这是开发者掌握环境

博客 5382

GDB调试core文件

coredump文件的生成以及调试

Qiang的博客 1万+

流体动力学仿真软件:SU2_(3).SU2的网格生成技术

设置网格的大小、密度等参数。

kkchenjj的博客 1030

《网络安全自学教程》- OSI七层模型分层及作用,数据封装与解封过程,数据传输过程。

OSI分哪七层,每层的作用是什么,解释数据在七层模型中是怎样传输的,封包和解封过程,数据包在每一层是怎么封装和解封的。

wangyuxiang946的博客 1万+

linux下gdb使用core文件调试程序,解决“段错误核心已转储“的问题

gdb使用core文件调试程序,解决“段错误核心已转储“的问题;设置core文件开关,解决> "警告:此文件自读入后已发生改动!!!"以及"core pattern" E667:同步失败的信息;等问题

比特的一天 3182

YOLOv8改进,YOLOv8添加DCNv4可变性卷积(windows系统成功编译),全网最详细教程

DCNv4通过两项关键增强解决了其前身DCNv3的局限性:1. 移除空间聚合中的softmax归一化,以增强其动态特性和表达能力;2. 优化内存访问以最小化冗余操作,从而加速计算。这些改进使得DCNv4相比DCNv3显著加快了收敛速度,并且处理速度大幅提升,前向传播速度超过三倍。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 6469

如何使用GDB工具来调试程序

官方参考文档:http://www.gnu.org/software/gdb/documentation/ GDB(GNU 项目调试器)可以让您了解程序在执行时“内部” 究竟在干些什么,以及在程序发生崩溃的瞬间正在做什么。GDB 做以下 4 件主要的事情来帮助您捕获程序中的 bug: ◼ 在程序启动之前指定一些可以影响程序行为的变量或条件 ◼ 在某个指定的地方或条件下暂停程序 ◼ 在程序停止时检查已经发生了什么 ◼ 在程序执行过程中修改程序中的变量或条件,这样就可以体验修复一...

m0_37322399的博客 2542

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

gdb Core Dump 调试程序错误

在程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。1.core文件的生成开关和大小限制--------------------------------- 1)使用ulimit -c命令可查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件。

嵌入式开发小站 2138

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

使用gdb+core文件调试程序异常奔溃bug

前言 话接上文将gdb移植到开发板,那么又该如何使用gdb来调试解决程序的各种疑难杂症呢? 使用gdb的方法 对于嵌入式开发而言,使用gdb的手段常见有两种:一种是通过gdb+gdbserver远程调试arm开发板上的程序。这种方法的优点是对arm开发板的资源消耗较少,只需一根网线就可以正常的调试程序。缺点是对于比较大的程序如果单步调试等手段比较费时费力,特别对于偶尔时不时才出现的bug更是如此。那么此时就得使用第二种手段:使用gdb+core文件来调试程序了。 core文件简介 关于core文件的介绍使用

qinjie的博客 1224

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

gdb调试core文件

部分ref :https://cloud.tencent.com/developer/article/1177442 1.core文件 当程序运行过程中出现Segmentation fault (core dumped)错误时,程序停止运行,并产生core文件。core文件是程序运行状态的内存映象。使用gdb调试core文件,可以帮助我们快速定位程序出现段错误的位置。当然,可执行程序编译时应加上-...

勤学如春起之苗,不见其增,日有所长! 辍学如磨刀之石,不见其损,日有所亏! 1634

gdb core dump调试程序错误

这几天编译项目,总是遇到segment fault: core dumped。一开始还能马上知道是刚才的修改引起的,到后来就不行了。到网上搜了一下core dump,很方便的找到问题了。记录一下。 当程序crash退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。 1. 使用

myxmu的专栏 1292

gdb 调试程序

gdb 调试程序 文章目录gdb 调试程序gdb查看内存错误1.允许生成core-dump文件2.设置文件生成路径3. debug模式编译程序并运行4.gdb查看core-dump文件定位错误gdb调试程序参考 gdb查看内存错误 1.允许生成core-dump文件 程序发生内存错误时而退出时,会生成一个core dump文件保存相关信息,用这个文件可以排查内存错误。 使用命令 ulimit -c 查看core开关,如果为0表示关闭,不会生成core文件。ulimit -a 查看信息会全一些 ulimit

hu_hao的博客 746

Linux生成core文件、core文件路径设置

1.设置core文件大小 列出所有资源的限制: ulimit -a ulimit -a.png 或者查看core file size: ulimit -c core file size: unlimited:core文件的大小不受限制 0:程序出错时不会产生core文件 1024:代表1024k,core文件超出该大小就不能生成了 设置core文件大小: ulimit -c file...

小天使faith的专栏 15万+

用gdb调试core dump文件

尊重原创:http://blog.chinaunix.net/u2/83905/showart_2134570.html  在Unix系统下,应用程序崩溃,一般会产生core文件,如何根据core文件查找问题的所在,并做相应的分析和调试,是非常重要的。什么是Core Dump?Core的意思是内存, Dump的意思是扔出来, 堆出来.开发和使用Unix程序时, 有时程序莫名其妙的dow

夕阳帆的专栏 6571
上一篇: 【转】git分支管理命令
下一篇: 【转】阿里研究员:警惕软件复杂度困局
LinuxG_G
博客等级 码龄15年 58粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值