公司动态

dmp文件

📅 2026/8/6 18:47:15
dmp文件
1、关于在QT应用中配置生成小型转储文件minidump时却生成了memory.hdmp文件1.1 memory.hdmp与minidump的区别1. memory.hdmp通常为Windows错误报告WER生成的堆转储文件包含进程内存的完整快照体积较大3。2. minidump.dmp小型转储文件仅包含崩溃时的关键信息如线程状态、寄存器值、堆栈片段体积更小适合调试1。1.2. 可能原因1.2.1 未正确调用MiniDumpWriteDump函数若未在异常处理函数中调用此API系统可能默认生成其他类型的转储文件。解决方案 显式调用MiniDumpWriteDump。在异常处理函数中需手动编写生成minidump的逻辑MiniDumpNormal生成仅含基本信息的minidump。若需更多调试信息可改用MiniDumpWithFullMemory等标志#include DbgHelp.h #pragma comment(lib, DbgHelp.lib) LONG WINAPI CrashInfocallback(EXCEPTION_POINTERS* pException) { HANDLE hFile CreateFile(Lcrash.dmp, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile ! INVALID_HANDLE_VALUE) { MINIDUMP_EXCEPTION_INFORMATION dumpInfo; dumpInfo.ThreadId GetCurrentThreadId(); dumpInfo.ExceptionPointers pException; dumpInfo.ClientPointers FALSE; // 指定生成小型转储类型 MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, dumpInfo, NULL, NULL); CloseHandle(hFile); } return EXCEPTION_EXECUTE_HANDLER; }1.2. 2 WER全局配置覆盖系统级别的错误报告设置可能优先生成heap dump。解决方案禁用WER全局覆盖。通过注册表或组策略关闭系统自动生成heap dump未验证正确性reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting /v Disabled /t REG_DWORD /d 1 /f1.2.3 权限或路径问题程序可能因权限不足未能写入.dmp文件转而生成.hdmp。解决方案验证文件路径与权限。确保程序有权限写入目标目录如避免写入C:\Program Files等受限路径建议指定绝对路径CreateFile(LC:\\logs\\crash.dmp, ...);1.2.4 异常处理链覆盖其他依赖库如Qt框架或第三方库可能覆盖了自定义的异常处理函数解决方案1优先注册异常处理函数。在main函数的最开始注册自定义异常处理避免被后续依赖库覆盖通过此方式确保异常过滤函数位于处理链顶端int main(int argc, char *argv[]) { SetUnhandledExceptionFilter(CustomExceptionFilter); // 最先注册 QApplication a(argc, argv); // ... }2 兼容QT框架行为若Qt内部模块如GUI线程覆盖了异常处理可在关键代码段临时重置过滤器void CriticalFunction() { LPTOP_LEVEL_EXCEPTION_FILTER oldFilter SetUnhandledExceptionFilter(CustomExceptionFilter); // 执行可能崩溃的操作 SetUnhandledExceptionFilter(oldFilter); }1.2.5 DbgHelp版本冲突不同库可能加载了不同版本的DbgHelp.dll导致功能异常。解决方案处理依赖库冲突。• 检查DbgHelp版本确保所有依赖项使用相同版本的DbgHelp.dll可通过静态链接或替换动态库。• 调整链接顺序在.pro文件中将自定义库置于其他库之前LIBS -lMyDebugHelpers -lQt5Core -lOtherLibs使用依赖分析工具通过Dependency Walker或Process Explorer检查冲突的动态库。2、 什么原因会导致本该应为访问不存在的地址崩溃的qt应用程序没有崩溃问题代码char *p new char; delete p; delete p;当QT程序访问无效内存地址时未崩溃可能与以下几个因素有关2.1. 内存填充值与调试环境特性- 在调试模式下内存管理器会用特定模式填充内存如0xcdcdcdcd、0xfeeefeee。这些地址可能在调试时被映射到受控区域访问时触发调试断言而非崩溃。- 例如Windows堆管理器释放内存后填充0xfeeefeee但程序可能未立即回收该内存页面导致访问时未触发访问违例。2.2 操作系统内存管理延迟- 操作系统可能未立即检测到无效访问。例如访问保留但未提交的页面时系统可能延迟触发异常或地址恰好在进程的合法地址空间内如用户态保留区此时不会立即崩溃。2. 3 编译器优化与未定义行为- 编译器可能优化掉部分无效访问代码。例如若无效访问位于未执行的分支中可能被优化删除。- 未定义行为如悬垂指针可能偶然访问到其他有效内存区域导致程序“看似正常”。2. 4. 信号/异常处理机制- 程序可能通过信号处理器如SIGSEGV或结构化异常处理SEH捕获了访问错误。例如cppsignal(SIGSEGV, [](int) { /* 忽略段错误 */ });- Qt框架可能在某些场景下封装了异常处理如事件循环捕获异常但需注意这并非Qt的默认行为。2.5. **内存分配器的行为**- 内存池或延迟回收机制可能导致已释放内存仍可短暂访问。例如某些内存分配器不会立即将释放的内存归还系统此时悬垂指针可能仍“有效”。2.6. **硬件/内存分页机制**- 无效地址可能位于已映射的页内但尚未被操作系统标记为不可访问。例如访问0xdddddddd可能落在进程的保留区域而实际页面属性仍为可读。-排查建议1. **检查内存地址模式**若访问地址为0xcdcdcdcd或0xfeeefeee需排查未初始化或已释放内存的使用。2. **启用调试工具**使用AddressSanitizer或DrMemory检测内存错误。3. **分析崩溃上下文**检查是否因异常处理或Qt事件循环掩盖了问题。3 异常记录中ExceptionFlags在Windows结构化异常处理SEH中ExceptionFlags是异常记录EXCEPTION_RECORD结构中的一个字段用于描述异常发生的上下文或状态。以下是其常见值及含义1. EH_UNWINDING0x1表示当前正在进行堆栈展开stack unwinding通常发生在异常处理过程中需要清理函数调用栈时。2. EH_EXIT_UNWIND0x2表示堆栈展开即将完成此时系统可能正在退出异常处理流程。3. EH_NESTED_CALL0x4表示当前异常是在另一个异常处理过程中触发的嵌套异常。4. EH_TARGET_UNWIND0x10表示堆栈展开的目标是特定的帧如__finally块或异常过滤器。5. EH_COLLIDED_UNWIND0x20表示多个展开操作发生冲突通常与异步异常处理相关。若ExceptionFlags为0x0表示异常可继续执行。若包含0x00000002EXCEPTION_UNWINDING则表示系统正在展开调用栈以寻找异常处理函数。若ExceptionFlags为0x00000001含义该值对应EXCEPTION_NONCONTINUABLE标志表示当前异常是不可继续执行的。若程序尝试在标记此标志的异常后继续执行例如通过异常处理函数返回EXCEPTION_CONTINUE_EXECUTION系统将触发新的异常状态码为STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025。典型场景当程序执行了非法操作如访问无效内存导致异常且该异常未被正确处理时系统可能将此标志置位。此时继续执行会导致程序崩溃或二次异常。exceptioncode :e06d7363(c EH exception)0xE06D7363是Microsoft C编译器生成的标准C异常类型标识符对应代码中的C EH (Exception Handling) exception。该异常通常由以下场景触发使用throw语句抛出的异常未被try/catch块捕获3。对象析构时发生异常如双重异常1。第三方库或系统模块抛出的异常未处理。4.ExceptionCode:cfffffff (application hang)线程是否卡在同步操作如WaitForSingleObject或EnterCriticalSection。是否存在多个线程互相等待资源死锁。是否有线程长时间占用CPU可能为无限循环。4.1常见问题定位示例死锁场景两个线程互相等待对方释放锁。通过!locks和线程堆栈可发现交叉依赖。无限循环某线程的堆栈显示长期停留在同一函数且无退出条件。资源耗尽观察句柄或内存使用量是否异常使用!handle或!heap。