对 GCC/Windows DLL/C++ 的任何改进; STL前端?
昨天,在 Cygwin 下使用 GCC 编译的 DLL 时,我遇到了一个相当烦人的崩溃。 基本上,一旦使用调试器运行,您可能最终会陷入由 RtlFreeHeap() 接收到它未分配的地址引起的调试陷阱。
这是 Cygwin 上的 GCC 3.4 的已知错误。 出现这种情况是因为 libstdc++ 库包含针对空字符串的“聪明”优化。 我就不详细介绍了(请参阅本文中的参考资料),但是每当您在一个 DLL 中为“属于”另一个 DLL 的 std::string 对象分配内存时,您最终都会为一个堆提供一个块以释放来自它的内存。另一堆。 因此,RtlFreeHeap() 中的SIGTRAP。
当跨 DLL 边界抛出异常时,还会报告其他问题。
一旦您的项目基于 DLL 和 STL,这使得 Windows 上的 GCC 3.4 成为不可接受的解决方案。 我有几个选项可以跳过此选项,其中许多选项非常耗时和/或烦人:
- 我可以 修补我的 libstdc++ 或 使用 --enable-full-dynamic-string 配置选项重建它
- 我可以使用静态库,这会增加我的链接时间
我也无法(还)切换到另一个编译器,因为我还使用了一些其他工具正在使用。 我从一些海湾合作委员会的人那里发现的评论是“几乎从未报道过,所以这可能不是问题”,这让我更恼火。
有人有关于此问题的消息吗?除了 GNU Radio bug 跟踪器。
谢谢!
Yesterday, I got bit by a rather annoying crash when using DLLs compiled with GCC under Cygwin. Basically, as soon as you run with a debugger, you may end up landing in a debugging trap caused by RtlFreeHeap() receiving an address to something it did not allocate.
This is a known bug with GCC 3.4 on Cygwin. The situation arises because the libstdc++ library includes a "clever" optimization for empty strings. I spare you the details (see the references throughout this post), but whenever you allocate memory in one DLL for an std::string object that "belongs" to another DLL, you end up giving one heap a chunk to free that came from another heap. Hence the SIGTRAP in RtlFreeHeap().
There are other problems reported when exceptions are thrown across DLL boundaries.
This makes GCC 3.4 on Windows an unacceptable solution as soon as your project is based on DLLs and the STL. I have a few options to move past this option, many of which are very time-consuming and/or annoying:
- I can patch my libstdc++ or rebuild it with the --enable-fully-dynamic-string configuration option
- I can use static libraries instead, which increases my link time
I cannot (yet) switch to another compiler either, because of some other tools I'm using. The comments I find from some GCC people is that "it's almost never reported, so it's probably not a problem", which annoys me even more.
Does anyone have some news about this? I can't find any clear announcement that this has been fixed (the bug is still marked as "assigned"), except one comment on the GNU Radio bug tracker.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您遇到的普遍问题是 C++ 从来都不是真正意义上的组件语言。 它的真正设计目的是用于创建完整的独立应用程序。 诸如共享库和其他此类机制之类的东西是由供应商自己创建的。 想想这个例子:假设您创建了一个返回 C++ 对象的 C++ 组件。 C++ 组件如何知道它将被 C++ 调用者使用? 如果调用者是 C++ 应用程序,为什么不直接使用该库呢?
当然,以上信息并不能真正帮助你。
相反,我会创建共享库/DLL,以便您遵循几个规则:
您可能需要在组件中创建额外的 API 来确保这些规则,但通过遵循这些规则,将确保不会发生上述问题。
The general problem you're running into is that C++ was never really meant as a component language. It was really designed to be used to create complete standalone applications. Things like shared libraries and other such mechanisms were created by vendors on their own. Think of this example: suppose you created a C++ component that returns a C++ object. How is the C++ component know that it will be used by a C++ caller? And if the caller is a C++ application, why not just use the library directly?
Of course, the above information doesn't really help you.
Instead, I would create the shared libraries/DLLs such that you follow a couple of rules:
You may have to create additional APIs in your component to ensure these rules, but by following these rules, it will ensure that problems like the one described won't happen.