我们面临的问题是libc与xcode 9.2捆绑在一起
Scenario :
我们有一个重载operator new和delete的框架 . 这些operator new和delete的定义将隐藏在dll中,并在此处定义了apple指南:https://developer.apple.com/library/content/technotes/tn2185/_index.html#//apple_ref/doc/uid/DTS10004200-CH1-SECTION13
我们还有一个应用程序,它链接到这个框架并重载它自己的operator new和delete .
Problem :
现在,问题是如果在框架内创建一个字符串(std :: string),它会调用应用程序端操作符new进行内存分配,但在销毁时,它调用框架端操作符delete . 由于应用程序端和框架端的不同堆实现,这可能会导致内存损坏,并且肯定是一个问题 .
仅当使用-o2或更高优化级别时,才会在框架的发布版本中观察到此问题 . 如果我们将-fno-inline标志传递给编译器,则不会出现此问题 . xcode 8.2也没有观察到这个问题 .
在进一步研究这个问题后,我发现basic_string的析构函数是在当前版本的libc中内联的,而libc与xcode 8.2捆绑在一起的情况并非如此 . 在clang论坛上对此进行了一些讨论:https://reviews.llvm.org/D24599
我的猜测是因为在运行时链接中内联,basic_string的析构函数引用框架端操作符delete来释放分配的内存,但我需要确认我的理论 .
如果是这种情况,那么我们应该使用-fno-inline标志构建我们的框架吗?如果我们使用这个标志或者我们应该考虑其他任何方法,是否有任何重大的性能损失?
定义重载运算符new和delete:
void * operator new(size_t len)throw(std :: bad_alloc)
void * operator new(std :: size_t len,const std :: nothrow_t&_nothrow)throw()
void * operator new [](size_t len)throw(std :: bad_alloc)
void operator delete(void * ptr)throw()
void operator delete(void * ptr,const std :: nothrow_t&_nothrow)throw()
void operator delete [](void * ptr)throw()
寻求帮助
如果需要,我会提供更多信息
1 回答
来自技术说明:
您的应用程序中有两个new / delete定义 . 这已经是Bad(tm)了 .
你能仔细检查图书馆是否真的遵循了这条规则 - 即没有导出符号?
我建议不要使用-fno-inline标志作为“快速修复”,因为这可能只隐藏当前的,明显的问题(多个新的/删除定义),同时仍然允许内存损坏 . 如果你无法摆脱重复的定义(这将是更好的选择IMO),你只能尝试确保 Headers 永远不会包含任何分配内存而能够内联 - 但即便如此我d既困难又有风险 .