所以有想到的,並符合下列目標之一的解決方案:
- 的二進制文件的大小將左右300K
- 能夠生成mdump文件在一個蕩婦崩潰增加。
- 能力做「暫停」的應用做了轉儲和contiune將是一個獎金
我給這要求一個完整的未知:
- 沒辦法我只能端口應用運行旅館的Windows Mobile。
那麼有什麼解決方案?
從Microsoft Sample for MDbg集成所需的所需部件。exe爲您提供一個「即時」調試器,用於附加,轉儲和分離崩潰過程。
第1步 - 從這裏下載源代碼到MDBG開始:http://www.microsoft.com/downloads/en/details.aspx?FamilyID=38449a42-6b7a-4e28-80ce-c55645ab1310&DisplayLang=en
2步 - 創建一個「撞車」處理程序,生成一個調試的過程,並等待完成。我使用以下幾行代碼重新啓動同一個exe文件,並添加一些額外的參數來調用調試器,並將xml文件輸出到std :: out。
string tempFile = Path.GetTempFileName();
Mutex handle = new Mutex(true, typeof(Program).Namespace + "-self-debugging");
try
{
Process pDebug = Process.Start(typeof(Program).Assembly.Location,
"debug-dump " + Process.GetCurrentProcess().Id + " " + tempFile);
if (pDebug != null)
pDebug.WaitForExit();
}
catch { }
finally
{
handle.ReleaseMutex();
}
Console.WriteLine(File.ReadAllText(tempFile));
第3步 - 編寫調試轉儲例程,這可以在同一個exe或不同的exe中。您需要從樣本中引用(或包含來源)'raw','corapi'和'mdbgeng'模塊。然後添加幾行到您的Main():
public static void Main(string[] args)
{
if (args.Length > 0 && args[0] == "debug-dump")
{ //debug-dump process by id = args[1], output = args[2]
using (XmlTextWriter wtr = new XmlTextWriter(args[2], Encoding.ASCII))
{
wtr.Formatting = Formatting.Indented;
PerformDebugDump(Int32.Parse(args[1]), wtr);
}
return;
}
//... continue normal program execution
}
static void PerformDebugDump(int process, XmlWriter x)
{
x.WriteStartElement("process");
x.WriteAttributeString("id", process.ToString());
x.WriteAttributeString("time", XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.RoundtripKind));
MDbgEngine e = new MDbgEngine();
MDbgProcess me = e.Attach(process);
me.Go().WaitOne();
try
{
x.WriteStartElement("modules");
foreach (MDbgModule mod in me.Modules)
x.WriteElementString("module", mod.CorModule.Name);
x.WriteEndElement();
foreach (MDbgThread thread in me.Threads)
{
x.WriteStartElement("thread");
x.WriteAttributeString("id", thread.Id.ToString());
x.WriteAttributeString("number", thread.Number.ToString());
int ixstack = -1;
foreach (MDbgFrame frame in thread.Frames)
{
x.WriteStartElement("frame");
x.WriteAttributeString("ix", (++ixstack).ToString());
x.WriteAttributeString("loc", frame.ToString(String.Empty));
string valueText = null;
x.WriteStartElement("args");
try
{
foreach (MDbgValue value in frame.Function.GetArguments(frame))
{
x.WriteStartElement(value.Name);
x.WriteAttributeString("type", value.TypeName);
try { x.WriteAttributeString("value", value.GetStringValue(1, false)); }
finally { x.WriteEndElement(); }
}
}
catch { }
x.WriteEndElement();
x.WriteStartElement("locals");
try
{
foreach (MDbgValue value in frame.Function.GetActiveLocalVars(frame))
{
x.WriteStartElement(value.Name);
x.WriteAttributeString("type", value.TypeName);
try { x.WriteAttributeString("value", value.GetStringValue(1, false)); }
finally { x.WriteEndElement(); }
}
}
catch { }
x.WriteEndElement();
x.WriteEndElement();
}
x.WriteEndElement();
}
}
finally
{
me.Detach().WaitOne();
}
x.WriteEndElement();
}
示例輸出
<process id="8276" time="2010-10-18T16:03:59.3781465-05:00">
<modules>
<module>C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll</module>
...etc
</modules>
<thread id="17208" number="0">
<frame ix="0" loc="System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop (source line information unavailable)">
<args>
<this type="System.Windows.Forms.Application.ComponentManager" value="System.Windows.Forms.Application.ComponentManager
 oleComponents=System.Collections.Hashtable
 cookieCounter=1
 activeComponent=System.Windows.Forms.Application.ThreadContext
 trackingComponent=<null>
 currentState=0" />
<dwComponentID type="N/A" value="<N/A>" />
<reason type="System.Int32" value="-1" />
<pvLoopData type="System.Int32" value="0" />
</args>
<locals>
<local_0 type="System.Int32" value="0" />
<local_1 type="System.Boolean" value="True" />
<local_2 type="System.Windows.Forms.UnsafeNativeMethods.IMsoComponent" value="<null>" />
<local_3 type="N/A" value="<N/A>" />
<local_4 type="N/A" value="<N/A>" />
<local_5 type="N/A" value="<N/A>" />
<local_6 type="System.Windows.Forms.Application.ThreadContext" value="System.Windows.Forms.Application.ThreadContext
 contextHash=System.Collections.Hashtable
 tcInternalSyncObject=System.Object
 totalMessageLoopCount=1
 baseLoopReason=-1
 currentThreadContext=System.Windows.Forms.Application.ThreadContext
 threadExceptionHandler=System.Threading.ThreadExceptionEventHandler
 idleHandler=<null>
 enterModalHandler=<null>
 leaveModalHandler=<null>
 applicationContext=System.Windows.Forms.ApplicationContext
 parkingWindow=<null>
 marshalingControl=System.Windows.Forms.Application.MarshalingControl
 culture=<null>
 messageFilters=<null>
 messageFilterSnapshot=<null>
 handle=912
 id=17208
 messageLoopCount=1
 threadState=1
 modalCount=0
 activatingControlRef=<null>
 componentManager=System.Windows.Forms.Application.ComponentManager
 externalComponentManager=False
 fetchingComponentManager=False
 componentID=1
 currentForm=Program.MainForm
 threadWindows=<null>
 tempMsg=System.Windows.Forms.NativeMethods.MSG
 disposeCount=0
 ourModalLoop=False
 messageLoopCallback=<null>
 __identity=<null>" />
<local_7 type="N/A" value="<N/A>" />
<local_8 type="N/A" value="<N/A>" />
<local_9 type="N/A" value="<N/A>" />
<local_10 type="N/A" value="<N/A>" />
<local_11 type="N/A" value="<N/A>" />
<local_12 type="N/A" value="<N/A>" />
<local_13 type="System.Boolean" value="False" />
<local_14 type="System.Windows.Forms.NativeMethods.MSG[]" value="array [1]
 [0] = System.Windows.Forms.NativeMethods.MSG" />
</locals>
</frame>
<frame ix="1" loc="System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner (source line information unavailable)">
<args>
<this type="System.Windows.Forms.Application.ThreadContext" value="System.Windows.Forms.Application.ThreadContext
 contextHash=System.Collections.Hashtable
 tcInternalSyncObject=System.Object
 totalMessageLoopCount=1
 baseLoopReason=-1
 currentThreadContext=System.Windows.Forms.Application.ThreadContext
 threadExceptionHandler=System.Threading.ThreadExceptionEventHandler
 idleHandler=<null>
 enterModalHandler=<null>
 leaveModalHandler=<null>
 applicationContext=System.Windows.Forms.ApplicationContext
 parkingWindow=<null>
 marshalingControl=System.Windows.Forms.Application.MarshalingControl
 culture=<null>
 messageFilters=<null>
 messageFilterSnapshot=<null>
 handle=912
 id=17208
 messageLoopCount=1
 threadState=1
 modalCount=0
 activatingControlRef=<null>
 componentManager=System.Windows.Forms.Application.ComponentManager
 externalComponentManager=False
 fetchingComponentManager=False
 componentID=1
 currentForm=Program.MainForm
 threadWindows=<null>
 tempMsg=System.Windows.Forms.NativeMethods.MSG
 disposeCount=0
 ourModalLoop=False
 messageLoopCallback=<null>
 __identity=<null>" />
<reason type="System.Int32" value="-1" />
<context type="System.Windows.Forms.ApplicationContext" value="System.Windows.Forms.ApplicationContext
 mainForm=Program.MainForm
 userData=<null>
 ThreadExit=System.EventHandler" />
</args>
<locals>
<local_0 type="System.Windows.Forms.Form" value="<null>" />
<local_1 type="System.Boolean" value="False" />
<local_2 type="N/A" value="<N/A>" />
<local_3 type="N/A" value="<N/A>" />
<local_4 type="N/A" value="<N/A>" />
</locals>
</frame>
... etc
</thread>
</process>
既然你有一個調試器的全部功能並沒有什麼從編寫儘可能多或儘可能少阻止你只要你喜歡,但上面的例子應該讓你開始。
UPDATE
此工作原理與NET 2.0和/或運行時3.5沒有任何進一步的依賴關係。
這可以調試運行在.Net 4.0進程中的.Net 2.0/3.5代碼;但是,它不適用於4.0(尚未)。
4.0 CLR看到這個帖子: http://blogs.msdn.com/b/rmbyers/archive/2008/10/27/icordebug-re-architecture-in-clr-4-0.aspx
關於這個問題的任何最終很好的解決方案?在.NET中有很好的示例應用程序源代碼? – Kiquenet 2011-09-05 11:05:48