配置更适合生产环境的coredump

发布时间:2026/10/21 12:46:44

配置更适合生产环境的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/10/19 15:36:51

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

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

2026/10/21 6:57:46

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

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

2026/10/21 7:42:13

ESP32-S3驱动3.97寸AXS15260屏的LVGL9完整开发指南

这次我们来看一个嵌入式 UI 工程:esp32s31_3.97寸axs15260_lvgl9。项目命名非常直白,对应的是 ESP32-S3 主控、3.97 寸 AXS15260 驱动芯片的 LCD 模组,再配合 LVGL 9 图形库做界面渲染。这套组合在小型 HMI、桌面摆件、智能家居控制面板里很常…

2026/10/21 12:45:49

把决策从大模型里拆出来:Agent架构中的System One实践

把「决策」从大模型里拆出来,是我今年在 Agent 架构上做得最值的一笔投资。先说结论:不是所有事情都要让那个上千亿参数的大模型来拍板,很多高频、小颗粒、模式固定的决策,完全可以用一个极轻量的 System One 模型来接管。这个思路…

2026/10/21 12:45:49

AI可复现性挑战:从随机种子到环境固定的全链路方案

最近几年,AI行业最不缺的就是“跑通的模型”和“没法复现的结果”。坦白说,入行越久,我越觉得“AI可复现性”像个被低估的硬门槛——很多团队能训练出精度不错的模型,但换台机器、换个环境、甚至换个同学重新执行一遍,…

2026/10/21 12:45:49

详解Git安装:Windows/macOS/Linux全平台配置与避坑指南

Git 安装教程这个题目,看起来像是给新手准备的基础内容,但我在实际帮人排查环境时发现,很多写了两年代码的人,装 Git 这一步也未必真弄明白了。装完能敲出 git --version ,跟装到顺手、装到不耽误后续开发&#xff0…

2026/10/21 12:45:49

AI漫剧规模化生产:从剧本到成片的完整工作流拆解

1. 项目概述与整体思路1.1 为什么AI漫剧能跑通"规模化"这条路先说结论:AI漫剧不是传统动画的替代品,而是一个全新的内容品类。它把动画制作从"人力密集型"彻底转成"算力密集型",这才是它能规模化的根本原因。过…

2026/10/21 12:45:49

740M多模态嵌入模型如何实现离线RAG落地

1. 项目概述:为什么740M的多模态嵌入模型突然成了RAG落地的关键支点“EmbeddingGemma 2:740M 多模态嵌入怎么跑离线 RAG”——这个标题一出来,我手边刚泡好的第三杯茶就凉了。不是因为技术太冷门,恰恰相反,它热得发烫&…

2026/10/21 12:40:48

LangChain + RAG实战:构建企业知识库问答系统的完整指南

做应用开发,总要面对一个尴尬:大模型看起来什么都懂,但一旦问到你们公司的报销制度、项目记录、售后口径,它就露馅了——要么不知道,要么编一个像模像样的答案。这也是这几年大模型落地时最常被追问的问题。RAG&#x…

2026/10/21 4:53:08

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/21 0:00:35

交通流仿真实战:IDM跟驰与MOBIL换道模型参数调优与避坑指南

简介:这份资源是面向交通工程学习者与Python开发者的微观交通流仿真项目,核心实现智能驾驶模型(IDM)下的车辆跟驰与换道行为,可用于理解速度、密度与流量之间的动态关系,适合具备Python基础、希望深入交通模…

2026/10/21 0:00:35

揭穿智能体表面顺从:用追踪代码重建任务执行确定性

1. 表面顺从不是智能体的“礼貌”,而是任务执行链路上的隐性断点最近在调试一个跨平台长周期任务调度系统时,我反复遇到一种令人困惑的现象:智能体在用户指令发出后,几乎秒级响应“已收到”“正在处理”“请稍候”,UI上…

2026/10/21 0:00:35

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑