Delphi中的Guard页面异常?

Ale*_*lex 6 delphi exception

有一篇由Raymond Chen 撰写的文章,他通过吃护页异常来讲述IsBadXxxPtr功能有多糟糕.

我不太明白它是如何应用于Delphi的.谁和如何正常(即不调用IsBadXxxPtr)处理此异常?我知道Delphi插入一个代码(例如)访问大型静态数组的内存 - 正是出于这个原因:扩展堆栈.

但是如果提出了防护页面异常:谁将在Delphi应用程序中处理它?我不能用不合适的方式使用try/except来意外地弄乱它吗?Delphi的调试器会通知我这些异常吗?

Bar*_*lly 14

Windows结构化异常处理(SEH)具有两阶段结构.当发生异常时,Windows首先通过遵循已注册的异常处理程序链(其头部存储在x86上的fs:[0]中,即FS段指向的段中的第一个dword)来查找异常的处理程序.寄存器 - 所有那些丑陋的16位段偏移逻辑都没有在32位中消失,它只是变得不那么相关了.

通过调用具有特定标志的函数来完成搜索,该指针存储在堆栈上的每个异常帧中.fs:[0]指向最顶层的帧.每个帧指向前一帧.最终,列表中的最后一帧是由OS提供的(如果未处理的异常到达,则此处理程序将弹出应用程序崩溃对话框).

这些函数通常会检查异常的类型,并返回一个代码来指示要执行的操作.其中一个可以返回的代码基本上是"忽略此异常并继续".如果Windows看到这一点,它会将指令指针重置为异常点并继续执行.另一个代码表明此异常帧应该处理给定的异常.第三个代码是"我不会抓住这个异常,继续搜索".Windows继续调用这些异常过滤器函数,直到找到以某种方式处理异常的函数.

如果Windows找到一个通过捕获它来处理异常,那么它将继续将堆栈展开回到该处理程序,该处理程序包括再次调用所有函数,只传递一个不同的标志.在这一点上,函数执行finally逻辑,直到执行except逻辑的处理程序.

但是,由于堆栈页面保护异常,过程是不同的.语言的异常处理程序都不会选择处理此异常,否则堆栈增长机制会中断.相反,过滤器搜索一直过滤到OS提供的基本异常处理程序,它通过提交适当的内存来增加堆栈分配,然后返回相应的返回代码以指示操作系统应该从中断的地方继续,而不是展开堆栈.

工具和调试基础结构旨在使这些特定异常正常播放,因此您无需担心处理它们.

十多年前,您可以在Matt Pietrek的MSJ精彩文章中阅读更多关于SEH 的内容.

  • Rob-如果您自己设置异常框架,则可以指定任何您喜欢的东西,这需要一点汇编程序。.NET异常支持一种称为异常过滤器的内容,它映射到SEH的搜索阶段,但据我所知,它们仅在ILASM语法和.NET的Visual Basic中公开。在WRT Linux中,我没有深入研究dcc使用的机制,但是它是PC映射的机制,为简单起见,我怀疑它不是两阶段的。 (2认同)
  • Alexander,堆栈扩展方法是为仅触发保护页面的线程而设计的,即它具有线程亲和力。IsBadReadPtr可以触发*不同*线程的保护页,因此,让异常泄漏到当前线程的异常处理程序链末尾的过滤器是行不通的;该处理程序将尝试扩展错误的线程堆栈。 (2认同)