在OSX上替换libstdc ++。dylib(4.0)全局新操作符和删除操作符 [英] Replacing libstdc++.dylib (4.0) global new and delete operators on OSX

查看:185
本文介绍了在OSX上替换libstdc ++。dylib(4.0)全局新操作符和删除操作符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆