zoukankan      html  css  js  c++  java
  • 有趣的异常

    有趣的异常

    缘起

    最近,在项目中遇到一个有趣的异常。在没附加调试器的情况下会直接崩溃。附加调试器后,会中断到调试器中,但是按 F5 继续运行后,程序还能继续执行。 interesting !你能猜出这是个什么异常吗?

    初遇错误

    在测试程序功能的时候,意外的崩溃了。以为是偶发事件,于是重新执行,依然会崩溃。一般遇到这种问题可以先考虑在调试器中运行,看看是否能重现。

    上调试器

    附加 vs 到目标进程,再次执行相应的功能,果然中断到了调试器中。简单查看调用栈及出错的代码,并没有显著异常(其实,有相当明显的提示,只是当时没有注意)。偶然点了 F5,没想到居然可以继续运行,有点意思。由于项目比较紧,就一直将就着挂着调试器运行测试代码。前些日子有点时间,再次看了下这个问题。

    再次检查

    再次在调试器中运行程序,异常果然再次发生了。这次心态比较平和,不急不躁,仔细一看异常提示信息,差点被自己气吐血。具体是什么异常呢?请看下图:

    stack-overflow-exception
    stack-overflow-exception

    这不是栈溢出吗?这么明显的提示,当时怎么就给华丽丽的错过了呢?一定要仔细看提示啊!知道是栈溢出,后面的问题就不用查了。这里简单介绍一下 32 位程序的栈增长过程。

    栈增长过程

    默认情况下,每个线程有 1 MB 的栈空间,这 1 MB 的空间对应的虚拟内存(按页面组织的,页面大小一般是 4KB)并不是一开始就有对应的物理页面的,而是按需分配的。

    开始时,最上方的两个虚拟页面(栈是向下增长的)有对应的物理页面,这两个页面有 PAGE_READWRITE 保护属性,其中第二个页面还额外包含 PAGE_GUARD 保护属性,是防护页面。当线程试图访问防护页面中的内存时,系统会得到通知 ,系统会去除第二个页面的 PAGE_GUARD 保护属性标志,为第三个页面调拨物理页面,然后为第三个页面设置 PAGE_GUARD 保护属性标志,以此类推。

    1022 个页面是最后一个带 PAGE_GUARD 的页面,也就是最后一个保护页面。当线程访问第 1022 个页面的时候,系统会得到通知,系统会去除第 1022 个页面的 PAGE_GUARD 保护属性标志,为第 1023 个页面调拨物理页面,但是系统并不会为第 1023 个页面设置 PAGE_GUARD 保护属性标志,相反的,会抛出 EXCEPTION_STACK_OVERFLOW 异常,该异常对应的值是 0xC00000FD

    系统永远不会为第 1024 个页面调拨物理页面。这样是为了保护进程的其它数据,使它们不会因为意外的内存写越界而遭到破坏。

    现象解释

    相信弄明白栈的增长过程,基本就明白了为什么在调试器中可以继续运行的原因了。当调试器收到栈溢出异常时,系统已经把保护页面的PAGE_GUARD 保护属性标志去除了,并且为下一个页面调拨了物理页面。在调试器中按 F5 继续运行,再次访问相同的地址已经不会产生异常。所以就可以继续运行了。但并不是所有情况下都可以这么幸运,当使用内存过多,访问到第 1024 个页面时,还是会报页面访问异常(对应的异常码是 0xC0000005)。

    access-violation-exception-after-stack-overflow
    access-violation-exception-after-stack-overflow

    总结

    • 一定要仔细看错误提示!

    • 遇到诡异的问题可以试试在调试器中运行程序。

    参考资料

    《Windows 核心编程(第 5 版)》

  • 相关阅读:
    设计模式实战应用之五:工厂方法模式
    Codeforces445A_DZY Loves Chessboard(预处理)
    void f(int(&p)[3]){} 和void f(int(*p)[3]){}的差别
    《linux 内核全然剖析》 mktime.c
    Java中对象、对象引用、堆、栈、值传递以及引用传递的详解
    android 仿ios开关控件
    ViewDragHelper实战 自己打造Drawerlayout
    [javase学习笔记]-8.5 statickeyword的使用场景
    玩转图片Base64编码
    Android stuido viewpagerindicator的使用
  • 原文地址:https://www.cnblogs.com/bianchengnan/p/13917818.html
Copyright © 2011-2022 走看看