c++ - 子系统:native中的异常处理

标签 c++ exception windows-10 native visual-studio-2019

我正在编写一个 native 模式应用程序(想想:link/subsystem:native)。这意味着我无法使用 kernel32.dll 中的任何内容,这(显然)对 C 运行时库没有任何意义。大多数情况下,这对我来说不是问题,因为我需要的一切都在 ntdll.dll 中。代码已编写并可以运行。

但是,我正在用 C++ 编写代码,并且存在如何处理异常处理的问题。我相信 native 模式应用程序的目的是使用 SEH,这就是我所做的。但这并不完全有效。

如果我在没有/EHa 的情况下编译,当我出现 RtlRaiseException 时,我的析构函数不会被调用。但是,如果我使用/EHa 进行编译,则会得到一个 undefined symbol (未解析的外部符号 __CxxFrameHandler4),它显然只存在于 C 运行时中。

(如何)我可以编译我的 C++ 代码以支持展开,同时仍然构建 native 模式应用程序吗?


编辑:VC 有 4 种可能的异常处理设置,所有这些设置在这种情况下都有问题:

  • 是,但存在 SEH 异常 (/EHa) - 如上所述,这会导致无法解析的外部符号 __CxxFrameHandler4
  • 是 (/EHsc) - 2 个未解析的符号:__CxxFrameHandler4 和 __std_terminate
  • 是,使用外部 C 函数 (/EHs) - 与/EHsc 相同,有 2 个未解决
  • - 没有未解析的符号,但引发异常时不会调用析构函数。

我想知道是否可以链接到 C 运行时的非 dll 版本。毕竟,如果所有内容都嵌入到我的可执行文件中,那么在启动时运行时就不需要加载任何 dll,对吗?

因此,我尝试链接 libvcruntime.lib(__CxxFrameHandler4 的明显主页)。好消息是 __CxxFrameHandler4 不再悬而未决。坏消息是,这又给了我 55 个未解析的符号。此列表包括像 __imp_TlsAlloc__imp_TlsGetValue 这样的项目,它们显然来自 kernel32.dll(因此我无法使用)。

我准备使用 C++ 异常或 SEH,但我无法在这种情况下使用它们。

我看到 ntdll.dll 中导出了许多与异常相关的函数。也许我应该加入一些其他异常处理机制?


Edit2:由于 __CxxFrameHandler4 不适合我,我尝试禁用新的异常处理 (/d2FH4-)。这样做的唯一效果是将未解析的符号更改为 __CxxFrameHandler3。这不是我希望的结果。

我没有主意了。如果有某种方法可以在不使用 kernel32 的情况下展开堆栈,我找不到它。事实上,ntdll 中存在名称中带有“Exception”的导出函数,这表明可能存在,但也可能没有。也许总有“C”代码的意图,其中析构函数不是一个东西。

如果有人有任何新的东西可以尝试或有新的地方可以看,我将不胜感激。甚至有权威人士表示这是不可能的。至少那时我会知道。

最佳答案

有这个(特殊的)cl.exe /kernel转变。基本上这意味着:

No exceptions, no RTTI and no default new() / delete()

我可能认为您已经找到了这个开关并且很乐意使用它?

编辑:

关键问题可能是:“为什么存在这个开关?”。我的猜测是,这是一条“来自上面的消息”:在 WIN 上使用 C++ 开发低级“事物”时,甚至不要尝试 C++ 异常、RTTI 和 dflt new()/delete()。

无论如何,我不建议在 C++ 低级(即“ native ”)WIN 构建中展开 C++ 堆栈。我假设您确实知道 SEH ?如果你这样做了,那么你就知道了those dark woods 。在那里可以使用 ASAN 。幸存者的故事确实存在。

关于c++ - 子系统:native中的异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59454174/

相关文章:

c++ - cuda代码的优化技巧

c++ - 字符数组地址的意外输出

c++ - R包与Rcpp链接错误 : "undefined symbol: LAPACKE_dgels"

postgresql - 捕获多种类型的异常

maven - 在Windows 10中从源代码构建hadoop时,Maven上的命令行太长

ubuntu - VirtualBox - 从主机操作系统创建虚拟机作为克隆

c++ - 由于对模板化类型的通用(前向)引用而无法实例化函数模板

java - 异常处理

java - 如何捕获ConnectionException、UnknownHostException?

windows - 使用 PowerShell 获取最新卷