在我的应用程序中生成/创建mdump文件 [英] Generate / create mdump files for in my app

查看:159
本文介绍了在我的应用程序中生成/创建mdump文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想寻找一种在我的应用程序中生成minidump文件的方法,这些文件类似于 ProcDump 不过是以代码的形式提供,而不需要提取一个3dparty工具来实现。



不希望使用 ProcDump 是:

1)二进制大小将大大增加(这是一个问题,因为我的应用程序是免费的,并且bandwith不是免费的)。

2)感觉很脏。

3)没有办法我可以移植该应用程序来运行客房窗口



我的要求是:

1)能够在致命的崩溃中生成mdump文件。

2)有能力做暂停应用程序做一个转储,并且将是一个奖金



如果这不是一个选项,有没有办法在当前上下文中动态地获取本地变量的值?



旁注:
做了fin 这篇文章,但它非常老,所以我犹豫,以我的工作为基础。

似乎有一个问题与IE 9或网站,所以我有问题的标签。

解决方案

所以有一个解决方案可以想到并符合以下目标:




  • 二进制文件的大小会增加约300k

  • 能够在致命的崩溃中生成mdump文件。

  • 能力做暂停的应用程序做一个转储,并且将是一个奖金



我会给这个要求一个完整的未知数:




  • 没有办法我可以移植该应用来运行Windows Mobile。



那么有什么解决方案?



您需要从Microsoft Sample 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);
尝试
{
进程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)
{//通过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;
}
// ...继续正常的程序执行$ ​​b $ b}

static void PerformDebugDump(int process,XmlWriter x)
{
x.WriteStartElement( 进程);
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(thread.Frames中的MDbgFrame框架)
{
x.WriteStartElement(frame);
x.WriteAttributeString(ix,(++ ixstack).ToString());
x.WriteAttributeString(loc,frame.ToString(String.Empty));
string valueText = null;

x.WriteStartElement(args);
尝试
{
foreach(frame.Function.GetArguments(frame)中的MDbgValue值)
{
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(localals);
尝试
{
foreach(frame.Function.GetActiveLocalVars(frame)中的MDbgValue值)
{
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 =8276time =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 =17208number =0>
< frame ix =0loc =System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(源行信息不可用)>
< args>
< this type =System.Windows.Forms.Application.ComponentManagervalue =System.Windows.Forms.Application.ComponentManager& #xA; oleComponents = System.Collections.Hashtable& #xA; cookieCounter = 1& ; #xA; activeComponent = System.Windows.Forms.Application.ThreadContext& #xA; trackingComponent =& lt; null& gt& #xA; currentState = 0/>
< dwComponentID type =N / Avalue =& lt; N / A& gt />
< reason type =System.Int32value = - 1/>
< pvLoopData type =System.Int32value =0/>
< / args>
< localals>
< local_0 type =System.Int32value =0/>
< local_1 type =System.Booleanvalue =True/>
< local_2 type =System.Windows.Forms.UnsafeNativeMethods.IMsoComponentvalue =& lt; null& gt />
< local_3 type =N / Avalue =& lt; N / A& gt />
< local_4 type =N / Avalue =& lt; N / A& gt />
< local_5 type =N / Avalue =& lt; N / A& gt />
< local_6 type =System.Windows.Forms.Application.ThreadContextvalue =System.Windows.Forms.Application.ThreadContext& #xA; contextHash = System.Collections.Hashtable& #xA; tcInternalSyncObject = System .Object& #xA; totalMessageLoopCount = 1& #xA; baseLoopReason = -1& #xA; currentThreadContext = System.Windows.Forms.Application.ThreadContext& #xA; threadExceptionHandler = System.Threading.ThreadExceptionEventHandler& #xA; idleHandler =& ; lt; null& gt& #xA; enterModalHandler =& lt&null& gt& #xA; leaveModalHandler =& lt&null& gt& #xA; applicationContext = System.Windows.Forms。 ApplicationContext& #xA; parkingWindow =& lt&null& gt;& #xA; marshalingControl = System.Windows.Forms.Application.MarshalingControl& #xA; culture =& lt&null& gt& messageFilters =& lt; null& gt;& #xA; messageFilterSnapshot =& lt; null& gt& #xA; handle = 912& #xA; id = 17208& #xA; messageLoopCount = 1& XA;的ThreadState = 1&安培; #xA; modalCount = 0&安培; #xA; activatingControlRef =安培; LT;空&安培; GT;&安培; #xA;的ComponentManager = System.Windows.Forms.Application.ComponentManager&安培; #xA; externalComponentManager =假&安培; #xA; fetchingComponentManager =假&安培; #xA; COMPONENTID = 1&安培; #xA; currentForm = Program.MainForm&安培; #xA; threadWindows =安培; LT;空&安培; GT;&安培; #xA; tempMsg = System.Windows.Forms.NativeMethods.MSG&安培; #xA; disposeCount = 0&安培; #xA; ourModalLoop =假&安培; #xA; messageLoopCallback =安培; LT;空&安培; GT;&安培; #xA; __identity =& lt; null&/>
< local_7 type =N / Avalue =& lt; N / A& gt/>
< ; local_8 type =N / Avalue =& lt; N / A& gt/>
< local_9 type =N / Avalue =& ;>
< local_10 type =N / Avalue =& lt; N / A& gt/>
< local_11 type =N / value =& lt; N / A>/>
< local_12 type =N / Avalue =& lt; N / A&
< local_13 type =System.Booleanvalue =False/>
< local_14 type =System.Windows.Forms.NativeMethods.MSG []value =array [1 ]&安培; #xA; [0] = System.Windows.Forms.NativeMethods.MSG/>
< / locals>
< / frame>
< frame ix =1loc = System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(源行信息不可用)>
< args>
< this type =System.Windows.Forms.Application.ThreadContextvalue = System.Windows.Forms.Application.ThreadContext&安培; #xA; contextHash = System.Collections.Hashtable&安培; #xA; tcInternalSyncObject = System.Object的&安培; #xA; totalMessageLoopCount = 1&安培; #xA; baseLoopReason = -1&安培; #xA; currentThreadContext = System.Windows.Forms.Application.ThreadContext&安培; #xA; threadExceptionHandler = System.Threading.ThreadExceptionEventHandler&安培; #xA; idleHandler =安培; LT;空&安培; GT;&安培; #xA; enterModalHandler =安培; LT;空&安培; GT;&安培; #xA; leaveModalHandler =安培; LT;空&安培; GT;&安培; #xA;的applicationContext = System.Windows.Forms.ApplicationContext&安培; #xA; parkingWindow =安培; LT;空&安培; GT;&安培; #xA; marshalingControl = System.Windows.Forms.Application.MarshalingControl&安培; #xA;培养=安培; LT;空&安培; GT;&安培; #xA; messageFilters =安培; LT;空&安培; GT;&安培; #xA; messageFilterSnapshot =安培; LT;空&安培; GT;&安培; #xA;处理= 912&安培; #xA; ID = 17208&安培; #xA; messageLoopCount = 1&安培; #xA;的ThreadState = 1&安培; #xA; modalCount = 0&安培; #xA; activatingControlRef =安培; LT;空&安培; GT;&安培; #xA;的ComponentManager = System.Windows.Forms.Application.ComponentManager&安培; #xA; externalComponentManager =假&安培; #xA; fetchingComponentManager =假&安培; #xA; COMPONENTID = 1&安培; #xA; currentForm = Program.MainForm&安培; #xA; threadWindows =安培; LT;空&安培; GT;&安培; #xA; tempMsg = System.Windows.Forms.NativeMethods.MSG&安培; #xA; disposeCount = 0&安培; #xA; ourModalLoop =假&安培; #xA; messageLoopCallback =安培; LT;空&安培; GT;&安培; #xA; __identity =& lt&null& gt;/>
< reason type =System.Int32value = - 1/>
< context type =System.Windows .Forms.ApplicationContextvalue =System.Windows.Forms.ApplicationContext& #xA;的MainForm = Program.MainForm&安培; #xA;的UserData =安培; LT;空&安培; GT;&安培; #xA; ThreadExit = System.EventHandler/>
< / args>
< localals>
< local_0 type =System.Windows.Forms.Formvalue =& lt ; null& gt;/>
< local_1 type =System.Booleanvalue =False/>
< local_2 type =N / Avalue =& < N / A>/>
< local_3 type =N / Avalue =& lt; N / A& gt/>
< local_4 type =N / Avalue =& lt / N / A& gt/>
< / localals>
< / frame>
...
< / thread>
< / process>

调试器的全部功能没有什么可以阻止您的写作尽可能多或少一点,但上面的例子应该让你开始。



更新



这可以与.Net 2.0和/或3.5运行时一起使用,无需任何进一步的依赖。



这可以调试.Net 2.0 / 3.5代码在.Net 4.0进程中运行;但是,它没有可以使用4.0(还)。



对于4.0 CLR看到这篇文章:
http://blogs.msdn.com/b/rmbyers/archive/2008/10/27/icordebug-re -archit-in-clr-4-0.aspx


Im looking for a way to generate minidump files in my applications simular to what ProcDump does but prefarably with code and not having to extract a 3dparty tool to do it.

The main reasons for not wanting to use ProcDump is:
1) Size of the binary would increase greatly ( This is a problem because my apps are freeware, and bandwith is not free).
2) Feels dirty.
3) No way i can port that app to run inn windows mobile.

My requirements are:
1) Ability to generate mdump files in a fatale crash.
2) Abilityt to do "pause" the app do a dump, and contiune would be a bonus
.
If this is not realy a option, is there a way to get the values of local varibales in the current context dynamicly?

Side note: I did find this article, but its very old so i so im hesitant to base my work of it.
There seems to either be a issue with IE 9 or with the site, so i had problems with tags.

解决方案

So there is one solution that comes to mind and meets the following goals:

  • Size of the binary would increase by around 300k
  • Ability to generate mdump files in a fatale crash.
  • Ability to do "pause" the app do a dump, and contiune would be a bonus

I'll give this requirement a complete unknown:

  • No way i can port that app to run inn windows mobile.

So what's the solution?

Integrate the required parts you need from the Microsoft Sample for MDbg.exe to provide you with a 'just-in-time' debugger that attaches, dumps, and detaches from the crashing process.

Step 1 - Start by downloading the source code to the mdbg from here: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=38449a42-6b7a-4e28-80ce-c55645ab1310&DisplayLang=en

Step 2 - Create a 'crash' handler that spawns a debugger process and waits for completion. I used the following few lines of code to re-launch the same exe with a few extra arguments to invoke the debugger and output an xml file to 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));

Step 3 - Write the debug dump routine, this can be in the same exe or in a different exe. You will need to reference (or include the source from) the 'raw', 'corapi', and 'mdbgeng' modules from the sample. Then add a few lines to your 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();
}

Example Output

<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&#xA;    oleComponents=System.Collections.Hashtable&#xA; cookieCounter=1&#xA;    activeComponent=System.Windows.Forms.Application.ThreadContext&#xA; trackingComponent=&lt;null&gt;&#xA; currentState=0" />
        <dwComponentID type="N/A" value="&lt;N/A&gt;" />
        <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="&lt;null&gt;" />
        <local_3 type="N/A" value="&lt;N/A&gt;" />
        <local_4 type="N/A" value="&lt;N/A&gt;" />
        <local_5 type="N/A" value="&lt;N/A&gt;" />
        <local_6 type="System.Windows.Forms.Application.ThreadContext" value="System.Windows.Forms.Application.ThreadContext&#xA;   contextHash=System.Collections.Hashtable&#xA;   tcInternalSyncObject=System.Object&#xA; totalMessageLoopCount=1&#xA;    baseLoopReason=-1&#xA;  currentThreadContext=System.Windows.Forms.Application.ThreadContext&#xA;    threadExceptionHandler=System.Threading.ThreadExceptionEventHandler&#xA;    idleHandler=&lt;null&gt;&#xA;   enterModalHandler=&lt;null&gt;&#xA; leaveModalHandler=&lt;null&gt;&#xA; applicationContext=System.Windows.Forms.ApplicationContext&#xA; parkingWindow=&lt;null&gt;&#xA; marshalingControl=System.Windows.Forms.Application.MarshalingControl&#xA;   culture=&lt;null&gt;&#xA;   messageFilters=&lt;null&gt;&#xA;    messageFilterSnapshot=&lt;null&gt;&#xA; handle=912&#xA; id=17208&#xA;   messageLoopCount=1&#xA; threadState=1&#xA;  modalCount=0&#xA;   activatingControlRef=&lt;null&gt;&#xA;  componentManager=System.Windows.Forms.Application.ComponentManager&#xA; externalComponentManager=False&#xA; fetchingComponentManager=False&#xA; componentID=1&#xA;  currentForm=Program.MainForm&#xA;   threadWindows=&lt;null&gt;&#xA; tempMsg=System.Windows.Forms.NativeMethods.MSG&#xA; disposeCount=0&#xA; ourModalLoop=False&#xA; messageLoopCallback=&lt;null&gt;&#xA;   __identity=&lt;null&gt;" />
        <local_7 type="N/A" value="&lt;N/A&gt;" />
        <local_8 type="N/A" value="&lt;N/A&gt;" />
        <local_9 type="N/A" value="&lt;N/A&gt;" />
        <local_10 type="N/A" value="&lt;N/A&gt;" />
        <local_11 type="N/A" value="&lt;N/A&gt;" />
        <local_12 type="N/A" value="&lt;N/A&gt;" />
        <local_13 type="System.Boolean" value="False" />
        <local_14 type="System.Windows.Forms.NativeMethods.MSG[]" value="array [1]&#xA; [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&#xA;  contextHash=System.Collections.Hashtable&#xA;   tcInternalSyncObject=System.Object&#xA; totalMessageLoopCount=1&#xA;    baseLoopReason=-1&#xA;  currentThreadContext=System.Windows.Forms.Application.ThreadContext&#xA;    threadExceptionHandler=System.Threading.ThreadExceptionEventHandler&#xA;    idleHandler=&lt;null&gt;&#xA;   enterModalHandler=&lt;null&gt;&#xA; leaveModalHandler=&lt;null&gt;&#xA; applicationContext=System.Windows.Forms.ApplicationContext&#xA; parkingWindow=&lt;null&gt;&#xA; marshalingControl=System.Windows.Forms.Application.MarshalingControl&#xA;   culture=&lt;null&gt;&#xA;   messageFilters=&lt;null&gt;&#xA;    messageFilterSnapshot=&lt;null&gt;&#xA; handle=912&#xA; id=17208&#xA;   messageLoopCount=1&#xA; threadState=1&#xA;  modalCount=0&#xA;   activatingControlRef=&lt;null&gt;&#xA;  componentManager=System.Windows.Forms.Application.ComponentManager&#xA; externalComponentManager=False&#xA; fetchingComponentManager=False&#xA; componentID=1&#xA;  currentForm=Program.MainForm&#xA;   threadWindows=&lt;null&gt;&#xA; tempMsg=System.Windows.Forms.NativeMethods.MSG&#xA; disposeCount=0&#xA; ourModalLoop=False&#xA; messageLoopCallback=&lt;null&gt;&#xA;   __identity=&lt;null&gt;" />
        <reason type="System.Int32" value="-1" />
        <context type="System.Windows.Forms.ApplicationContext" value="System.Windows.Forms.ApplicationContext&#xA; mainForm=Program.MainForm&#xA;  userData=&lt;null&gt;&#xA;  ThreadExit=System.EventHandler" />
    </args>
    <locals>
        <local_0 type="System.Windows.Forms.Form" value="&lt;null&gt;" />
        <local_1 type="System.Boolean" value="False" />
        <local_2 type="N/A" value="&lt;N/A&gt;" />
        <local_3 type="N/A" value="&lt;N/A&gt;" />
        <local_4 type="N/A" value="&lt;N/A&gt;" />
    </locals>
</frame>
... etc
</thread>
</process>

Since you have the full power of a debugger there is nothing stopping you from writing as much or as little as you like, but the above example should get you started.

UPDATE

This works with the .Net 2.0 and/or 3.5 runtime without any further dependencies.

This can debug .Net 2.0/3.5 code running in a .Net 4.0 process; however, it does not work with 4.0 (yet).

For 4.0 CLR see this post: http://blogs.msdn.com/b/rmbyers/archive/2008/10/27/icordebug-re-architecture-in-clr-4-0.aspx

这篇关于在我的应用程序中生成/创建mdump文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆