为什么我的代码在 Windows 7 上不会出现段错误? [英] Why won't my code segfault on Windows 7?

查看:66
本文介绍了为什么我的代码在 Windows 7 上不会出现段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个不寻常的问题,但这里是:

This is an unusual question to ask but here goes:

在我的代码中,我不小心在某处取消了 NULL 的引用.但不是应用程序因段错误而崩溃,它似乎停止执行当前函数并将控制权返回给 UI.这使调试变得困难,因为我通常希望收到崩溃警报,以便我可以附加调试器.

In my code, I accidentally dereference NULL somewhere. But instead of the application crashing with a segfault, it seems to stop execution of the current function and just return control back to the UI. This makes debugging difficult because I would normally like to be alerted to the crash so I can attach a debugger.

可能是什么原因造成的?

What could be causing this?

具体来说,我的代码是一个 ODBC 驱动程序(即 DLL).我的测试应用程序是 ODBC 测试 (odbct32w.exe),它允许我在我的 DLL 中显式调用 ODBC API 函数.当我调用具有已知段错误的函数之一时,ODBC 测试不会使应用程序崩溃,而是简单地将控制权返回给 UI,而不打印函数调用的结果.然后我可以再次调用驱动程序中的任何函数.

Specifically, my code is an ODBC Driver (ie. a DLL). My test application is ODBC Test (odbct32w.exe) which allows me to explicitly call the ODBC API functions in my DLL. When I call one of the functions which has a known segfault, instead of crashing the application, ODBC Test simply returns control to the UI without printing the result of the function call. I can then call any function in my driver again.

我确实知道,从技术上讲,应用程序调用 ODBC 驱动程序管理器,该管理器加载并调用我的驱动程序中的函数.但这是无关紧要的,因为我的段错误(或发生的任何事情)导致驱动程序管理器函数也不会返回(应用程序未打印结果就证明了这一点).

I do know that technically the application calls the ODBC driver manager which loads and calls the functions in my driver. But that is beside the point as my segfault (or whatever is happening) causes the driver manager function to not return either (as evidenced by the application not printing a result).

我的一位同事在使用类似机器时遇到了同样的问题,而另一位同事则没有,但我们无法确定任何具体差异.

One of my co-workers with a similar machine experiences this same problem while another does not but we have not been able to determine any specific differences.

推荐答案

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.

这篇关于为什么我的代码在 Windows 7 上不会出现段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆