发布时间:2026/8/31 6:47:56
配置更适合生产环境的coredump 简介在文章gdb调试基础中学习了gdb基础的调试命令和手法。但在实际开发过程中除了调试手法之外如何构建出适合生产环境的应用和依赖gdb以什么样的规则还原崩溃现场的依赖我们如何在开发环境下搭建出一套和生产环境类似的依赖路径这些同样非常重要。基于以上问题本篇文章给出了可行的方案和详细的回答我们开始传统coredump生成与调试配置coredump生成你的应用崩溃时Ubuntu默认不会生成coredump需要进行如下配置sudosysctl-wkernel.core_patterncore.%e.%pulimit-cunlimited这样程序崩溃后会在当前目录生成以core开头的dump文件。需要注意的是这样只是临时修改且只对当前shell生效完成coredump的配置之后还需要留意cmake的不同构建类型产生的dump文件存在的差异cmake中的四种构建类型cmake中有Debug、Release、RelWithDebInfo和MinSizeRel四种构件类型Debug包含完整的调试信息编译器不会对代码有任何优化传递-g编译参数Release不包含调试信息编译器会对代码进行优化以提高运行速度-O3 -DNDEBUGRelWithDebInfo包含调试信息编译器会对代码进行一定程度的优化-O2 -g -DNDEBUGMinSizeRel不包含调试信息编译器会启用二进制文件大小的优化这一般应用于资源受限的系统中-Os -DNDEBUG这里值得注意的是cmake中设置CMAKE_BUILD_TYPE为其中某一种类型时本质只是默认配置了向编译器传递的编译参数主要是-g和-O你可以在cmake文件中重新指定覆盖某种构建类型的默认行为调试dump文件完成前面的配置之后你的应用崩溃时在当前目录会生成一个core开头的文件这就是操作系统生成的coredump笔者这里是core.gdb_lab.16872然后直接使用gdb命令如下gdb ./build/gdb_lab core.gdb_lab.16872这样就进入了gdb的交互式界面现在可以按照上一篇文章gdb调试基础介绍的那样开始调试你崩溃的应用了这里需要留意Debug和RelWithDebInfo两种构建类型产生的dump文件能够正常添加断点调试能够正常打印变量信息同时也包含文件名和代码行号等详细信息Release和MinSizeRel这两种构建类型缺乏大量调试内容gdb分析dump文件时bt只能看见简单的堆栈信息更适合生产环境的coredump方案在生产环境中往往不能使用上面的方案因为带有调试符号的应用程序通常非常的大这会为生产环境中部署带来麻烦所以通常的做法是配置编译时携带符号信息产物生成后将应用和依赖中的符号信息复制一份到单独的文件中然后再将这些符号信息从你的应用或者依赖中剥离。当出现core dump时再加载单独的符号文件这样即能保证应用和依赖的体积也能通过加载的符号文件直观的观察崩溃时应用的工作情况两不误编译带符号信息的产物首先需要编译出携带详细符号信息的产物在cmake中通常配置RelWithDebInfo这样编译器会优化代码的同时还会在产物中保留符号信息。读者这里的产物是gdb_lab应用可以通过readelf -S build/gdb_lab | grep debug、file build/gdb_lab和nm build/gdb_lab三个命令查看gdb_lab中是否包含符号信息如果存在的话会观察到以上类似的输出其中file命令显示not stripped。我们来看下现在gdb_lab文件的大小gdb_lab大小为2532448Byte差不多2.4MiB这已经比笔者的测试代码还大了。所以如果在生产环境中还是使用这样的方案那么对生产设备的硬件要求将会相当高。所以这就是需要将符号信息单独提取出来的意义符号提取首先将gdb_lab中的符号信息提取到一个单独的文件中objcopy --only-keep-debug build/gdb_lab build/gdb_lab.debug这样一来在build目录中就会生成文件gdb_lab.debug这就是gdb_lab文件中的符号信息成功提取符号信息之后就可以放心的将符号从gdb_lab中剥离了strip build/gdb_lab-obuild/gdb_lab_stripped执行以上命令后gdb_lab_stripped就是将gdb_lab进行符号剥离后的应用部署到生产环境时就使用gdb_lab_stripped我们来观察一下三者的大小可以看到gdb_lab.debug和gdb_lab_stripped的大小相加差不多就是原始携带符号信息的gdb_lab的大小我们同样使用先前的命令查看被剥离符号信息后的应用观察可以看到这里的输出和前面的输出区别相当大file命令输出strippednm命令输出no symbolscmake自动化提取符号在编译流水线中这样手动提取符号当然不方便可以通过cmake配置自动化的符号提取方案if(CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) add_custom_command(TARGET gdb_lab POST_BUILD COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $TARGET_FILE:gdb_lab ${CMAKE_BINARY_DIR}/gdb_lab.debug COMMAND ${CMAKE_STRIP} $TARGET_FILE:gdb_lab -o $TARGET_FILE:gdb_lab_stripped COMMENT Release: 分离调试符号到 symbols/gdb_lab.debug 并 strip ) endif()这样在完成构建后符号文件和经过strip的应用就都在build目录下了。或者在add_custom_command中不进行strip通过cmake安装时使用cmake--installbuild/--strip这样install中的产物就是将符号剥离后的产物了调试符号剥离后的产物接下来我们直接运行符号剥离后的应用gdb_lab_stripped会产生一个coredump笔者这里是core.gdb_lab_strippe.19187。按照之前的经验我们使用gdbgdb ./build/gdb_lab_stripped core.gdb_lab_strippe.19187发现这里bt之后全是问号这就是因为我们把符号剥离了所以导致这里堆栈信息都是问号。还记得我们一开始使用objcopy 提取出来的符号文件吗这时候就需要在gdb的交互式命令行中加载这个符号文件了symbol-file ./build/gdb_lab.debug符号文件加载后我们的堆栈清晰了很多文件、函数、崩溃的行号都显示出来了此时也可以打印当前栈帧中变量的值。这就是符号文件的作用这里我们注意到在调试符号分离的应用时进入gdb交互界面之后需要手动通过symbol-file命令加载符号文件如果符号文件多了这会比较繁琐有没有什么比较优雅的方法呢当然有通过build id关联符号文件每次编译产物中都会储存一个唯一的Build ID我们可以通过这个Build ID将产物和符号文件进行关联这样就不需要每次手动加载文件了第一步就是确定产物的Build IDreadelf-n./build/gdb_lab_stripped|grepBuild ID笔者这里的Build ID为139f2905c87e07d3ee995767c64b4cb5684697fbgdb在加载应用后会去固定规则的目录下查找符号文件规则如下/usr/lib/debug/.build-id/前两位十六进制/剩余部分.debug这里的/usr/lib/debug目录在gdb交互式命令行中通过show debug-file-directory得到对于笔者这里的产物来说gdb会自动判断/usr/lib/debug/.build-id/13/9f2905c87e07d3ee995767c64b4cb5684697fb.debug文件是否存在如果存在则会自动加载符号反之则不会加载需要手动加载嗯这好像也不是很方便add-gnu-debuglink关联符号文件上面一种自动加载符号文件的方案也没有减少太多工作量通过add-gnu-debuglink的方式关联符号文件会方便很多这种方式需要在编译阶段添加额外的步骤if(CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) add_custom_command(TARGET gdb_lab POST_BUILD COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $TARGET_FILE:gdb_lab ${CMAKE_BINARY_DIR}/gdb_lab.debug COMMAND ${CMAKE_STRIP} $TARGET_FILE:gdb_lab -o $TARGET_FILE:gdb_lab_stripped COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglinkgdb_lab.debug $TARGET_FILE:gdb_lab_stripped COMMENT Release: 分离调试符号到 symbols/gdb_lab.debug 并 strip ) endif()我们对比上面的cmake这里通过objcopy将符号文件的文件名和strip之后的产物进行了关联可以通过objdump-s-j.gnu_debuglink ./build/gdb_lab_stripped这个命令查看关联关系是否成功建立一切顺利的话将会输出gdb_lab.debug即表示gdb_lab_stripped关联的符号文件名称为gdb_lab.debug符号文件和产物的关联关系确定了那么这种方式下gdb会去哪些目录下查找这个文件呢可执行文件所在目录对于笔者这里来说就是会尝试加载./build/gdb_lab.debug可执行文件目录下的 .debug/ 子目录笔者这里会尝试加载./build/.debug/gdb_lab.debugdebug-file-directory默认 /usr/lib/debug拼接可执行文件的完整路径笔者这里会尝试加载/usr/lib/debug/home/zuoluo/SourceCode/gdbTest/build/gdb_lab.debug以上三条规则就是通过add-gnu-debuglink建立关联关系后gdb查找符号文件的规则gdb如果成功找到符号文件则会输出Reading symbols from /home/zuoluo/SourceCode/gdbTest/build/.debug/gdb_lab.debug可以留意gdb的输出内容这要友好很多更推荐这种方式配置动态库加载路径在实际开发中崩溃环境现场通常远离我们的开发环境。coredump是应用在发生崩溃时操作系统为其生成的进程快照这其中也包括应用依赖哪些动态库以及这些动态库的位置这些位置信息硬编码到coredump文件中gdb在调试coredump文件时会使用硬编码的位置查找动态库并加载info sharedlibrary命令直观的展示了哪些动态库被gdb加载了哪些没有找到所以在开发环境调试coredump文件时设置gdb搜索和加载动态库的路径就显得非常关键solib-search-path在进入gdb的交互式界面之后可以通过set solib-search-path的方式设置gdb搜索动态库的路径上图可以看到gdb还没有加载libgdblib.so库bt时不能显示任何符号信息info sharedlibrary也显示libgdblib.so是No的状态这时候就需要我们手动设置动态库的搜索路径了上图通过solib-search-path设置了搜索路径gdb立刻尝试从新设置的路径中加载那些还未加载的动态库这里就是libgdblib.so。因为我在相同路径下放置了对应动态库的符号文件所以对应符号文件也自动加载了进来。如此一来bt就能看到详细的堆栈信息了可以看到堆栈中还存在一些无法解析的符号那是因为笔者这里只加载了动态库的符号文件gdblib.debug没有加载可执行程序的符号文件这里还需要注意的一点是如果在set solib-search-path之前gdb就已经找到了需要加载的动态库那么即使你通过set solib-search-path设置的目录下有需要的动态库那么gdb也不会尝试重新加载会继续使用已经加载的动态库sysroot通过set sysroot的方式可以设置路径前缀。怎么理解呢coredump中记录了应用崩溃时各个动态库的绝对路径调试coredump时gdb尝试加载这些动态库如果不存在则不加载如果我们设置了sysroot那么gdb就会将sysroot设置的路径拼接到从coredump中读取的路径之前作为一个新的绝对路径去加载。这对于生产环境中依赖复杂的应用非常好使笔者这里设置了/home/zuoluo/SourceCode/gdbTest为sysrootgdb将sysroot的路径拼接到coredump中记录的路径之前这里值得注意的是即使在set sysroot之前gdb已经找到了对应的动态库当设置了set sysroot之后gdb也会按照设置的sysroot重新去查找和加载动态库如果找不到那么gdb不会使用原来加载成功的库info sharedlibrary会显示未加载.gdbinit自动化配置文件谁也不想coredump但是现实往往事与愿违线上总是出现coredump每一次的coredump在进入gdb调试界面时都需要执行差不多的命令配置符号环境、动态库搜索路径等这会有大量重复性劳动特别是一遇到工程比较大同时依赖比较复杂的情况这样每次都手动配置环境会大大增加调试负担。有没有什么解决方案呢答案当然是有的——.gdbinit.gdbinit一般放在家目录下gdb在启动调试某个应用后会去家目录读取这个文件你在这个文件中写的任何调试配置命令都会被gdb执行不再需要你手动去配置这很优雅当然你也可以自定义文件路径然后通过gdb命令行参数指定某个自动化配置文件gdb-x./my.gdbinit ./build/bin/gdb_lab core.gdb_lab.7681my.gdbinit文件中配置的指令就会被gdb正确的执行非常方便总结本文介绍了coredump配置的方法再此基础上给出了cmake工程下更适合生产环境的配置方案回答了gdb在调试时的一些默认行为规则了解掌握这些规则能够帮助我们设计更好的自动化配置方案大大提高我们的调试效率

相关新闻

2026/8/31 6:47:56

数据中心租赁技术指南:从需求测算到业务迁移的实践要点

当大厂开始算起经济账时,数据中心租赁从备选方案变成了热门生意。这个趋势看起来是财务决策,落到基础设施团队面前却是一连串具体技术问题:业务要租多少机柜,单机柜按多大功率申请,网络接入选单线还是多线,…

2026/8/31 6:47:56

DCO-OFDM可见光通信仿真:MATLAB实现、直流偏置与BER分析

简介:本资源是一个面向通信工程专业本科生及可见光通信初学者的MATLAB仿真项目,聚焦DCO-OFDM调制技术在可见光通信系统中的性能评估问题,特别适用于理解光通信中直流偏置设计、AWGN信道建模与误码率分析等核心环节。压缩包仅含1个MATLAB脚本文…

2026/8/31 6:47:56

Phigros高难谱面AP全攻略:从判定机制到实战练习

刚接触 Phigros 高难度谱面的时候,很多人都会把“把 All Perfect 打出来”当作一个阶段性的证明。而当你看到标题里“定数组用骰子定的16.2”这样的表述,可能第一反应是:这是一首定数被随机分配的谱面,还是一场靠运气完成的挑战&a…

2026/8/31 6:57:56

Windows许可证能退款吗?类型、条件与操作流程详解

当你买了新电脑或单独购买了 Windows 许可证,却因为各种原因不再需要它时,很自然会想问一个问题:Windows 许可证能退款吗?这个问题在开发者、企业采购和普通用户之间其实经常出现。有人是因为预装系统的电脑退货了,有人…

2026/8/31 6:57:56

HarmonyOS 鸿蒙家庭中控与全屋智能联动

一、为什么这是鸿蒙新生态的关键能力鸿蒙新生态的价值不只是把应用搬到新的系统上,而是把服务拆成能被系统理解、能被多端调用、能在场景里自然出现的能力。全屋智能正是这种思路的典型切入点。它关注的不是单一页面的漂亮程度,而是用户在回家模式里是否…

2026/8/31 6:57:56

Node.js后端库1.0版本接入实战:从评估到生产调优

一个 Node.js 后端库发布 1.0 版本,是开发链路里值得停下来认真看的节点。这个版本号不是普通更新,它意味着项目对外承诺了相对稳定的 API 边界,你可以开始评估它能不能进入生产环境,而不是只在 Demo 里跑一跑。如果你正在做后端选…

2026/8/31 6:57:56

头条研发岗四轮面试实战复盘:算法、系统设计与项目深挖全记录

第一次收到今日头条研发岗的面试邀请时,我正在工位上改一个线上BUG。电话那头HR语速很快,问我明天下午有没有时间,二面直接安排在后天。这种快节奏,后来成了贯穿整场面试的主旋律。这篇面经不是网上那种“整理高频题”的汇总&…

2026/8/31 6:57:56

小米2019秋招算法笔试题A卷全解析:从KMP到动态规划

一年一度的秋招又要开始了,算法岗笔试题永远是大家最头疼的关卡。翻出我自己当年整理的小米2019秋招算法笔试题(A卷),发现很多思路直到今天依然适用。这份试卷覆盖了数据结构、字符串匹配、动态规划、机器学习基础等多个维度&…

2026/8/31 6:52:56

基于Spring Boot与uniapp的全开源微信小程序商城实战指南

简介:这是一套面向Java后端与uniapp前端开发者、专为快速构建微信小程序商城而设计的全栈开源解决方案,适用于新零售、线上网店及轻量级电商建站场景,尤其适合具备基础Web开发能力的中初级工程师学习与二次开发。资源包共2000个文件&#xff…

2026/8/31 1:05:20

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/31 2:14:20

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/31 1:41:28

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/8/31 0:07:32

STM32C5设备支持包(IAR DFP)安装指南与常见坑

上一阵子在IAR里折腾一块基于STM32C5系列的新板子,工程从STM32CubeMX导出来之后怎么都编译不过。报错信息很干脆:找不到设备描述文件。跟着错误路径去查,发现指向的是一个让我愣了一下的名字:STMicroelectronics.stm32c5xx.2.1.0.…

2026/8/31 0:07:32

STM32N657 SWO引脚矛盾:CubeMX显示PB3,数据手册为PB5

拿到STM32N657这颗料的第一天,我就撞上了一个让人原地懵圈的引脚矛盾:CubeMX里清清楚楚显示SWO在PB3,翻开数据手册的引脚说明表,却赫然写着PB5。对于一个靠SWO输出调试日志吃饭的人而言,这种"工具和手册打架"…

2026/8/28 16:16:48

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/28 16:16:50

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/31 6:53:02

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…