【发布时间】:2026-01-11 06:55:01
【问题描述】:
在使用 GCC 时,考虑到我有时在发布时和有时在调试时编译同一个库,ABI 是否保证兼容?
(使用相同的编译器)
我有一个可执行文件和一些共享对象(一些依赖于其他对象),我希望能够在不重新编译所有内容的情况下交换发布/调试共享对象,但 只有感兴趣的共享对象。
这可能吗,或者在某些情况下我可能会以这种方式得到一些未定义的行为? (假设我的代码是严格打包的,并且在发布和调试中都进行了填充)
编辑:
我将详细说明我们遇到的问题。我们有一个自定义版本的intrusive_ptr,在调试模式下我们有我们自己的intrusive_ptr,它有一个单个 成员,它是boost::intrusive_ptr,在发布时我们只使用boost::intrusive_ptr。我们intrusive_ptr的API和boost::intrusive_ptr是一样的,而且我们在类中没有任何虚函数。
我们看到的是这样的:
如果我们使用所有调试库或所有发布库都可以正常工作。如果我们将调试可执行文件与发布库混合使用,intrusive_ptr 会发生内存泄漏,并且不会释放对象。
我们的intrusive_ptr 和boost::intrusive_ptr 的大小在调试和发布时都是相同的(我们的类不会在顶部增加任何大小开销)。
所以我想知道是什么导致了泄漏,唯一想到的就是 ABI 差异。
想法?
【问题讨论】:
-
术语“调试”和“发布”在 gcc 领域没有很好的定义,往往是 IDE 的一个特性。如果您的“调试”构建在调试模式下使用 libstdc++,那么不,安全迭代器功能会更改集合对象布局。混合会导致随机内存损坏。
-
其实我已经检查过了,代码没有用libstdc++编译
-
@MaxShifrin 你找出问题的原因了吗?
-
是的,ABI 不保证是兼容的,据我回忆,在我们的例子中,这是对象结构中的一些额外填充。因此我们不能以这种方式做指针技巧,必须围绕这个问题进行设计。
标签: c++ gcc compilation shared-ptr abi