Reputation: 2272
I have a quite strange crash in my XCTest suite.
The test target is Application tests
with Allow testing Host Application API
checkbox enabled.
Build for active arch only
is YES.
Now I have only ONE test in my test suite, and it still crashes.
Xcode
says that the cause of crash is "Heap corruption".
I've seen the possible reasons of heap corruption, it seems none applies in my case.
When testing with Address Sanitiser
and Behaviour Sanitiser
, I get smth like this:
The test looks like this:
- (void)testHeapCorruption {
MyCppClassDictionary dict;
int file_index1 = 41;
// MyCppClassPtr is custom_ptr<MyCppClass>
MyCppClassPtr data_to1 = new MyCppClass(0, 0, 41);
dict.pushDataItem(data_to1);
MyCppClassPtr data_from1 = dict.find(file_index1);
}
and MyCppClass
like this:
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;
}
A custom_ptr
is a template class which works like std::shared_ptr
: it stores the number of references to an object, and calls a destructor only when there're no references.
The crash happens only when the object code of MyCppClass
and MyCppClassDictionary
is located in Application
target. When I duplicate the classes (MyCppClass2, MyCppClassDictionary2) and link them only to Test
target, everything is OK.
Now the low-level part
Inside ApplicationTarget
package there's ./ApplicationTarget
binary and PlugIns/TestTarget.xctest/./TestTarget
binary.
When see the symbols of TestTarget
binary, MyCppClass
functions are "extern function" in "Segment External Symbols" segment.
I assume that "Heap" in "Heap corruption" looks similar to this:
I'd like to know:
TestTarget
binary is loaded into process memory, relatively to main target. malloc
, it is possible to print heap
's start address?I'd like to understand the root of the problem, but feel that my memory management/assembly skills are not enough.
Any comments/links are highly appreciated.
Upvotes: 0
Views: 167
Reputation: 2272
The reason of the problem was that the object code for Test Target and Main Target was slightly different.
A custom_ptr
looked like this:
//file custom_ptr.h
template<class T> class custom_ptr
{
#ifdef DEBUG
T* some_debug_pointer;
#endif
};
And I passed DEBUG=1
in Preprocessor Definitions
only for Main Target.
So in Main target custom_ptr
had a member some_debug_pointer
, thus size of custom_ptr
object was bigger than in Test target, where custom_ptr
didn't have some_debug_pointer
member.
Upvotes: 0