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

发布于 2024-10-10 14:02:16 字数 509 浏览 6 评论 0原文

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

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

可能是什么原因造成的?

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

我确实知道,从技术上讲,应用程序调用 ODBC 驱动程序管理器,该管理器加载并调用我的驱动程序中的函数。但这不是重点,因为我的段错误(或发生的任何事情)导致驱动程序管理器功能也不会返回(如应用程序不打印结果所证明的那样)。

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

This is an unusual question to ask but here goes:

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?

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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

哆兒滾 2024-10-17 14:02:16

Windows 具有不可移植语言扩展(称为“SEH ") 允许您捕获页面错误和分段违规作为异常。

操作系统库的某些部分(特别是在处理某些窗口消息的操作系统代码内部,如果我没记错的话)有一个 __try 块,并且将使您的代码即使面对这样的情况也能继续运行灾难性的错误。您可能在这些 __try 块之一内被调用。悲伤但真实。

查看此博客文章,例如: OnLoad 异常消失的情况 – x64 中的用户模式回调异常

更新:

我发现它有点评论中归因于我的想法很奇怪。郑重声明:

  • 没有声称 SEH 本身不好。

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

  • 没有认为 SEH 的存在意味着你必须吞下所有错误。

    当然,SEH 是一种通用机制,不能将其归咎于每一次愚蠢的使用。我所说的是,某些 Windows 二进制文件在调用函数指针时会吞下 STATUS_ACCESS_VIOLATION,这是一个真实且可观察到的事实,而且这并不漂亮。请注意,他们可能有历史原因或情有可原的情况来证明这一点。因此“悲伤但真实。”

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

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

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.

Check out this blog post, for example: The case of the disappearing OnLoad exception – user-mode callback exceptions in x64

Update:

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

  • 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.

  • 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."

  • 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.

千笙结 2024-10-17 14:02:16

取消引用 NULL 指针是一种未定义的行为,它几乎可以产生任何结果 —— seg.fault、给 IRS 的信或 stackoverflow 上的帖子:)

Dereferencing NULL pointer is an undefined behavior, which can produce almost anything -- a seg.fault, a letter to IRS, or a post to stackoverflow :)

小瓶盖 2024-10-17 14:02:16

Windows 7 也有其容错堆 (FTH),有时会执行此类操作。就我而言,它也是一个 NULL 取消引用。如果您在 Windows 7 上进行开发,您真的想将其关闭!

什么是 Windows 7 的容错堆?

http://msdn.microsoft.com/en-us/library/ dd744764%28v=vs.85%29.aspx

Windows 7 also have its Fault Tollerant Heap (FTH) which sometimes does such things. In my case it was also a NULL-dereference. If you develop on Windows 7 you really want to turn it off!

What is Windows 7's Fault Tolerant Heap?

http://msdn.microsoft.com/en-us/library/dd744764%28v=vs.85%29.aspx

记忆之渊 2024-10-17 14:02:16

此处了解不同类型的异常处理程序 - 它们不捕获相同类型的异常。

Read about the different kinds of exception handlers here -- they don't catch the same kind of exceptions.

身边 2024-10-17 14:02:16

将调试器附加到所有可能调用 dll 的应用程序,打开该功能,以便在引发异常时中断,而不仅仅是在 [调试]|[异常] 菜单中未处理。

ODBC 是大多数(如果不是全部)COM,因为此类未处理的异常会导致问题,这些问题可能表现为奇怪地退出 ODBC 函数,或者像它挂起并且永远不会返回一样糟糕。

Attach your debugger to all the apps that might call your dll, turn on the feature to break when an excption is thrown not just unhandled in the [debug]|[exceptions] menu.

ODBC is most (if not all) COM as such unhandled exceptions will cause issues, which could appear as exiting the ODBC function strangely or as bad as it hang and never return.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文