跨平台 C++ 程序崩溃调试与 Dump 文件分析
前言
C++ 程序在运行时可能会由于 空指针访问、数组越界、非法内存访问、栈溢出 等原因崩溃。为了分析崩溃原因,我们通常会生成 Dump 文件(Windows 的 .dmp,Linux 的 core,macOS 的 .crash),然后用调试工具分析。
1. Windows: MiniDump 生成 .dmp 文件
Windows 提供了 MiniDumpWriteDump() API 来生成 MiniDump 文件(.dmp),它可以记录程序崩溃时的内存、线程、异常信息等。
1.1 MiniDumpWriteDump() 介绍
BOOL MiniDumpWriteDump(HANDLE hProcess, // 进程句柄DWORD ProcessId, // 进程 IDHANDLE hFile, // Dump 文件句柄MINIDUMP_TYPE DumpType, // Dump 类型PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, // 异常信息 (可选)PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, // 额外数据 (可选)PMINIDUMP_CALLBACK_INFORMATION CallbackParam // 回调函数 (可选)
);
1.2 参数解析
| 参数 | 作用 |
|---|---|
hProcess | 进程句柄(用 GetCurrentProcess() 获取) |
ProcessId | 进程 ID(用 GetCurrentProcessId() 获取) |
hFile | 目标 Dump 文件的句柄(用 CreateFile() 创建) |
DumpType | Dump 类型(控制记录多少信息) |
ExceptionParam | 异常信息(用于捕获崩溃时的状态,可选) |
UserStreamParam | 额外数据(可为空) |
CallbackParam | 回调函数(可为空) |
1.3 Dump 类型(MINIDUMP_TYPE)
| 类型 | 值(十六进制) | 描述 |
|---|---|---|
| MiniDumpNormal | 0x00000000 | 默认值,仅包含基本信息(进程、线程、模块) |
| MiniDumpWithDataSegs | 0x00000001 | 记录全局变量数据段 |
| MiniDumpWithFullMemory | 0x00000002 | 完整 Dump,包含所有进程内存(文件较大) |
| MiniDumpWithHandleData | 0x00000004 | 记录所有句柄信息 |
| MiniDumpFilterMemory | 0x00000008 | 过滤一些私有的内存区域以减少 Dump 大小 |
| MiniDumpScanMemory | 0x00000010 | 扫描进程内存以获取更多信息 |
| MiniDumpWithUnloadedModules | 0x00000020 | 记录已卸载的模块 |
| MiniDumpWithIndirectlyReferencedMemory | 0x00000040 | 记录被指针间接引用的内存内容 |
| MiniDumpFilterModulePaths | 0x00000080 | 仅记录模块路径,不包含完整的模块数据 |
| MiniDumpWithProcessThreadData | 0x00000100 | 记录进程/线程额外信息 |
| MiniDumpWithPrivateReadWriteMemory | 0x00000200 | 记录进程私有的读写内存 |
| MiniDumpWithoutOptionalData | 0x00000400 | 不包含可选数据,减小 Dump 大小 |
| MiniDumpWithFullMemoryInfo | 0x00000800 | 记录完整的内存信息 |
| MiniDumpWithThreadInfo | 0x00001000 | 记录所有线程的详细信息 |
| MiniDumpWithCodeSegs | 0x00002000 | 记录代码段信息 |
| MiniDumpWithoutAuxiliaryState | 0x00004000 | 不包含辅助状态信息 |
| MiniDumpWithFullAuxiliaryState | 0x00008000 | 记录完整的辅助状态信息 |
| MiniDumpWithPrivateWriteCopyMemory | 0x00010000 | 记录写时复制(Copy-on-Write)的私有内存 |
| MiniDumpIgnoreInaccessibleMemory | 0x00020000 | 忽略无法访问的内存区域 |
| MiniDumpWithTokenInformation | 0x00040000 | 记录进程的 Token 信息(用于权限分析) |
| MiniDumpWithModuleHeaders | 0x00080000 | 记录模块的 PE 头信息 |
| MiniDumpFilterTriage | 0x00100000 | 仅记录用于故障诊断的最小数据集 |
| MiniDumpValidTypeFlags | 0x001FFFFF | 所有可用的 Dump 类型标志位(用于验证 Dump 类型) |
推荐使用 MiniDumpWithDataSegs | MiniDumpWithThreadInfo,可以更全面地分析崩溃原因。
1.4 自定义 Dump 文件存储路径
在 Windows 上,我们可以自定义 Dump 文件的存储路径,例如存放到 C:\Dumps\ 目录下:
std::string dumpPath = "C:\\Dumps\\crash_dump.dmp";
HANDLE hFile = CreateFileA(dumpPath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
确保 C:\Dumps\ 目录存在,否则 CreateFileA() 可能会失败。
1.5 Windows 代码示例
#include <windows.h>
#include <dbghelp.h>
#include <iostream>#pragma comment(lib, "dbghelp.lib")void CreateDump(const std::string& dumpPath, EXCEPTION_POINTERS* pExceptionInfo) {HANDLE hFile = CreateFileA(dumpPath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile != INVALID_HANDLE_VALUE) {MINIDUMP_EXCEPTION_INFORMATION dumpInfo;dumpInfo.ThreadId = GetCurrentThreadId();dumpInfo.ExceptionPointers = pExceptionInfo;dumpInfo.ClientPointers = TRUE;MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpWithDataSegs | MiniDumpWithThreadInfo, &dumpInfo, NULL, NULL);CloseHandle(hFile);}
}LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS* pExceptionInfo) {std::string dumpPath = "C:\\Dumps\\crash_dump.dmp";CreateDump(dumpPath, pExceptionInfo);return EXCEPTION_EXECUTE_HANDLER;
}int main() {SetUnhandledExceptionFilter(ExceptionHandler);// 触发崩溃int* p = nullptr;*p = 10;return 0;
}
1.6 Dump 分析
可以用 Visual Studio 或 WinDbg 打开 .dmp 文件,查看调用栈、崩溃地址等信息。
2. Linux: Core Dump 生成
Linux 默认会生成 core 文件,记录程序崩溃时的内存状态。
2.1 启用 Core Dump(需要命令启动)
ulimit -c unlimited # 允许生成 core dump 文件
2.2 自定义 Core Dump 存储路径
可以修改 /proc/sys/kernel/core_pattern 来改变 Core Dump 存放路径,例如:
echo "/tmp/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
这样崩溃后,Core Dump 文件将存放到 /tmp/ 目录,并包含程序名和进程 ID。
2.3 代码示例
#include <iostream>
#include <csignal>
#include <sys/resource.h>void EnableCoreDump() {struct rlimit core_limit = { RLIM_INFINITY, RLIM_INFINITY };setrlimit(RLIMIT_CORE, &core_limit);
}void Crash() {int* p = nullptr;*p = 42;
}int main() {EnableCoreDump();Crash();return 0;
}
2.4 Dump 生成路径
-
默认在当前目录 ./core
-
或 /var/lib/systemd/coredump/
-
可修改 /proc/sys/kernel/core_pattern
2.5 Dump 分析
gdb ./your_program core
bt # 查看调用栈
3. macOS: Crash Report(需要命令启动)
3.1 启用 Core Dump(需要命令启动)
macOS 也可能默认 禁用了 Core Dump,需要运行以下命令启用:
ulimit -c unlimited
3.2 自定义 Core Dump 存储路径
macOS 默认将 .crash 文件存放在 ~/Library/Logs/DiagnosticReports/,但可以使用 ulimit -c unlimited 后修改:
echo "/tmp/crash.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
这样崩溃后,Crash Report 文件会存放到 /tmp/ 目录。
3.3 代码示例
#include <iostream>
#include <csignal>void Crash() {int* p = nullptr;*p = 42;
}int main() {signal(SIGSEGV, [](int signum) {std::cerr << "Segmentation fault caught!" << std::endl;exit(1);});Crash();return 0;
}
3.4 Dump 分析
lldb -c ~/Library/Logs/DiagnosticReports/YourApp.crash
bt # 查看调用栈
结论
参考表:如何判断崩溃原因
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
崩溃在 nullptr 访问 | 访问空指针 | assert(p != nullptr); |
| 崩溃在数组访问 | 数组越界 | 开启 ASan,检查索引 |
delete 崩溃 | 释放了已释放的内存 | nullptr 赋值后再 delete |
| 运行一段时间后崩溃 | 内存泄漏或数据竞争 | 启用 Valgrind 或 ThreadSanitizer |
| GUI 无响应 | 死锁或 UI 线程阻塞 | 检查 std::mutex 是否死锁 |
对比总结
| 平台 | 默认 Dump 目录 | 是否需要命令启动 | Dump 文件格式 | 代码生成 Dump | 触发 Dump 的方式 | 如何分析 Dump | 调试工具 |
|---|---|---|---|---|---|---|---|
| Windows | %LOCALAPPDATA%\CrashDumps\ 或 C:\Users\<用户名>\AppData\Local\CrashDumps\ | ❌ 无需命令 | .dmp | MiniDumpWriteDump() 生成 .dmp | 进程崩溃自动生成 或 手动调用 MiniDumpWriteDump() | WinDbg (!analyze -v),Visual Studio 直接打开 .dmp | WinDbg, Visual Studio |
| Linux | ./core 或 /var/lib/systemd/coredump/ | ✅ 需要 ulimit -c unlimited | core | setrlimit(RLIMIT_CORE, &core_limit) 生成 core | 进程崩溃(SIGSEGV 等)自动生成 或 gcore 手动触发 | gdb <程序> <core>,或 eu-stack -p core | gdb |
| macOS | ~/Library/Logs/DiagnosticReports/ | ✅ 需要 ulimit -c unlimited | .crash | signal(SIGSEGV, handler) 生成 .crash | 进程崩溃(SIGSEGV 等)自动生成 或 lldb -> process save-core 生成 | lldb -c <crash文件>,atos -o <可执行文件> -p <进程ID> | lldb, atos |
相关文章:
跨平台 C++ 程序崩溃调试与 Dump 文件分析
前言 C 程序在运行时可能会由于 空指针访问、数组越界、非法内存访问、栈溢出 等原因崩溃。为了分析崩溃原因,我们通常会生成 Dump 文件(Windows 的 .dmp,Linux 的 core,macOS 的 .crash),然后用调试工具分…...
缺陷VS质量:为何软件缺陷是质量属性的致命对立面?
为何说缺陷是质量的对立面? 核心逻辑:软件质量的定义是“满足用户需求的程度”,而缺陷会直接破坏这种满足关系。 对立性:缺陷的存在意味着软件偏离了预期行为(如功能错误、性能不足、安全性漏洞等)&#…...
伍[5],伺服电机,电流环,速度环,位置环
电流环、速度环和位置环是电机控制系统中常见的三个闭环控制环节,通常采用嵌套结构(内环→外环:电流环→速度环→位置环),各自负责不同层级的控制目标。以下是它们的详细说明及相互关系: 1. 电流环(最内环) 作用:控制电机的电流,间接控制输出转矩(τ=Kt⋅Iτ=Kt⋅…...
RuntimeError: CUDA error: device-side assert triggered
RuntimeError: CUDA error: device-side assert triggered 欢迎来到英杰社区,这里是博主英杰https://bbs.csdn.net/topics/617804998 原因: cuda运行可能是异步的(asynchronously),因此报错信息中提示的位置可能不准确…...
清华大学Deepseek第六版AIGC发展研究3.0(共186页,附PDF下载)
人工智能生成内容(AIGC)正以前所未有的速度改变我们的生活。 2024年底,清华大学新闻与传播学院与人工智能学院联合发布了《AIGC发展研究3.0版》,这份报告系统梳理了AIGC技术的突破性进展、应用场景及社会影响,并展望了…...
SpringBoot生成唯一ID的方式
1.为什么要生成唯一ID? 数据唯一性:每个记录都需要有一个独一无二的标识符来确保数据的唯一性。这可以避免重复的数据行,并有助于准确地查询、更新或删除特定的记录。 数据完整性:通过使用唯一ID,可以保证数据库中的数…...
通俗易懂的分类算法之K近邻详解
通俗易懂的分类算法之K近邻详解 用最通俗的语言和例子,来彻底理解 K近邻(K-Nearest Neighbors,简称 KNN) 这个分类算法。不用担心复杂的数学公式,我会用生活中的例子来解释,保证你一听就懂! 1.…...
CSDN markdown 操作指令等
CSDN markdown 操作指令等 页内跳转 [内容](#1) <div id"1"> </div>...
【linux】文件与目录命令 - uniq
文章目录 1. 基本用法2. 常用参数3. 用法举例4. 注意事项 uniq 命令用于过滤文本文件中相邻的重复行,并支持统计重复次数或仅保留唯一行。它通常与 sort 命令配合使用,因为 uniq 只识别相邻的重复行。 1. 基本用法 语法: uniq [选项] [输入…...
零信任沙箱:为网络安全筑牢“隔离墙”
在数字化浪潮汹涌澎湃的今天,网络安全如同一艘船在波涛汹涌的大海中航行,面临着重重挑战。数据泄露、恶意软件攻击、网络钓鱼等安全威胁层出不穷,让企业和个人用户防不胜防。而零信任沙箱,就像是一座坚固的“隔离墙”,…...
【金融量化】Ptrade中交易环境支持的业务类型
1. 普通股票买卖 • 特点: 普通股票买卖是最基础的交易形式,投资者通过买入和卖出上市公司的股票来获取收益。 ◦ 流动性高:股票市场交易活跃,买卖方便。 ◦ 收益来源多样:包括股价上涨的资本利得和公司分红。 ◦ 风险…...
【Java---数据结构】链表 LinkedList
1. 链表的概念 链表用于存储一系列元素,由一系列节点组成,每个节点包含两部分:数据域和指针域。 数据域:用于存储数据元素 指针域:用于指向下一个节点的地址,通过指针将各个节点连接在一起,形…...
紧跟 Web3 热潮,RuleOS 如何成为行业新宠?
Web3 热潮正以汹涌之势席卷全球。从金融领域的创新应用到供应链管理的变革,从社交媒体的去中心化尝试到游戏产业的全新玩法探索,Web3 凭借其去中心化、安全性和用户赋权等特性,为各个行业带来了前所未有的机遇。在这股热潮中,Rule…...
CC++的内存管理
目录 1、C/C内存划分 C语言的动态内存管理 malloc calloc realloc free C的动态内存管理 new和delete operator new函数和operator delete函数 new和delete的原理 new T[N]原理 delete[]的原理 1、C/C内存划分 1、栈:存有非静态局部变量、函数参数、返回…...
Spark核心之02:RDD、算子分类、常用算子
spark内存计算框架 一、目标 深入理解RDD弹性分布式数据集底层原理掌握RDD弹性分布式数据集的常用算子操作 二、要点 ⭐️1. RDD是什么 RDD(Resilient Distributed Dataset)叫做**弹性分布式数据集,是Spark中最基本的数据抽象,…...
【Resis实战分析】Redis问题导致页面timeout知识点分析
事故现象:前端页面返回timeout 事故回溯总结一句话: (1)因为大KEY调用量,随着白天自然流量趋势增长而增长,最终在业务高峰最高点期占满带宽使用100%。   (2&#x…...
单一职责原则(设计模式)
目录 问题: 定义: 解决: 方式 1:使用策略模式 示例:用户管理 方式 2:使用装饰者模式 示例:用户操作 方式 3:使用责任链模式 示例:用户操作链 总结 推荐 问题&a…...
生理信号概念
rPPG 信号(远程光电容积脉搏波信号) 原理: 基于光电容积脉搏波描记法,利用普通摄像头,在一定距离外捕捉人体皮肤表面因心脏泵血导致的血液容积变化引起的细微颜色变化,通过图像处理和信号分析算法提取心率…...
安卓内存泄露之DMA-BUF异常增长:Android Studio镜像引起DMA内存泄露
安卓内存泄露之DMA-BUF异常增长:Android Studio镜像引起DMA内存泄露 - Wesley’s Blog 今天用着安卓 14 的板子的时候突然系统卡死。 查看日志发现launcher都被干掉了 03-04 06:13:35.544 7872 8479 I ActivityManager: vis BFGS 18740: com.android.launcher3 (pid 8407) se…...
android13打基础: 控件checkbox
测试checkbox的activity // todo: 高级控件checkbox public class Ch4_CheckBoxActivity extends AppCompatActivityimplements CompoundButton.OnCheckedChangeListener {Overrideprotected void onCreate(Nullable Bundle savedInstanceState) {super.onCreate(savedInstance…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
