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

C# 如何在BSoD发生时使用C转储缓冲区,c#,dump,crash-dumps,minidump,bsod,C#,Dump,Crash Dumps,Minidump,Bsod,我为C语言中的多个应用程序设计了一个日志服务。 出于节省性能的考虑,所有日志都应该先存储在缓冲区中,然后在缓冲区已满时写入日志文件。 但是,有一些扩展卡PCI/PCI-e导致BSoD,这不在我的控制范围内。当BSoD发生时,缓冲区中的日志将丢失,但我想找到一种保存它们的方法 我发现一些文章正在讨论如何在软件崩溃时转储数据。但是,需要自己转储所有内容,我认为这会导致一些性能问题;其他文章仅适用于单个应用程序崩溃 是否有人建议即使发生BSoD也保存我的日志 编辑:如果有任何减少数据丢失的建议,也欢迎

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

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

是否有人建议即使发生BSoD也保存我的日志


编辑:如果有任何减少数据丢失的建议,也欢迎使用。

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

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

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

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

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


不幸的是,我必须证实@MobyDisk所说的:这几乎是不可能的,至少是不可靠的。

这是不可能的。BSOD之后,操作系统甚至没有运行。CPU停止了。我知道这几乎是不可能的,但是当BSoD发生时,内核会从主内存转储一些数据,对吗?我们是否有机会让内核以任何格式转储我的数据,我可以稍后恢复它们?即使是完全内存转储,如果我仍然可以恢复它们,我也可以接受。否。默认情况下,内核执行一个小型转储,这只是调试崩溃的驱动程序所需的信息。可能会转储所有系统内存,但这对您也没用。谢谢您的解释,请注意我的问题。我认为这很容易,但似乎不容易。我将考虑如何以其他方式进行我的项目。