❶ 請教一個C#生成mp文件的問題
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace MiniDump
...{
class Program
...{
static void Main(string[] args)
...{
try
...{
string a = "";
a = null;
if (a.ToString() == "1")
Console.WriteLine("a is 1");
}
catch
...{
MiniDump.TryDump("c:MiniDmp.dmp", MiniDump.MiniDumpType.WithFullMemory);
}
Console.ReadKey();
}
}
/**//// <summary>
/// 該類要使用在windows 5.1 以後的版本,如果你的windows很舊,就把Windbg裡面的dll拷貝過來,一般都沒有問題
/// DbgHelp.dll 是windows自帶的 dll文件 。
/// </summary>
public static class MiniDump
...{
/**//*
* 導入DbgHelp.dll
*/
[DllImport("DbgHelp.dll")]
private static extern Boolean MiniDumpWriteDump(
IntPtr hProcess,
Int32 processId,
IntPtr fileHandle,
MiniDumpType mpType,
ref MinimpExceptionInfo excepInfo,
IntPtr userInfo,
IntPtr extInfo );
/**//*
* MINIDUMP_EXCEPTION_INFORMATION 這個宏的信息
*/
struct MinimpExceptionInfo
...{
public Int32 ThreadId;
public IntPtr ExceptionPointers;
public Boolean ClientPointers;
}
/**//*
* 自己包裝的一個函數
*/
public static Boolean TryDump(String dmpPath, MiniDumpType dmpType)
...{
//使用文件流來創健 .dmp文件
using (FileStream stream = new FileStream(dmpPath, FileMode.Create))
...{
//取得進程信息
Process process = Process.GetCurrentProcess();
// MINIDUMP_EXCEPTION_INFORMATION 信息的初始化
MinimpExceptionInfo mei = new MinimpExceptionInfo();
mei.ThreadId = Thread.CurrentThread.ManagedThreadId;
mei.ExceptionPointers = Marshal.GetExceptionPointers();
mei.ClientPointers = true;
//這里調用的Win32 API
Boolean res = MiniDumpWriteDump(
process.Handle,
process.Id,
stream.SafeFileHandle.DangerousGetHandle(),
dmpType,
ref mei,
IntPtr.Zero,
IntPtr.Zero);
//清空 stream
stream.Flush();
stream.Close();
return res;
}
}
public enum MiniDumpType
...{
None = 0x00010000,
Normal = 0x00000000,
WithDataSegs = 0x00000001,
WithFullMemory = 0x00000002,
WithHandleData = 0x00000004,
FilterMemory = 0x00000008,
ScanMemory = 0x00000010,
WithUnloadedMoles = 0x00000020,
= 0x00000040,
FilterMolePaths = 0x00000080,
WithProcessThreadData = 0x00000100,
WithPrivateReadWriteMemory = 0x00000200,
WithoutOptionalData = 0x00000400,
WithFullMemoryInfo = 0x00000800,
WithThreadInfo = 0x00001000,
WithCodeSegs = 0x00002000
}
}
}
❷ 載入到內存的dll可以mp么
作者用的就是這種方法,我說的沒有對應進程就是,LODEPE點開後沒有該DLL的名稱什麼的,就選擇不了,所以不能mp出來。
我試過在文件全部復制完成的時候用winhex保存文件,結果看了沒有導入表和導出表
❸ 怎麼能讓我的程序在崩潰時生成mp文件
調試Dump文件很簡單,雙擊自動打開VC然後F7運行。
但是中間要注意很多事情。
1。Dump文件放在哪裡
Dump文件不用非要放在你編譯出來的位置,你完全可以建立一個新的文件夾來放它。
2。要恢復當時的現場
可能你要問,怎麼可能,這個mp文件可是用戶發給我的,我不可能去用戶家裡調試吧?
這個恢復現場可不是指的非要到那台機器上去,而是要把產生mp文件對應的二進制文件拿到。
但是恢復現場需要所有的二進制文件都要對應,你一定要有導致用戶崩潰的那些Exe和Dll。既然是你發布的程序,Exe文件當然你會有。所以這里只考慮Dll就行了。
Dump文件中記錄了所有dll文件的版本號和時間戳,所以你一定可以同過某種途徑拿到它。如果你能從用戶那裡拿到最好,如果不方便,用戶不可能用的是我們平常不常用的操作系統,所以找個有對應系統的機器一般都會有。但是記住不光是文件名稱要一致,還要核對版本和時間戳,如果不同一樣沒有辦法用。