在OSX上替换libstdc ++。dylib(4.0)全局新操作符和删除操作符 [英] Replacing libstdc++.dylib (4.0) global new and delete operators on OSX
问题描述
我想用XCode 3.2,GCC 4.2,libstdc ++ 4.0,动态版本替换全局新的和删除操作符。
I'm trying hard to replace the global new and delete operators with XCode 3.2, GCC 4.2, libstdc++ 4.0, dynamic version.
标题新并实现它们。它们在下面粘贴。
I took the protypes directly from the header "new" and implemented them. They are pasted below.
该项目是一个.plugin所以一个动态库。这个插件必须委派分配给主应用程序自己的alloc / free例程,这些例程在一个旧的C SDK中。
The project is a .plugin so a dynamic lib. This plug-in MUST delegate allocation to the main application's own alloc/free routines, which are in an old C SDK.
所有我自己的调用new / delete以及std :: list和std :: map分配都被正确替换,但不是当std :: vector :: push_back以生长其缓冲区。在这种情况下,我的操作符new不被调用,但我的操作符删除。我知道,因为我在我的新运算符分配的任何缓冲区的前四个字节写一个令牌,并在运算符删除中检查此令牌。请参阅下面的违规代码。
All my own call to new/delete along with std::list and std::map allocations are correctly replaced, BUT not when std::vector::push_back has to grow its buffer. It that case, my operator new is not called but my operator delete is. I know that, because I write a token in the first four bytes of any buffer allocated by my new operator and I check this token in operator delete. See below for offending code.
extern "C++"
{
__attribute__((visibility("default"))) void* operator new(std::size_t) throw (std::bad_alloc);
__attribute__((visibility("default"))) void* operator new[](std::size_t) throw (std::bad_alloc);
__attribute__((visibility("default"))) void operator delete(void*) throw();
__attribute__((visibility("default"))) void operator delete[](void*) throw();
__attribute__((visibility("default"))) void* operator new(std::size_t, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void* operator new[](std::size_t, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void operator delete(void*, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void operator delete[](void*, const std::nothrow_t&) throw();
}
以下代码会在yo超出范围,因为分配给std :: vector的内存没有被我的操作符new分配。
The following code will cause an assert when "yo" goes out of scope because the memory allocated for the std::vector was not allocated by my operator new.
{
std::vector<std::string> yo;
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
}
以下代码是确定的,因为std :: vector :: reserve call my operator new:
The following code is ok because std::vector::reserve calls my operator new:
{
std::vector<std::string> yo;
yo.reserve(4);
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
}
GBD(调试器)不会让步骤进入std :: vector :: push_back实现当它需要增长缓冲区(方法名为_M_insert_aux)。所有我知道的是,我的操作符new不从std :: vector :: push_back。
GBD (debugger) won't let met step into the std::vector::push_back implementation when it need to grow the buffer (the method is named _M_insert_aux). All I know is that my operator new is never called from std::vector::push_back.
上述解决方法不能应用于所有第三方库我在用着。其中一个是push_back的大用户。
The workaround above can't be applied to all the 3rd party libs that I'm using. One of which is a big user of push_back.
我试图链接到libstdc ++。a但我有同样的问题。
I tried linking statically to libstdc++.a but I'm having the same issue.
有一些专门针对std :: vector< std :: string>不使用全局新运算符?
Is there some specialization for std::vector< std::string > that doesn't use the global new operator?
BTW这在VS9的窗口上完美工作。
BTW this worked perfectly on windows with VS9.
推荐答案
我最终通过使用乔治·科斯坦萨的技术解决了我的问题:反之。
I finally solved my problem by using George Costanza's technique: doing the opposite.
代替尝试让我的操作符新的和删除可见性,我完全隐藏它们。
Instead of trying to make my operators new and delete visibles, I hid them completely.
诀窍是设置这些在每个静态libs&
The trick is to set these in every static libs & in the bundle settings:
- 设置C ++标准库类型:静态
- 默认情况下隐藏的符号:已选中
- 修复&继续:取消选中(非常重要,否则默认禁用之前的设置)
因为使用XCode 3.2简单地点击Build后更改这些设置将无法工作。
and do a clean all & build because with XCode 3.2 simply hitting Build after changing these settings won't work.
显然,我改变了操作符new&删除原型为:
Obviously, I changed the operator new & delete prototypes to:
#pragma GCC visibility push(hidden)
extern "C++"
{
void* operator new(std::size_t) throw (std::bad_alloc);
void* operator new[](std::size_t) throw (std::bad_alloc);
void operator delete(void*) throw();
void operator delete[](void*) throw();
void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw();
} // extern "C++"
#pragma GCC visibility pop
没有为什么这样工作?必须同时具有静态和隐藏符号才能工作。它似乎屏蔽我的捆绑插件从STL专门化实现,内联他们的分配器。
No why does that work? Must have both Static + Hidden Symbols to work. It seems to shield my bundle plug-in from STL specializations implementations that inlined their allocators.
还要注意,这只发生在一个bundle插件动态加载从一个大app。在一个从控制台应用程序调用的一个简单的.dylib项目,一切工作正常与任何设置。
Also note that this only happened in a bundle plug-in dynamically loaded from a big app. In a trivial .dylib project called from a console application everything worked fine with any settings.
这篇关于在OSX上替换libstdc ++。dylib(4.0)全局新操作符和删除操作符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!