cGDB 调试方法

news2024/12/22 23:24:50

用法总结

Ubuntu系统,安装cGDB

  • sudo apt update
  • sudo apt install cgdb

编译代码

  • g++ -g -o example example.cpp -lpthread
  • 要确保有 -g ,代码是调试信息编译的 

启动测试:cgdb ./可执行文件

  • 此处可以使用esc进入命令模式,vim命令上下翻页代码
  • i 进入命令输入模式

设置断点

  • (gdb) break main                     # 在 main 函数入口处设置断点
  • (gdb) break MyService::Start        # 在 MyService::Start 函数处设置断点
  • (gdb) break 42                       # 在第 42 行设置断点
  • (gdb) info breakpoints               # 显示所有断点信息

 

 控制断点

  • (gdb) disable 1                      # 禁用编号为 1 的断点
  • (gdb) enable 1                       # 启用编号为 1 的断点
  • (gdb) delete 1                       # 删除编号为 1 的断点

 

 运行程序(设置好断点后,就可以运行程序开始调试了)

  • (gdb) run                            # 运行程序

 执行控制(截图演示,一张命令行截图+一张UI界面显式截图)

  • (gdb) step                           # 单步执行,进入函数内部
  • (gdb) next                           # 单步执行,不进入函数内部
  • (gdb) finish                         # 运行到当前函数结束
  • (gdb) continue                       # 继续运行到下一个断点或程序结束

 

 

 

修改变量(后面事例演示)

  •  (gdb) set var = value                # 设置变量 var 的值为 value

多线程调试(后续事例演示)

  • (gdb) info threads                   # 显示所有线程
  • (gdb) thread 2                       # 切换到线程 2
  • (gdb) thread apply all bt            # 对所有线程执行 backtrace

退出GDB

  • quit 
//上述事例测试代码

#include <functional>
#include <iostream>
#include <thread>
#include <chrono>
#include <vector>

class TimerTask {
public:
    TimerTask(int id, std::function<void()> callback)
        : task_id(id), task_callback(callback) {}

    void execute() {
        if (task_callback) {
            task_callback();
        }
    }

    int get_id() const { return task_id; }

private:
    int task_id;
    std::function<void()> task_callback;
};

class TimerScheduler {
public:
    void add_task(int delay_sec, int id, std::function<void()> callback) {
        tasks.emplace_back(id, callback);
        std::thread([this, delay_sec, id]() {
            std::this_thread::sleep_for(std::chrono::seconds(delay_sec));
            this->execute_task(id);
            }).detach();
    }

    void execute_task(int id) {
        for (auto& task : tasks) {
            if (task.get_id() == id) {
                task.execute();
                break;
            }
        }
    }

    void run() {
        // Simulate running scheduler
    }

private:
    std::vector<TimerTask> tasks;
};



class MyService {
public:
    MyService(TimerScheduler& scheduler) : scheduler(scheduler) {}

    void start() {
        auto task = std::bind(&MyService::task_callback, this, std::placeholders::_1);
        scheduler.add_task(5, 1, std::bind(task, 42));
    }

    void task_callback(int value) {
        std::cout << "Task executed with value: " << value << std::endl;
    }

private:
    TimerScheduler& scheduler;
};

int main() {
    TimerScheduler scheduler;
    MyService service(scheduler);

    service.start();
    scheduler.run();

    std::this_thread::sleep_for(std::chrono::seconds(10)); // Simulate running
    return 0;
}

使用事例

 调试代码一:简单的多线程调试方法

#include <iostream>
#include <thread>
#include <vector>
#include <chrono>

void thread_function(int id) {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "Thread " << id << " finished execution." << std::endl;
}

int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(thread_function, i);
    }

    for (auto& t : threads) {
        t.join();
    }

    return 0;
}

 设置断点并运行程序

  • (gdb) break main
  • (gdb) run

单步执行同时查看变量的变化

  • (gdb) step
  • (gdb) next
  • (gdb) info locals

查看所有线程(此时再执行创建线程的循环中,目前已经创建了两个线程) 

  • (gdb) info threads

 切换到指定线程,并在该线程中单步执行

  • (gdb) thread 3

对所有线程执行回溯  (gdb) thread apply all bt

调试代码二:复杂线程下的调试

#include <iostream>
#include <thread>
#include <vector>
#include <chrono>
#include <mutex>

std::mutex mtx;

void thread_function(int id) {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::lock_guard<std::mutex> lock(mtx);
    std::cout << "Thread " << id << " acquired the lock." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "Thread " << id << " released the lock." << std::endl;
}

int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 3; ++i) {
        threads.emplace_back(thread_function, i);
    }

    for (auto& t : threads) {
        t.join();
    }

    return 0;
}

 

设置断点开始调试

  • (gdb) break thread_function
  • (gdb) run

 

thread_function函数入口查看所有线程 

 

切换到线程4,然后再线程4中单步执行程序(step) ,查看并修改4号线程的id变量

  • (gdb) print id
  • (gdb) set id = 19
  • (gdb) print id

最后退出调试即可quit 

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

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

相关文章

生活方式酒店升势迅起,喆啡酒店缘何成为投资热点?

伴随国内消费结构转型升级&#xff0c;旅游需求持续增加。文旅部发布的《国内旅游提升计划&#xff08;2023—2025年&#xff09;》提出&#xff0c;需丰富优质旅游供给&#xff0c;并进一步提高消费者体验及满意度&#xff0c;这将为酒店行业带来更广阔的客源和更高的质量要求…

SpringBoot上传超大文件导致OOM,完美解决办法

问题描述 上传大文件报错: Caused by: java.lang.OutOfMemoryError at java.io.ByteArrayOutputStream.hugeCapacity(ByteArrayOutputStream.java:123) ~[?:1.8.0_381] at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:117) ~[?:1.8.0_381] …

探索Axure在数据可视化原型设计中的无限可能

在当今数字化浪潮中&#xff0c;产品设计不仅关乎美观与功能的平衡&#xff0c;更在于如何高效、直观地传达复杂的数据信息。Axure RP&#xff0c;作为原型设计领域的佼佼者&#xff0c;其在数据可视化原型设计中的应用&#xff0c;正逐步揭开产品设计的新篇章。本文将从多个维…

同声翻译怎么做?其实有这几种方法

同声翻译怎么做&#xff1f;同声翻译&#xff08;Simultaneous Interpretation&#xff09;是指在说话人讲话的同时&#xff0c;翻译人员即时将内容转换成另一种语言的过程。随着全球化的发展和技术的进步&#xff0c;同声翻译已成为跨文化交流的重要工具。那么&#xff0c;今天…

stl-priority_queue 优先队列

目录 ​编辑优先队列 头文件&#xff1a;#include《queue》&#xff1b;即可 访问&#xff1a;只能访问队首.top() 添加。push&#xff08;元素&#xff09;&#xff0c;按优先级排列 删除。pop&#xff08;&#xff09;&#xff0c;删除队首元素&#xff08;堆顶&#xff…

嵌入式初学-C语言-八

#接嵌入式初学-C语言-七# 分支结构 分支结构&#xff1a;又被称之为选择结构 选择结构的形式 多分支 语法&#xff1a; if(条件1) { 语句1; } else if(条件2) { 语句2; } ... else { 语句n1; }案例&#xff1a; #include <stdio.h> int main() { // 需求&#xff…

采购订单打开单据时表格行设置颜色

文章目录 采购订单打开单据时表格行根据条件显示背景色Python实现插件实现创建项目创建类&#xff0c;实现接口重写方法编译后挂载插件到表单插件启动开发环境进行测试单元格设置背景色行背景色 采购订单打开单据时表格行根据条件显示背景色 Python实现 import clr clr.AddR…

VitualBox虚拟机重启后配置无法保存,已安装软件变为没有安装

VitualBox虚拟机重启后虚拟机还原为上次开机的状态&#xff0c;安装的安装包配置啥的全部丢失。 按网上的配置了半天也没解决。最终用下面讨巧的办法&#xff0c;即不重启虚拟机。 我们不在重启虚拟机&#xff0c;那我们想关闭虚拟机的时候怎么办呢&#xff1f; 1、按下图所…

104 二叉树的最大深度

解题思路&#xff1a; \qquad 最大深度可以想到使用DFS(深度优先)或BFS(广度优先)来解决。 \qquad DFS&#xff1a;一般用 递归 or 迭代栈。递归实现较为简单。 \qquad BFS&#xff1a;一般用 迭代队列。 DFS&#xff1a; \qquad 对于每个节点&#xff0c;将左子树的最大深…

二进制搭建 Kubernetes v1.20(上)

目录 一、操作系统初始化配置 二、升级Liunx内核 三、部署docker引擎 四、部署etcd集群 五、部署Master组件 六、部署Worker Node组件 hostnameip需要部署k8s集群master0120.0.0.100kube-apiserver kube-controller-manager kube-scheduler etcdk8s集群master0220.0.0.1…

小阿轩yx-部署 KVM 虚拟化平台

小阿轩yx-部署 KVM 虚拟化平台 案例前置知识点 KVM 自 Linux 2.6.20 版本之后就直接整合到 Linux 内核依托 CPU 虚拟化指令&#xff08;如Intel-VT、AMD-V&#xff09;实现高性能的虚拟化支持与 Linux 内核高度整合&#xff0c;在性能、安全性、兼容性、稳定性上都有很好的表…

11day-C++list容器使用

这里写目录标题 1. list的介绍及使用1.1 list的介绍1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity1.2.4 list element access1.2.5 list modifiers1.2.6 list的迭代器失效 2. list的模拟实现2.1 list的反向迭代器 1. list的介绍及使用 1.1 list的介绍 list的…

Teamcenter用本地胖客户端启动时,可以看到插件的菜单项,但是用Eclipse启动时看不到

用本地胖客户端启动时&#xff0c;可以看到定制包的插件菜单项&#xff0c;但是用Eclipse启动时&#xff0c;看不到&#xff1f; 原因&#xff1a; 是因为Eclipse启动下&#xff0c;是采用 JAVA1.8 来运行的。但是本机的胖客户端是采用JAVA 11来运行的 解决办法&#xff1a;…

二,SSM 搭建环境:持久化层

二&#xff0c;SSM 搭建环境&#xff1a;持久化层 文章目录 二&#xff0c;SSM 搭建环境&#xff1a;持久化层物理建模&#xff1a;创建对应的 数据库和数据表Mybatis 逆向工程 的配置设置执行逆向生成资源归位(逆行生成的内容&#xff0c;移动到对应模块的包当中去)移动&#…

Hive-内部表和外部表

区别 内部表实例 准备数据 查看数据 删除数据 外部表实例 准备数据 查看数据 删除数据 区别 内部表&#xff1a;管理元数据&#xff08;记录数据的文件和目录的信息&#xff09;和数据。当删除内部表时&#xff0c;会删除数据和表的元数据&#xff0c;所以当多个表关…

Creo protoolkit 二次开发(三) 遍历模型的特征

一、特征概念 Creo是基于特征的参数化建模&#xff0c;在模型树上的每个项目都是特征。 模型主要由各类特征构成。以零件模型为例&#xff0c;其基本特征包括基准特征、拉伸特征、孔特征、倒圆角特征、旋转特征、曲面特征、切口特征、阵列特征和扫描特征等。这些特征的叠加形成…

angular入门基础教程(七)系统路由

路由的实现 当我们系统越来复杂&#xff0c;功能越来越多&#xff0c;路由也就是必须的了。在 ng 中如何实现路由呢&#xff1f; 启用路由 在 app 目录下&#xff0c;新建一个 router 目录&#xff0c;把 app.routers.ts 文件拷贝过来&#xff0c;并修改一下。 import { Ro…

【数据结构】链式二叉树的实现和思路分析及二叉树OJ

【数据结构】链式二叉树的实现和思路分析及二叉树OJ &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;数据结构 文章目录 【数据结构】链式二叉树的实现和思路分析及二叉树OJ前言一.链式二叉树的定义及结构二.链式二叉树的遍历2.1前序遍历2.2中…

《LeetCode热题100》---<双指针篇四道②>

本篇博客讲解LeetCode热题100道双指针篇中的 第三道&#xff1a;三数之和&#xff08;中等&#xff09; 第四道&#xff1a;接雨水&#xff08;困难&#xff09; 第三道&#xff1a;三数之和&#xff08;中等&#xff09; 法一&#xff1a;暴力枚举&#xff08;三重循环&#x…

Java学习Day18:基础篇8

多态 基本信息&#xff1a; 应用场景&#xff1a; 可以把子类对象赋值给父类对象&#xff0c;实现多态从而使用同一种方法&#xff1b; 多态中调用成员的特点 1.调用成员变量都看左边 调用成员变量:编译看左边&#xff0c;运行也看左边 编译看左边: javac编译代码的时候&a…