C语言gdb调试

news2025/1/12 19:55:45

目录

1.gdb介绍

2.设置断点

2.1.测试代码

2.2.设置函数断点

2.3.设置文件行号断点

2.4.设置条件断点

2.5.多线程调试

3.删除断点

3.1.删除指定断点

3.2.删除全部断点

4.查看变量信息

4.1.p命令

4.2.display命令

4.3.watch命令

5.coredump日志

6.总结


1.gdb介绍

        gdb是一个强大的调试工具,广泛用于调试 C、C++ 以及其他编程语言的程序。它帮助程序员在开发过程中识别并修复错误,提高程序的可靠性和性能。

        掌握gdb的基本使用方法非常重要,它能够帮助我们快速定位一些段错误问题或者解决一些程序异常问题。

        如果提示没有gdb命令需要手动安装一下gdb插件:

        在 Ubuntu/Debian 上安装 gdb:sudo apt install gdb

        在 CentOS/RHEL 上安装 gdb:sudo yum install gdb

        日常工作中可以选择gdb启动程序或者gdb -p 程序进程号,来调试程序,章节2,设置断点将会详细讲解。

2.设置断点

2.1.测试代码

        先上一段测试代码,方便讲解设置断点的方法:

main.c文件

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

#define THREAD_NUM 3
#define LOOP_NUM 10

void *task(void *arg) {
    while (1) {
        int num = *(int *)arg;
        printf("my num:%d\n", num);
        sleep(1);
    }
}

void first_print(int num) {
    printf("first hello: %d\n", num);
    return;
}

void second_print(int num) {
    printf("second hello: %d\n", num);
    return;
}

void test_copy(char *dest, char *src) {
    memcpy(dest, src, strlen(src));
}

int main()
{
    
    char *s = NULL;
    char *p = "123";
    //test_copy(s, p);

    for (int i = 0; i < 10; i++) {
        first_print(i);
        second_print(i);
    }

    pthread_t threads[THREAD_NUM];
    int thread_arg[THREAD_NUM] = {0};
    for (int i = 0; i < THREAD_NUM; i++) {
        thread_arg[i] = i;
        pthread_create(&threads[i], NULL, task, &thread_arg[i]);
    }

    for (int i = 0; i < THREAD_NUM; i++) {
        pthread_join(threads[i], NULL);
    }

    return 0;
}

 makefile文件:

test:main.c
	gcc	-O0	-g	-o	test	main.c	-lpthread

.PHONY:clean
clean:
	rm -rf test *.o

        代码功能非常简单,两个打印函数,以及创建3个线程,死循环打印。

2.2.设置函数断点

        函数断点,顾名思义,断点设置在函数上,操作命令: b 函数名

        经过makefile编译后会产生一个test可执行文件,通常来说我们直接gdb可执行文件即可,即gdb test,然后输入r运行程序。

        那么如何设置断点呢,通常可以在执行r命令之前设置断点或者运行过程中设置断点,但是运行过程中设置断点你需要保证程序还没有运行到你将要设置的断点的位置,否则不会命中断点。

        下面我们设置两个函数断点,first_print和second_print,执行b first_print回车然后再执行b second_print即可。

        通过 i b命令查看我们当前设置断点信息,可以看到设置了两个断点,编号分别为1 2 ,然后就可以执行 r 命令运行程序。

        当我们运行程序后,可以看到程序命中了第一个断点,执行c命令, 作用是跳转到下一个断点,执行 n 命令可以运行到一下行。

2.3.设置文件行号断点

        gdb还可以针对文件的某一行设置断点,操作命令:b 文件名:行号

        可以看到我们将断点设置在了main.c文件的第23行,运行程序,程序停止在了23行的位置。

2.4.设置条件断点

        设置条件断点,即再设置断点的基础之上再加上额外的条件,例如某一个变量等于固定的数值,操作命令:b 函数 if (变量 == 常数)

        可以看到我设置了一个断点在函数first_print,且仅当num值为2时命中该断点,运行程序和预期结果一致。

2.5.多线程调试

        在程序中,如果存在多线程的情况,调试起来稍微复杂一些,但是这种场景经常会出现在多核开发环境上,因此需要掌握其调试方法。

        那么如果设置一个断点到一个函数,这个函数会被多个线程调用,那么必定会发生线程切换,因此调试时需要加锁,命令:set scheduler-locking on

        可以看到,将断点设置到了12行,如果不加锁那么这三个线程都会触发这个断点,当第一次触发时我们可以加锁,使得只有当前线程能停在这个断点,若要解锁 ,执行命令:set scheduler-locking off。

        可以看到解锁之后发送了线程切换。

        还有一种方式就是查看当前运行的全部线程,然后进入需要调试的线程。查看全部线程的命令:info threads

        可以看到有三个子线程,然后可以通过thread 线程号 命令,进入具体的线程。

3.删除断点

3.1.删除指定断点

        删除指定断点,操作命令:d 断点编号

        如图,开始设置了两个断点,其编号分别为1 和 2 ,执行命令d 1 删除断点1,然后查看断点情况,只剩下断点2,同理如果要删除断点2,执行命令d 2即可。

3.2.删除全部断点

        删除全部断点,操作命令:d 

4.查看变量信息

        查看变量信息有多种命令,每种命令有不同的作用。

4.1.p命令

        主要用于查看变量的值,操作命令::p 变量名

        如图,执行p num可以查看到num的值。

4.2.display命令

        主要用于一直显示某个变量的值,好处就是不用每次手动执行p命令来查看某个变量的值,操作命令:display 变量名

         如果想取消一直显示,首先执行display,获取id,然后执行命令:undisplay id 即可

 

4.3.watch命令

        watch命令可以追踪某个变量变化前的值和变化后的值,操作命令:watch 变量名

        如果需要需要watch,首先查看所有监视点:info watchpoints,然后执行删除命令,删除指定watch:delete hw watchpoint 3

 

5.coredump日志

        将测试代码第36行,//test_copy(s, p);取消注释,然后重新编译,很明显程序会段错误,此时我们可以执行ulimit -c unlimited,使其可以生产coredump日志文件,然后可以使用gdb调试命令,定位问题,操作命令:gdb 可执行文件名 core文件名

        使用bt命令可以看到具体的调用堆栈信息,然后f id进入具体的函数,通过p命令查看变量的值,很明显dest为空指针。

        

6.总结

        gdb是程序员调试程序不可获取的工具,需要大家多多使用,熟能生巧 。

        注:makefile如果加了-o3编译优化或者其他优化手段,可能在运行时行号会发生跳跃,和预期不一致。

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

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

相关文章

winform第三方界面开源库AntdUI的使用教程保姆级环境设置篇

1. AntdUI 1.1. 导入项目 1.1.1. 首先新建一个空白的基于.net的Winfrom项目1.1.2. 复制AntdUI中src目录到我们的解决方案下面1.1.3. 解决方案下添加现有项目1.1.4. 添加项目引用 1.2. 编写代码 1.2.1. 改写Form1类&#xff0c;让其继承自public partial class Form1 : AntdUI.W…

记录一下vue2项目优化,虚拟列表vue-virtual-scroll-list处理10万条数据

文章目录 封装BrandPickerVirtual.vue组件页面使用组件属性 select下拉接口一次性返回10万条数据&#xff0c;页面卡死&#xff0c;如何优化&#xff1f;&#xff1f;这里使用 分页 虚拟列表&#xff08;vue-virtual-scroll-list&#xff09;&#xff0c;去模拟一个下拉的内容…

企业开通部署 Azure OpenAI 流程:如何创建一个AI聊天机器人

由于众所周知的原因&#xff0c;国内没法直接调用 OpenAI 接口。 下面我将演示企业如何开通 Azure OpenAI 服务&#xff0c;以及如何使用 C# 调用 Azure OpenAI 接口创建一个 Console 应用程序并实现聊天机器人功能。 1开通 Azure OpenAI 服务 要开通 Azure OpenAI 服务&…

CNN Test Data

由于数据量过大&#xff0c;打不开了 搞一组小的吧。收工睡觉 https://download.csdn.net/download/spencer_tseng/90256048

STM32使用ITM调试_通过仿真器实现串口打印

IDE&#xff1a;CLion MCU: STM32F407VET6 工具&#xff1a;OpenOCD Telnet 一、简介 调试单片机时&#xff0c;如果要打印数据往往需要另接一根线通过USB转TTL接到电脑上。但这样做往往并不方便&#xff0c;尤其是身边没有USB转TTL工具时。这时可以使用单片机自带的ITM单元…

Ubuntu 磁盘修复

Ubuntu 磁盘修复 在 ubuntu 文件系统变成只读模式&#xff0c;该处理呢&#xff1f; 文件系统内部的错误&#xff0c;如索引错误、元数据损坏等&#xff0c;也可能导致系统进入只读状态。磁盘坏道或硬件故障也可能引发文件系统只读的问题。/etc/fstab配置错误&#xff0c;可能…

RT-DETR融合[AAAI2025]的ConSeg中的CDFAPreprocess模块

RT-DETR使用教程&#xff1a; RT-DETR使用教程 RT-DETR改进汇总贴&#xff1a;RT-DETR更新汇总贴 《ConDSeg: A General Medical Image Segmentation Framework via Contrast-Driven Feature Enhancement》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/abs/2412.083…

线程与互斥锁

一、线程 1、定义 进程的创建、销毁与切换存在着较大的时空开销&#xff0c;因此人们急需一种轻型的进程技术来减少开销。在80年代&#xff0c;线程的概念开始出现&#xff0c;线程被设计成进程的一个执行路径&#xff0c;同一个进程中的线程共享进程的资源&#xff0c;因此系…

如何搭建 Vue.js 开源项目的 CI/CD 流水线

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

uni app 写的 小游戏,文字拼图?文字拼写?不知道叫啥

从下方的偏旁部首中选在1--3个组成上面文章中的文字&#xff0c;完成的文字标红 不喜勿喷 《满江红》 其中用到了两个文件 strdata.json parameters.json 这两个文件太大 放到资源中了 资源文件 <template><view class"wenzi_page_main"><view c…

DBeaver执行本地的sql语句文件避免直接在客户端运行卡顿

直接在客户端运行 SQL 语句和通过加载本地文件执行 SQL 语句可能会出现不同的性能表现&#xff0c;原因可能包括以下几点&#xff1a; 客户端资源使用&#xff1a; 当你在客户端界面直接输入和执行 SQL 语句时&#xff0c;客户端可能会消耗资源来维护用户界面、语法高亮、自动完…

基于STM32的智能电表可视化设计:ESP8266、AT指令集、python后端Flask(代码示例)

一、项目概述 随着智能家居的普及&#xff0c;智能电表作为家庭用电管理的重要工具&#xff0c;能够实时监测电流、电压及功率&#xff0c;并将数据传输至后台进行分析和可视化。本项目以STM32C8T6为核心&#xff0c;结合交流电压电流监测模块、ESP8266 Wi-Fi模块、OLED显示屏…

MySQL 如何赶上 PostgreSQL 的势头?

原文地址 我与 MySQL 社区的前辈交谈时&#xff0c;经常遇到这个问题&#xff1a;「为什么 MySQL 这么棒&#xff0c;而且&#xff08;至少根据 DB-Engines 的计算&#xff09;仍然比 PostgreSQL 更流行&#xff1b;但它的地位在下降&#xff0c;PostgreSQL 却势不可挡地越来越…

关于在windows系统中编译ffmpeg并导入到自己项目中这件事

关于在windows系统中编译ffmpeg并导入到自己项目中这件事 前因&#xff08;可跳过不看&#xff09; 前阵子由于秋招需求&#xff0c;写了一个简易的安卓播放器&#xff0c;最终因为时间问题还有一些功能没有实现着实可惜&#xff0c;如&#xff1a;倍速播放&#xff0c;快进操…

word中电流符号i或者j,这两个字母的头上的点会消失---完美解决办法

上图中&#xff0c;是我已经改好的格式。 具体解决办法是将公式转成LATEX格式&#xff0c;然后在字母i或者j前加上//&#xff0c;再转换会unicode&#xff0c;专业形式即可解决。更快的解决办法就是复制我在word文档里面写的。 word文档放在资源里面了&#xff0c;有需要自取即…

【C++】std::string和size()函数进阶解析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;基础知识&#xff1a;C 中的std::string字符串的基础概念size() 函数基础使用size()实例&#xff1a;计算字符串长度 &#x1f4af;基于size()的字符串解析和访问方式代码实…

《OpenCV计算机视觉实战项目》——银行卡号识别

文章目录 项目任务及要求项目实现思路项目实现及代码导入模块设置参数对模版图像中数字的定位处理银行卡的图像处理读取输入图像&#xff0c;预处理找到数字边框使用模版匹配&#xff0c;计算匹配得分 画出并打印结果 项目任务及要求 任务书&#xff1a; 要为某家银行设计一套…

【开发环境搭建篇】Visual Studio 2022 安装和使用

本文收录于 《C编程入门》专栏&#xff0c;从零基础开始&#xff0c;介绍C编程入门相关的内容&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、下载三、安装四、使用五、总结 一、前言 本文介绍如何在Windows环境下安装Visual Studio 2022。 什么是Vi…

【面试题】技术场景 5、日志采集ELK

日志采集的重要性与采集方式 重要性&#xff1a;在项目开发、测试及生产环境中&#xff0c;日志是定位系统问题的关键手段&#xff0c;对系统维护与问题排查至关重要。采集方式 常规采集&#xff1a;按天保存日志文件至专门目录&#xff0c;文件名包含项目名、端口及日期&…

matlab的绘图的标题中(title)添加标量以及格式化输出

有时候我们需要在matlab绘制的图像的标题中添加一些变量&#xff0c;这样在修改某些参数后&#xff0c;标题会跟着一块儿变。可以采用如下的方法&#xff1a; x -10:0.1:10; %x轴的范围 mu 0; %均值 sigma 1; %标准差 y normpdf(x,mu,sigma); %使用normpdf函数生成高斯函数…