一、Windows系统的任务管理器里抓dump
启动任务管理器,选中某个进程,右键,弹出菜单"创建转储文件"
注意事项:
当你在64位Windows系统上抓32位进程的dmup文件时,如果用的是64位任务管理器,那么在用Windbg加载后,要用!wow64exts.sw切换到X86模式下,如果不想做这步切换,就要用32位的任务管理器来生成dmp文件。32位任务管理器在C:\Windows\SysWOW64\Taskmgr.exe
适合的场景:在任务管理器里还能看到进程,当程序出现业务问题、性能问题、失去响应;当程序崩溃跳出系统错误提示框的时候,特别适合应用在客户机出现上述问题时使用。因为我们不用传其他工具到客户机上。
二、修改注册表
@echo off
echo 正在启用Dump...
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps"
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d "D:\CrashDumps" /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2 /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpCount /t REG_DWORD /d 10 /f
echo Dump已经启用
pause
@echo on
将上述内存保存为*.bat,然后执行,就开始了自动抓dmp文件的功能,只要有程序崩溃,就会在指定的目录下生成。
键值说明:
名称:DumpCount
,类型:REG_DWORD
,最大保留Dump个数,默认为10.
名称:DumpType
,类型:REG_DWORD
,Dump类型(1-Mini dump, 2-Full dump),默认为1.
名称:DumpFolder
,类型:REG_EXPAND_SZ
,Dump文件保存的位置。
当不需要自动抓取时,可以将下面的内容
@echo off
echo 正在关闭Dump...
reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /f
echo Dump已经关闭
pause
@echo on
保存为bat执行,就不会在自动产生了
适合的场景:无法稳定重现的崩溃问题抓取
三、编程
直接使用Windows的API——MiniDumpWriteDump和SetHandleExceptionFilter。
1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using System.IO; 5 using System.Linq; 6 using System.Runtime.InteropServices; 7 using System.Text; 8 using System.Threading; 9 using System.Threading.Tasks; 10 11 namespace MyCommon 12 { 13 public static class MiniDump 14 { 15 /* 16 * 导入DbgHelp.dll 17 */ 18 [DllImport("DbgHelp.dll")] 19 private static extern Boolean MiniDumpWriteDump( 20 IntPtr hProcess, 21 Int32 processId, 22 IntPtr fileHandle, 23 MiniDumpType dumpType, 24 ref MinidumpExceptionInfo excepInfo, 25 IntPtr userInfo, 26 IntPtr extInfo ); 27 28 /* 29 * MINIDUMP_EXCEPTION_INFORMATION 这个宏的信息 30 */ 31 struct MinidumpExceptionInfo 32 { 33 public Int32 ThreadId; 34 public IntPtr ExceptionPointers; 35 public Boolean ClientPointers; 36 } 37 38 /* 39 * 自己包装的一个函数 40 */ 41 public static Boolean TryDump(String dmpPath, MiniDumpType dmpType) 42 { 43 44 //使用文件流来创健 .dmp文件 45 using (FileStream stream = new FileStream(dmpPath, FileMode.Create)) 46 { 47 //取得进程信息 48 Process process = Process.GetCurrentProcess(); 49 // MINIDUMP_EXCEPTION_INFORMATION 信息的初始化 50 MinidumpExceptionInfo mei = new MinidumpExceptionInfo(); 51 mei.ThreadId = Thread.CurrentThread.ManagedThreadId; 52 mei.ExceptionPointers = Marshal.GetExceptionPointers(); 53 mei.ClientPointers = true; 54 55 //这里调用的Win32 API 56 Boolean res = MiniDumpWriteDump( 57 process.Handle, 58 process.Id, 59 stream.SafeFileHandle.DangerousGetHandle(), 60 dmpType, 61 ref mei, 62 IntPtr.Zero, 63 IntPtr.Zero); 64 65 //清空 stream 66 stream.Flush(); 67 stream.Close(); 68 return res; 69 } 70 } 71 72 public enum MiniDumpType 73 { 74 None = 0x00010000, 75 Normal = 0x00000000, 76 WithDataSegs = 0x00000001, 77 WithFullMemory = 0x00000002, 78 WithHandleData = 0x00000004, 79 FilterMemory = 0x00000008, 80 ScanMemory = 0x00000010, 81 WithUnloadedModules = 0x00000020, 82 WithIndirectlyReferencedMemory = 0x00000040, 83 FilterModulePaths = 0x00000080, 84 WithProcessThreadData = 0x00000100, 85 WithPrivateReadWriteMemory = 0x00000200, 86 WithoutOptionalData = 0x00000400, 87 WithFullMemoryInfo = 0x00000800, 88 WithThreadInfo = 0x00001000, 89 WithCodeSegs = 0x00002000 90 } 91 } 92 }
1 using MyCommon; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading; 7 using System.Threading.Tasks; 8 9 namespace DumpDemo 10 { 11 class Program 12 { 13 static void Main(string[] args) 14 { 15 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler( (obj, ars) => 16 { 17 MiniDump.TryDump("DumpDemo_Err.dmp", MyCommon.MiniDump.MiniDumpType.WithProcessThreadData); 18 Console.WriteLine(ars); 19 }); 20 21 ExceptionFunc(); 22 23 Console.ReadKey(); 24 } 25 26 /// <summary> 27 /// 引发程序奔溃的异常代码 28 /// </summary> 29 static void ExceptionFunc() 30 { 31 new Thread(arg=>Console.WriteLine(arg.ToString())).Start(); 32 } 33 } 34 }
参考:https://www.cnblogs.com/yilang/p/11106495.html
Windbg常用命令:https://www.cnblogs.com/huangsitao/p/10299300.html