且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么我的代码在 Windows 7 上不会出现段错误?

更新时间:2022-01-26 00:24:24

Windows 有 非可移植语言扩展(称为SEH"),它允许您将页面错误和分段违规作为异常捕获.

Windows has non-portable language extensions (known as "SEH") which allow you to catch page faults and segmentation violations as exceptions.

OS 库的某些部分(特别是在处理一些窗口消息的 OS 代码中,如果我没记错的话)有一个 __try 块,即使在面对如此灾难性的错误.您很可能在这些 __try 块之一内被调用.悲伤但真实.

There are parts of the OS libraries (particularly inside the OS code that processes some window messages, if I remember correctly) which have a __try block and will make your code continue to run even in the face of such catastrophic errors. Likely you are being called inside one of these __try blocks. Sad but true.

查看这篇博文,例如:OnLoad异常消失的案例——x64中的用户模式回调异常

更新:

我觉得评论中被归咎于我的想法有点奇怪.备案:

I find it kind of weird the kind of ideas that are being attributed to me in the comments. For the record:

  • 没有声称 SEH 本身很糟糕.

    我说它不可移植",这是真的.我还声称在用户模式代码中使用 SEH 忽略 STATUS_ACCESS_VIOLATION 是可悲的".我坚持这一点.我应该希望我有勇气在新代码中做到这一点,而你正在审查我的代码,你会冲我大喊大叫,就像我写了 catch (...) {/* 忽略这个!*/}.这是个坏主意.这对访问冲突尤其不利,因为获得 AV 通常意味着您的进程处于不良状态,您不应继续执行.

  • I did not claim that SEH itself is bad.

    I said that it is "non-portable", which is true. I also claimed that using SEH to ignore STATUS_ACCESS_VIOLATION in user mode code is "sad". I stand by this. I should hope that I had the nerve to do this in new code and you were reviewing my code that you would yell at me, just as if I wrote catch (...) { /* Ignore this! */ }. It's a bad idea. It's especially bad for access violation because getting an AV typically means your process is in a bad state, and you shouldn't continue execution.

我确实没有争辩说 SEH 的存在意味着你必须吞下所有错误.

当然 SEH 是一种通用机制,不能责怪对它的每一次愚蠢的使用.我所说的是,一些 Windows 二进制文件在调用函数指针时吞下了 STATUS_ACCESS_VIOLATION,这是一个真实且可观察的事实,而且这还不够漂亮.请注意,他们可能有历史原因或情有可原的情况来证明这一点.因此悲伤但真实".

I did not argue that the existence of SEH means that you must swallow all errors.

Of course SEH is a general mechanism and not to blame for every idiotic use of it. What I said was that some Windows binaries swallow STATUS_ACCESS_VIOLATION when calling into a function pointer, a true and observable fact, and that this is less than pretty. Note that they may have historical reasons or extenuating circumstances to justify this. Hence "sad but true."

没有在这里注入任何Windows vs. Unix"的论调.在任何平台上,坏主意都是坏主意.在 Unix 类型的操作系统上尝试从 SIGSEGV 中恢复同样是粗略的.

I did not inject any "Windows vs. Unix" rhetoric here. A bad idea is a bad idea on any platform. Trying to recover from SIGSEGV on a Unix-type OS would be equally sketchy.