内存分配崩溃了操作系统。谁应该责怪操作系统

时间:2015-03-25 23:02:40

标签: c++

这个简短的片段

#include <new>

int main(){
  while(true){
     try{
        new char[0x10000000];
     }catch(std::bad_alloc bac){
     }
  }
}
当编译为64位应用程序并在64位Windows系统上运行时,

显然会崩溃整个操作系统。

这是一个有效的c ++程序。怎么会发生这种情况?这也不是msvc编译器的错误吗?

所有其他编译器/系统组合在最坏情况下使系统迟缓。

不要在家里试试。用户Christophe在他的系统上尝试了这个并且它崩溃了。

评论者:我对调试不感兴趣。这是一个有效的c ++程序。我的代码没有错。我很好奇是什么可能导致这种行为。

1 个答案:

答案 0 :(得分:10)

当应用程序使用大量内存时,&#34;蓝屏的一个非常合理的场景&#34;是一个崩溃的司机。这里有两个常见的问题:

  1. 驱动程序无法分配内存且无法检测分配函数返回的NULL时无法分配内存&#34;,导致NULL [或接近NULL]内存访问。

  2. 司机没有正确地锁定&#34;它的内存缓冲区,导致驱动程序需要的页面&#34;在使用页面时被换出 - 这导致&#34; IRQL不减少或等于&#34;蓝屏,这是由操作系统检测到当驱动程序处于调度程序被锁定的模式时发生页面调入请求而引起的。换句话说,驱动程序要求&#34;在完成此操作之前必须运行其他任务&#34;然后发生页面错误,这是从交换页面页面请求,这确实需要不同的任务[交换器进程]运行 - 不能吃蛋糕并吃它,所以操作系统说&#34;不能做&#34; - 此时无法继续,因为驱动程序无法访问内存,无法切换到其他任务,因此除了&#34;报告错误并停止&之后我们无法执行任何操作#34;

  3. 第三种选择是驱动程序检测到它无法分配内存,但决定它无法继续,然后通过调用&#34发出自己的蓝屏;我想要蓝屏现在&#34; Windows中的功能。写得很好的司机不应该这样做,但是像一些司机作家仍然认为这是一个好主意&#34;。

  4. 抱歉,自从我编写Windows驱动程序以来已经过了大约11年,因此可以预期的错误代码已经丢失了。我认为7B用于IRQLNotLessOrEqual,而0xC00000005用于访问未映射的内存(NULL访问等)。

    几台不同机器表现相同的事实可以很容易地解释为许多具有类似硬件的机器(例如相同的打印机,USB [鼠标或键盘?]或片状的CD-ROM驱动器),或具有相同的硬件防病毒软件 - AV软件总是有一个驱动程序组件,以及#34; hook&#34;进入其他过程等。

    鉴于&#34;内存确实耗尽&#34;这些日子并不常见,没有那么熟练/经验丰富/尽职尽责的开发人员可能无法正确测试假冒内存或真正的内存不足情况,因此在这种情况下没有检测到他们的驱动程序失败。

    要提供更多详情,我们至少需要知道蓝屏&#34;代码&#34; (屏幕顶部有四到五个十六进制数字)

    假设调试此类故障有一定的意义,您可以设置窗口以在崩溃时存储转储(或小型转储),或使用第二台PC将WinDBG连接为远程调试器[或某些其他远程调试器]到崩溃的机器 - 当机器蓝屏时,它会在重新启动之前在调试器中停止,这样你就可以看到系统的状态,包括查看导致该代码的代码的调用堆栈崩溃 - 通常会显示实际导致问题的组件。但是,除非您实际上与驱动程序开发人员保持良好联系(至少是相关支持人员的电子邮件地址),否则解决此问题的可能性不大。