问题描述
我的XCTest套件发生了非常奇怪的崩溃。
测试目标为Application tests
,并启用了Allow testing Host Application API
复选框。Build for active arch only
为是。
现在我的测试套件中只有一个测试,它仍然崩溃。Xcode
说崩溃的原因是“堆损坏”。
我已经见过the possible reasons堆损坏,看来对我来说这没有用。
在使用Address Sanitiser
和BehavIoUr Sanitiser
进行测试时,我得到如下信息:
测试如下:
- (void)testHeapCorruption {
MyCppClassDictionary dict;
int file_index1 = 41;
// MyCppClassptr is custom_ptr<MyCppClass>
MyCppClassptr data_to1 = new MyCppClass(0,41);
dict.pushDataItem(data_to1);
MyCppClassptr data_from1 = dict.find(file_index1);
}
和MyCppClass
像这样:
typedef custom_ptr<MyCppClass> MyCppClassptr;
MyCppClass::MyCppClass(const void* data,int len,int file_index) : m_file_index(file_index)
{
if(len > 0)
{
m_data = malloc(len);
memcpy(m_data,data,len);
}
this->m_len = len;
m_len_initial = len;
}
MyCppClass::~MyCppClass()
{
if (m_data) free(m_data);
}
void MyCppClassDictionary::pushDataItem(MyCppClassptr item)
{
assert(item);
assert( item->m_file_index != -1 );
m_undo_map[item->m_file_index] = item;
}
MyCppClassptr MyCppClassDictionary::find(int file_index)
{
auto it = m_undo_map.find(file_index);
if ( it != m_undo_map.end() )
return it->second;
return 0;
}
custom_ptr
是一个模板类,其作用类似于std::shared_ptr
:它存储对对象的引用数量,仅在没有引用时才调用析构函数。
仅当MyCppClass
和MyCppClassDictionary
的目标代码位于Application
目标中时,才会发生崩溃。当我复制类( MyCppClass2 , MyCppClassDictionary2 )并将它们仅链接到Test
目标时,一切正常。
现在是低级部分
在ApplicationTarget
软件包中,有./ApplicationTarget
个二进制文件和PlugIns/TestTarget.xctest/./TestTarget
个二进制文件。
当看到TestTarget
二进制符号时,MyCppClass
函数是“段外部符号”部分中的“外部函数”。
我认为“堆损坏”中的“堆”看起来与此类似:
我想知道:
- 相对于主要目标,如何准确地将
TestTarget
二进制文件加载到进程内存中。
- 它们是否可能具有不同的堆:一个堆用于主要目标,另一个堆用于测试目标?
- 当将数据分配到一个堆上并在另一个堆上释放时,是否可以调试场景?在
malloc
内部/之前,可以打印heap
的起始地址吗? - 我可以尝试哪种 logging ?因为地址Sanitiser告诉了事实后的问题。
我想了解问题的根源,但感觉我的内存管理/组装技能还不够。
任何评论/链接都将受到高度赞赏。
解决方法
问题的原因是测试目标和主要目标的目标代码略有不同。
一个custom_ptr
看起来像这样:
//file custom_ptr.h
template<class T> class custom_ptr
{
#ifdef DEBUG
T* some_debug_pointer;
#endif
};
我只为主要目标在DEBUG=1
中通过了Preprocessor Definitions
。
因此,在主要目标custom_ptr
中有一个成员some_debug_pointer
,因此custom_ptr
对象的大小大于测试目标中的情况,在测试目标中,custom_ptr
没有some_debug_pointer
成员