【问题标题】:C# simulating a system crashC# 模拟系统崩溃
【发布时间】:2014-01-13 23:28:59
【问题描述】:

如何在 c#/c++ 中模拟系统崩溃或断电?

我正在编写一个类似于数据库的库,需要实现典型sql数据库的事务原理的某些方面。该库有一种方法,它必须确保所有数据都写入硬盘驱动器(使用 win api 函数 FlushFileBuffers)。在此行之后,图书馆将认为交易已完成。经过一些研究,我发现 FlushFileBuffers 不可靠,例如硬盘驱动器可能只是返回所有缓冲区都已刷新,即使情况并非如此。我需要一种在调用 FlushFileBuffers 后立即杀死我的系统的方法,以检查数据是否在代码行之后实际写出。这可能如下所示:

writeToFile(fileHandle);
FlushFileBuffers(fileHandle);
killSystem(); //this is missing

在系统下次重新启动时,我可以检查数据是否真的被写出。如果没有办法杀死系统,我可以用其他方案来测试吗?欢迎所有想法!

【问题讨论】:

  • 在虚拟机中运行它并崩溃(或“杀死 -9”)虚拟机主机进程。
  • (我不知道如何同步这个过程。)
  • 您可以做的一件事是创建一个程序来枚举进程并杀死除自身之外的每个进程。它应该在一个循环中完成,并且应该尝试捕获内部杀戮。以管理员权限运行这样的程序,您的操作系统将以光速关闭:D
  • 旁注:如果您只是为该代码编写适当的单元测试...(例如模拟“文件系统”,而不是检查您的系统在部分写入时的行为),那就容易多了。
  • 我正在使用单元测试,所有方法都使用模拟文件系统进行测试。问题在于 win api、真正的文件系统、驱动程序和硬件,所以它不是我的程序的一部分,但遗憾的是我的责任的一部分。我也需要测试这些以确保我的系统正常工作。

标签: c# c++ database testing


【解决方案1】:

调用 TerminateProcess 不应允许任何进程进行清理。

static void Main(string[] args)
{
    // Get the process.
    Process target = Process.GetProcesses()
        .First(p => 
               p.ProcessName.IndexOf("VMWare",
                                     StringComparison.OrdinalIgnoreCase) >= 0);

    // Headshot!
    TerminateProcess(target.Handle, 0);
}

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool TerminateProcess(IntPtr hProcess, int uExitCode);

按照user2864740的建议使用虚拟机并用上述方法杀死它可能会产生预期的效果。

阅读更多关于TerminateProcess

【讨论】:

  • 如果我直接在我的应用程序上使用它,它仍然会刷新所有缓冲区,例如即使没有 FlushFileBuffers,所有文件也会被正确写出。 (但如果我拔掉我的电脑,它们会被损坏)。但是你的意思是我应该在虚拟机中运行我的应用程序然后杀死虚拟机?这可能会奏效。我需要一些时间来测试...... :)
【解决方案2】:

并行的解决方案是首先不模拟它。他们有一个工具可以将数字写入硬盘驱动器并同时将其发送到服务器。您主动拔下电脑的插头并重新启动它。该工具将在重新启动后检查硬盘上的数字是否小于数字上的数字。如果是这种情况,则无法刷新到硬盘。

不漂亮,但应该可以工作......

【讨论】:

    猜你喜欢
    • 2018-04-20
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多