C++ 自定义全局新建/删除覆盖系统库
Posted
技术标签:
【中文标题】C++ 自定义全局新建/删除覆盖系统库【英文标题】:C++ custom global new/delete overriding system libraries 【发布时间】:2016-05-10 17:29:49 【问题描述】:我正在 Linux 项目上覆盖 C++ 全局新建/删除运算符。这一切都在我自己的代码中运行良好,直到我发现系统库中的新/删除符号也被我的代码替换了!这是一个非常糟糕的问题,因为它超出了我想要的“邪恶程度”。
所以问题是如何防止链接器/编译器替换其他(系统)共享库中的新/删除符号?或者更准确地说,我如何控制哪些共享库链接我的库中的 sym? 我希望系统库仍将使用其默认的新/删除实现。尤其是当可执行文件稍后使用不受我控制的 dlopen() 加载其他可选动态库时。
自定义全局 new/delete 操作符实现被构建到一个共享库中。
我在网上搜索了如何控制动态链接,但没有成功。我首先尝试更改测试可执行文件上的库链接顺序,但这并没有改变任何东西。
【问题讨论】:
您使用了错误的自定义点。如果您真的想在任何地方进行此更改,则替换全局运算符很有用。如果您只想在本地化库中自定义分配,您应该使用一些其他机制(例如分配器)来提供自定义点。 考虑仅在您的类上重载 new 和 delete 运算符。如果您的大多数对象都有一个基类,请在此处进行。这应该涵盖您正在使用的大部分内存。然后,您可以在需要管理 STL 容器内的对象的情况下创建自定义 STL 分配器。 仅在普通的“根”类中重载新/删除在诸如使用普通函数分配原始内存的情况下对我没有帮助。重构大量代码以使用自定义基础 new/delete 将是乏味的。我正在寻找 LD_PRELOAD 分配器以在其他 C++ 程序上测试它的可能性。 【参考方案1】:我发现系统库中的新/删除符号也被我的代码替换了!
你可以阅读解释为什么会发生这种情况here。
所以问题是如何防止链接器/编译器替换其他(系统)共享库中的新/删除符号?
您可以通过使用-fvisibility=hidden
构建并明确标记您执行要使用__attribute__((visibility("default")))
导出的函数,将您的::operator new
和::operator delete
设为您的库专用。或者,您可以使用linker version script 来获得相同的结果。
【讨论】:
我知道 linux .so 库与 win .dll 有很大不同。但我不知道在可执行文件中解析的动态符号会像归档文件一样链接,需要在所有链接代码中进行单一定义。所以在 *nix 中似乎是不可能的.. 太糟糕了。还是谢谢!我已经在使用 -fvisibility=hidden 编译二进制文件并在代码中标记导出的函数。 太糟糕了,它在这个超市操作系统中不起作用。我用 -fvisibility=hidden 标记了项目,用 __attribute__((visibility("hidden"))) 标记了操作符 new。我的系统库仍然被我的操作员覆盖以上是关于C++ 自定义全局新建/删除覆盖系统库的主要内容,如果未能解决你的问题,请参考以下文章