自动生成 .NET 故障转储
我知道如何使用 ADPlus 或 DebugDiag 生成故障转储文件,但我想知道是否有一种方法可以在客户的计算机上执行此操作而无需安装这些工具...具体来说,我希望能够配置我的应用程序(例如,使用注册表值)在发生严重故障时生成故障转储。 更具体地说,我需要能够从 C# 应用程序执行此操作,但我不介意在必要时进行 P/Invoke'ing。 谢谢!
I know how to generate Crash Dump files with ADPlus or DebugDiag, but I'm wondering if there is a way to do this on a customer's computer without installing these tools... specifically, I would like to be able to configure my application (using a registry value, for example) to generate a crash dump in the case of a critical failure. More specifically, I need to be able to do this from a C# application, but I don't mind P/Invoke'ing if necessary. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
请注意,从“失败”进程(甚至线程)本身内部创建小型转储并不简单,或者可能不准确(也MiniDumpWriteDump 函数的备注)。
此外,如果您的进程如此愤怒以至于您可能需要编写故障转储,则整个情况通常会非常糟糕,甚至尝试创建故障转储也可能导致另一次崩溃(例如挂起的情况 - 但这些甚至可能是更难从当前进程中“捕获”)。
如果您无法在客户端系统上安装单独的应用程序,您可以做的“最好”的事情是启动一个外部进程(在危急情况下也可能失败!)并让它从当前进程创建故障转储(请参阅< href="https://web.archive.org/web/20090825040700/http://msdn.microsoft.com/en-us/magazine/cc188701.aspx" rel="noreferrer">来自 John Robbins 的 Superassert.NET< /a>)。 您甚至可以走得更远,将外部二进制文件放入您的应用程序资源中,在启动时将其从那里提取(以最大限度地减少关键情况下的故障)到磁盘(如果您敢的话)。
Note that creating a minidump from inside the "failing" process (or even thread) itself is not trivial or might not be accurate (also MiniDumpWriteDump function's Remarks).
Besides, if your process is in such anger that you might need to write a crash dump, the whole situation is typically so hosed, that even attempting to create a crash dump could cause another crash (situations like hangs aside - but those might be even harder to "catch" from within the current process).
The "best" thing you can do, if you cannot install separate applications on your client's systems, is to start an external process (which could also fail in critical situations!) and let that create a crashdump from your current process (see Superassert.NET from John Robbins). You could even go so far, as to put the external binary into your app resources, extract it from there on startup (as to minimize failure in critical situtations) to disk (if you dare).
您可以配置 Windows 错误报告 (WER),以使用以下注册表脚本在特定目录中创建故障转储:
转储将进入 C:\Dumps,其名称反映崩溃进程的名称。 DumpType=2 给出完整的内存转储。 DumpType=1 给出一个小型转储。 在 64 位机器上,您不需要将它们放在 Wow32 节点下。 WER 仅使用上面指定的非 WOW 注册表项。
根据崩溃的类型,此方法可能不起作用。 我还没有弄清楚它无法捕获的原因或崩溃类型。 任何人?
You can configure Windows Error Reporting (WER) to create a crash dump in a specific directory using the following registry script:
The dump will go into C:\Dumps with a name that reflects the name of the process that crashed. DumpType=2 gives a full memory dump. DumpType=1 gives a mini dump. On 64 bit machines, you do not need to put these under the Wow32 nodes. WER only uses the non-WOW registry key specified above.
Depending on the type of crash, this method may not work. I have yet to figure out why or which crash types it doesn't catch. Anyone?
我认为如果你的应用程序被软管攻击,那么你不妨尝试创建一个迷你转储文件,最糟糕的情况是什么,你的应用程序会崩溃吗? 无论如何,它正在这样做,所以你不妨尝试一下。
MSDN 论坛中提到的代码由 VoiDed 看起来相当可靠。 我需要一个 VB.Net 版本,所以这里为任何可能需要它的人提供了一个 VB 版本:
只要确保您可靠地处理对它的调用,您就应该相对安全。
I think if your app is hosed then you might as well take a shot at creating a mini dump file, what's the worst that's going to happen, your app will crash? It's doing that anyway, so you might as well try.
The code in the MSDN forum mentioned by VoiDed seems pretty solid. I needed a VB.Net version so here's a VB version for anyone that might need it:
Just make sure you solidly eception handle the calls to it and you should be relatively safe.
您可以在
AppDomain.UnhandledException
事件中 P/Invokedbghelp.dll
的MiniDumpWriteDump
函数。在这种情况下,您可以转储 .NET 异常数据的日志并将小型转储写入文件。
MSDN 上还有一个 线程论坛,其中描述了 P/Invoke 签名和正确用法。
You could P/Invoke
dbghelp.dll
'sMiniDumpWriteDump
function in theAppDomain.UnhandledException
event.In this event you could dump a log of the .NET exception data and write a minidump to file.
There's also a thread on the MSDN forums which describes the P/Invoke signature and proper usage.
您可以调用 Environment.FailFast,这将:
除其他事项外。
You can call Environment.FailFast, which will:
Among other things.
根据您需要的信息类型,您可以为
AppDomain.UnhandledException
事件添加处理程序? (我知道这并不完全是您正在寻找的,但它肯定可以在客户端计算机上使用。)Depending on what kind of information you need, you could add a handler for the
AppDomain.UnhandledException
event? (I know it's not exactly what you're looking for, but it's definitely available on the client machines.)你使用像 log4net 这样的日志框架吗? 通常,您会关闭某个版本的调试级别消息。 但是,您可以考虑编写一个特殊的附加程序,仅在某些情况下(例如崩溃)记录到文件。 该附加程序首先写入仅内存的环形缓冲区,该缓冲区可以写入文件,稍后 - 例如由 280Z28 建议的异常处理程序触发。
Do you use a logging framework like log4net? Normally you switch off debug-level messages for a release. However you can think about writing a special appender which logs to a file only in certain cases (like a crash). This appender writes at first into a memory-only ringbuffer which can be written to a file, later - triggered for instance by a exceptionhandler like suggested by 280Z28.