编译 C++ 程序:分离与保留调试信息以支持 GDB 对 Core 文件的调试

在 C++ 程序开发过程中,调试是一个非常重要的环节。当程序出现问题,尤其是在生产环境中出现崩溃并生成 Core 文件时,我们需要使用调试工具(如 GDB)对程序进行深入分析,找出问题的根源。为了在需要时能够有效地使用 GDB 进行调试,我们需要一种方法来在编译过程中巧妙地处理调试信息,既能保证最终程序的高效运行,又能在需要时方便地使用调试信息进行故障排查。这就涉及到如何在编译过程中分离和保留调试信息,同时确保 GDB 可以使用这些信息对 Core 文件进行调试。

一、使用 Makefile 实现

DEBUG_FILE = $(TARGET).debug
$(TARGET): $(OBJECTS)$(CC) $(LDFLAGS) $(LIBPATH) -Wl,--start-group $(OBJECTS) $(LIBS) -Wl,--end-group -o $@$(objcopy) --only-keep-debug $(TARGET) $(DEBUG_FILE)$(STRIP) $(TARGET)$(objcopy) --add-gnu-debuglink=$(DEBUG_FILE) $(TARGET)

$(objcopy) --only-keep-debug $(TARGET) $(DEBUG_FILE)
使用 objcopy 工具将 $(TARGET) 中的调试信息提取出来,并存储在 $(DEBUG_FILE) 中。
--only-keep-debug 选项表示只保留调试信息,将其分离出来存储在单独的文件中。这样做的好处是可以减小最终可执行文件的大小,同时保留调试信息以便后续调试。

$(STRIP) $(TARGET)
使用 strip 工具从 $(TARGET) 中去除调试信息和符号表等内容。这样可以减小可执行文件的大小,使其更适合在生产环境中使用,因为这些信息在运行时通常是不需要的。

$(objcopy) --add-gnu-debuglink=$(DEBUG_FILE) $(TARGET)
再次使用 objcopy 工具将调试信息文件 $(DEBUG_FILE) 以 GNU 调试链接的方式添加到 $(TARGET) 中。这样,调试器可以在需要时找到并使用存储在 $(DEBUG_FILE) 中的调试信息,即使这些信息已经从 $(TARGET) 中剥离。这是一种常见的做法,既可以使最终的可执行文件更小,又能在需要调试时仍然可以使用调试信息。

二、使用 CMakeLists.txt 实现


set(DEBUG_FILE ${PROJECT_NAME}.debug)add_custom_command(TARGET ${PROJECT_NAME}POST_BUILDCOMMAND ${OBJCOPY} --only-keep-debug $<TARGET_FILE:${PROJECT_NAME}> ${DEBUG_FILE}COMMENT "Creating debug file ${DEBUG_FILE} from ${PROJECT_NAME}"
)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILDCOMMAND ${CMAKE_STRIP} "$<TARGET_FILE:${PROJECT_NAME}>"COMMENT "Strip debug symbols done on final binary."
)
add_custom_command(TARGET ${PROJECT_NAME}POST_BUILDCOMMAND ${OBJCOPY} --add-gnu-debuglink=${DEBUG_FILE} $<TARGET_FILE:${PROJECT_NAME}>COMMENT "Adding GNU debug link to ${PROJECT_NAME}"
)

2.1 添加自定义命令:分离并存储调试信息:

add_custom_command(TARGET ${PROJECT_NAME}POST_BUILDCOMMAND ${OBJCOPY} --only-keep-debug $<TARGET_FILE:${PROJECT_NAME}> ${DEBUG_FILE}COMMENT "Creating debug file ${DEBUG_FILE} from ${PROJECT_NAME}"
)

add_custom_command:这是 CMake 中的一个函数,用于添加自定义的构建命令。
TARGET ${PROJECT_NAME}:表示这个自定义命令将作用于 ${PROJECT_NAME} 这个目标。
POST_BUILD:指定该命令将在构建 ${PROJECT_NAME} 目标之后执行。

COMMAND ${OBJCOPY} --only-keep-debug $<TARGET_FILE:${PROJECT_NAME}> ${DEBUG_FILE}:
${OBJCOPY} 是一个工具,用于操作对象文件。
--only-keep-debug 是 OBJCOPY 的一个选项,用于从 PROJECT_NAME(使用生成器表达式来获取 ${PROJECT_NAME} 目标的最终文件)中仅提取并保留调试信息。
最终将提取出的调试信息存储在 ${DEBUG_FILE} 中。

2.2 添加自定义命令:去除最终二进制文件中的调试信息:

add_custom_command(TARGET ${PROJECT_NAME} POST_BUILDCOMMAND ${CMAKE_STRIP} "$<TARGET_FILE:${PROJECT_NAME}>"COMMENT "Strip debug symbols done on final binary."
)

${CMAKE_STRIP} 是 CMake 中用于调用 strip 工具的变量。

该命令使用 strip 工具从最终的二进制文件中去除调试信息和符号表,以减小最终二进制文件的大小。

2.3 添加自定义命令:添加 GNU 调试链接:

add_custom_command(TARGET ${PROJECT_NAME}POST_BUILDCOMMAND ${OBJCOPY} --add-gnu-debuglink=${DEBUG_FILE} $<TARGET_FILE:${PROJECT_NAME}>COMMENT "Adding GNU debug link to ${PROJECT_NAME}"
)

COMMAND ${OBJCOPY} --add-gnu-debuglink=${DEBUG_FILE} $<TARGET_FILE:${PROJECT_NAME}>:
再次使用 OBJCOPY 工具,--add-gnu-debuglink=${DEBUG_FILE} 选项将之前存储在 ${DEBUG_FILE} 中的调试信息以 GNU 调试链接的方式添加到最终的二进制文件中。

这样做的好处是既减小了最终二进制文件的大小,又在需要时可以通过该链接使用存储在 ${DEBUG_FILE} 中的调试信息进行调试。

三、实际使用

假如可执行文件是hello
把hello,hello.core,hello.debug放在一个目录,用以下命令,可以自动使用调试文件

gdb hello hello.core
bt //查看堆栈信息

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

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

相关文章

python对mongodb的增删查改

python对mongodb的增删查改 1. 安装 pymongo2. 连接 MongoDB3. 创建&#xff08;插入&#xff09;文档插入单个文档插入多个文档 4. 查询文档查询单个文档查询多个文档复杂查询嵌套查询分页条件查询&#xff08;通用模版&#xff09; 5. 更新文档更新单个文档更新多个文档更新嵌…

Tesseract5.4.0自定义LSTM训练

准备jTessBoxEditor&#xff0c;然后配置环境变量。 1、将图片转换成tif格式的&#xff0c;这里需要用画图工具另存为&#xff1b; 2、生成box文件 执行命令&#xff1a; tesseract agv.normal.exp1.tif agv.normal.exp1 -l eng --psm 6 batch.nochop makebox 关于box文件…

Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(1):Oracle Dataguard 工作原理

Oracle Dataguard&#xff08;主库为 Oracle 11g 单节点&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;Oracle Dataguard 工作原理 目录 Oracle Dataguard&#xff08;主库为 Oracle 11g 单节点&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;Oracle …

Windows系统安装Docker Desktop

文章目录 注意事项安装步骤官网下载软件安装到其它盘符操作(如果就想安装到C盘可以跳过这个步骤, 直接执行文件)等待出现软件安装界面Windows系统的配置软件的一些必要设置(以下设置需要点击apply才能生效&#xff0c;如果点不了&#xff0c;那就是安装后&#xff0c;出现了错误…

从零开始RTSP协议的实时流媒体拉流(pull)的设计与实现(一)

此文为系列文章&#xff0c;此系列主要讲解RTSP客户端的拉流及播放&#xff0c;文章持续更新&#xff0c;会从rtsp的基本协议讲起&#xff0c;如何一步步实现音视频的拉流过程&#xff0c;包括一系列涉及到的协议&#xff0c;rtsp&#xff0c;sdp&#xff0c; rtp&#xff08;本…

让私域用户付费的三个关键要素

在吸引私域用户付费的过程中&#xff0c;有三个关键要素是不可忽视的。 下面&#xff0c;就一起来看看是哪三个要素&#xff0c;帮助你更好地挖掘私域用户的潜力。 价值提供&#xff1a;真正解决用户的问题 简单来说&#xff0c;用户愿意为他们认为有价值的东西付费。当你的…

Qt:子线程在程序退出时的操作

在Qt中可以使用线程指针对子线程进行操作。子线程可以使用使用基本指针&#xff0c;shared_ptr&#xff0c;两种指针进行操作&#xff08;QSharedPointer指针操作有问题还未解决&#xff0c;先不讲&#xff09;。 // c标准库 shared_ptr<QThread> thread_;// 基本指针 Q…

特殊车辆检测数据集VOC+YOLO格式2730张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2730 标注数量(xml文件个数)&#xff1a;2730 标注数量(txt文件个数)&#xff1a;2730 …

LookingGlass使用

背景 Looking Glass 是一款开源应用程序&#xff0c;可以直接使用显卡直通的windows虚拟机。 常见环境是Linux hostwindows guest&#xff0c;基本部署结构图&#xff1a; 编译 git clone --recursive https://github.com/gnif/LookingGlass.git编译client mkdir client/b…

Ceph 手动部署(CentOS9)

#Ceph手动部署、CentOS9、squid版本、数字版本19.2.0 #部署服务:块、对象、文件 一、部署前规划 1、兼容性确认 2、资源规划 节点类型节点名称操作系统CPU/内存硬盘网络组件安装集群节点CephAdm01CentOS94U/8GOS:40G,OSD:2*100GIP1:192.169.0.9(管理&集群),IP2:…

如何优化亚马逊广告以提高ROI?

在竞争激烈的亚马逊市场中&#xff0c;优化广告以提高投资回报率&#xff08;ROI&#xff09;是卖家的关键任务。以下是一些实用的策略&#xff1a; 一、精准的关键词研究与选择 深入了解产品特性和目标受众 详细分析产品的功能、用途、优势和适用人群。例如&#xff0c;如果你…

CSS学习记录23

CSS用户界面 CSS调整大小 resize 属性规定元素是否应&#xff08;以及如何&#xff09;被用户调整大小。下例只允许用户调整 <div> 元素的宽度&#xff1a; div {resize: horizontal;overflow: auto; } 下例只允许用户调整 <div> 元素的高度&#xff1a; div {…

Linux菜鸟级常用的基本指令和基础知识

前言:很多Linux初学者都会头疼于指令太多记不住&#xff0c;笔者刚学习Linux时也是如此&#xff0c;学习Linux指令时&#xff0c;学了后面的指令&#xff0c;前面的指令也会忘的差不多了&#xff0c;针对于以上这些情况&#xff0c;笔者今天来分享一篇Linux菜鸟级的常用指令的博…

【数据仓库】hive on Tez配置

hive on Tez 搭建 前提是hive4.0hadoop3.2.2数仓已搭建完成&#xff0c;现在只是更换其执行引擎 为Tez。搭建可参考【数据仓库】hive hadoop数仓搭建实践文章。 Tez 下载 下载地址 https://archive.apache.org/dist/tez/ 官网地址 https://tez.apache.org/releases/apac…

《机器学习》--线性回归模型详解

线性回归模型是机器学习中的一种重要算法&#xff0c;以下是对其的详细解释&#xff1a; 一、定义与原理 线性回归&#xff08;Linear Regression&#xff09;是利用数理统计中回归分析&#xff0c;来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。线性回归…

电子价签会是零售界的下一个主流?【新立电子】

电子价签&#xff0c;作为一种能够替代传统纸质标签的数字显示屏&#xff0c;已经在零售行业中展现出其巨大的潜力。它具有实时更新、集中管理、高效节能的特点&#xff0c;实现价格的实时更新&#xff0c;大大减少更新价格的工作量和时间。为消费者带来更加便捷、准确的购物体…

sql server期末复习

表操作 创建create 删除drop 修改alter 数据操作 查询 select from <tableName> 插入 insert into <tableName> values 修改 update <tableName> set 删除 delete from <tableName> 授权与收回对数据的操作权限 授予 grant <权…

用python编写一个放烟花的小程序

import pygame import random # 代码解释及使用说明&#xff1a; # 首先&#xff0c;导入 pygame 和 random 库。pygame 用于创建游戏窗口和图形绘制&#xff0c;random 用于生成随机数。 # 初始化 pygame&#xff0c;并设置屏幕尺寸为 800x600 像素&#xff0c;设置窗口标题为…

dns网址和ip是一一对应的吗?

DNS网址和IP地址是一一对应的吗&#xff1f;我们在上网时&#xff0c;为什么总是使用网址而不是一串数字&#xff1f;这些问题其实涉及到互联网的基本运作原理。DNS&#xff08;域名系统&#xff09;是我们日常上网过程中一个不可或缺的部分&#xff0c;它帮助我们将人类易于记…

Json与jsoncpp

目录 一、关于Json 1.数据类型 2.语法规则 二、写Json相关API 1.Json::Value类 2.append方法 3.toStyledString方法 三、读Json相关API 1.Json::Reader类 2.parse方法 3.类型判断方法 4.类型转换方法 5.getMemberNames方法 四、完整代码 一、关于Json Json是一种轻…