使用C#时如何在BSoD发生时转储我的缓冲区

时间:2014-08-13 04:10:51

标签: c# dump crash-dumps minidump bsod

我为C#中的多个应用程序设计了一个日志服务。 由于考虑了性能保存,所有日志应首先存储在缓冲区中,然后在缓冲区已满时写入日志文件。 但是,有一些扩展卡(PCI / PCI-e)导致BSoD,这些不在我的控制之下。当BSoD发生时,缓冲区中的日志将丢失,但我想找到一种方法来保留它们。

我发现有些文章正在讨论如何在软件崩溃时转储数据。但是,minidump one需要自己转储所有内容,我认为这会导致一些性能问题;其他文章(A) (B)仅适用于单个应用程序崩溃。

即使BSoD发生,有没有人建议保存我的日志?

编辑:如果有任何建议减少数据丢失以尽量减少,也欢迎。

1 个答案:

答案 0 :(得分:0)

由于性能原因,您的C#应用​​程序中的缓冲区未写入磁盘,因此剩下的唯一其他位置是内存(RAM)。由于您不知道Windows在崩溃时如何管理您的内存,我们必须考虑两种情况:a)日志实际上在RAM中,b)RAM已经交换到磁盘(页面文件)。要访问BSoD的所有RAM,您必须配置Windows以创建完整内存转储而不是内核小型转储。

在蓝屏时,操作系统几乎停止依赖任何东西,甚至是大多数内核驱动程序。它唯一的尝试是将物理RAM的内容写入磁盘。此外,由于它甚至不能依赖有效的NTFS数据结构,因此它会写入它知道的连续磁盘空间的唯一位置:页面文件。这也是为什么您的页面文件需要至少与物理RAM和一些元数据一样大的原因,否则它将无法保存信息。

此时我们已经可以回答案例b):如果你的日志实际上被交换到了页面文件,它可能会被转储覆盖。

如果缓冲区确实是工作集(RAM)的一部分,那么该部分将包含在内核转储中。从内核转储调试.NET应用程序几乎是不可能的,因为分析.NET堆的SOS命令仅适用于用户模式完全内存转储。如果您可以通过其他方式(例如某个子字符串)识别您的日志条目,您当然可以在内核转储上执行简单的字符串搜索。

总而言之,你想要实现的目标听起来像一个XY问题。如果您想测试您的服务,为什么不删除或更换不相关的有问题的PCI卡或在另一台PC上进行测试? 如果蓝屏日志记录是您的日志记录服务的显式功能,您应该在编写服务之前将其视为风险并进行评估。这是一个项目管理问题,也是StackOverflow的主题。

不幸的是,我必须确认@MobyDisk说的是什么:它几乎是不可能的,至少是不可靠的。