0

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

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

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

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

4

1 回答 1

0

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

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

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

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

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

不幸的是,我必须确认@MobyDisk 所说的:(几乎)不可能,至少不可靠。

于 2014-09-08T10:28:38.717 回答