2

昨天,在 Cygwin 下使用 GCC 编译的 DLL 时,我遇到了一个相当烦人的崩溃。基本上,一旦您使用调试器运行,您最终可能会陷入由 RtlFreeHeap() 接收到它未分配的地址所引起的调试陷阱。

这是Cygwin上 GCC 3.4 的一个已知错误。出现这种情况是因为 libstdc++ 库包含针对空字符串的“聪明”优化。我为您省去了细节(请参阅本文中的参考资料),但是每当您在一个 DLL 中为“属于”另一个 DLL 的 std::string 对象分配内存时,您最终都会给一个堆释放一个来自另一个堆。因此RtlFreeHeap() 中的 SIGTRAP

当跨 DLL 边界引发异常时,还会报告其他问题。

一旦您的项目基于 DLL 和 STL,这使得 Windows 上的 GCC 3.4 成为不可接受的解决方案。我有几个选项可以跳过这个选项,其中许多非常耗时和/或烦人:

由于我正在使用其他一些工具,我也不能(还)切换到另一个编译器。我从一些 GCC 人那里得到的评论是“它几乎从未被报道过,所以这可能不是问题”,这让我更加恼火。

有人有这方面的消息吗?除了GNU Radio bug tracker上的一条评论外,我找不到任何明确的声明表明此问题已得到修复(该错误仍被标记为“已分配”)。

谢谢!

4

1 回答 1

1

您遇到的一般问题是 C++ 从来都不是真正意义上的组件语言。它实际上是为创建完整的独立应用程序而设计的。诸如共享库和其他此类机制之类的东西是由供应商自己创建的。想想这个例子:假设您创建了一个返回 C++ 对象的 C++ 组件。C++ 组件如何知道它将被 C++ 调用者使用?如果调用者是 C++ 应用程序,为什么不直接使用库呢?

当然,以上信息并不能真正帮助您。

相反,我会创建共享库/DLL,以便您遵循一些规则:

  1. 由组件创建的任何对象也会被同一个组件销毁。
  2. 当所有创建的对象都被销毁时,可以安全地卸载组件。

您可能必须在您的组件中创建额外的 API 来确保这些规则,但是通过遵循这些规则,它将确保不会发生类似的问题。

于 2009-02-06T21:17:20.357 回答