Reputation: 201
I have a problem executing c++ code compiled (and debugged) through XCode Version 9.2 (9C40b) on an iPhone simulator.
Code snippet is as below; all the involved files are part of the same library that is later linked to an iPhone application for execution. Please note that the posted code snipped has been customized and trimmed down for investigation purposes, originally it was serving a different purpose, but it has been enough of a pain to isolate the 'offending lines' -.-
// HEADER FILE struct_definition.h CONTAINING STRUCT DECLARATION
struct SRowLogBookDescriptor
{
SRowLogBookDescriptor();
mutable u32 key ;
std::string name ;
std::string ui_name ;
u32 type ;
u32 physical_quantity ;
std::string unit_of_measure ;
u32 constraints_size ;
u8* constraints ;
std::string comment ;
u64 marker;
};
//---------------------------------------------
// SOURCE FILE struct_definition.cpp CONTAINING STRUCT CONSTRUCTOR DEFINITION
SRowLogBookDescriptor::SRowLogBookDescriptor()
: key(0xFFFFFFFF)
, name("name")
, ui_name("ui_name")
, type(0xAAAAAAAA)
, physical_quantity(0x55555555)
, unit_of_measure("unit")
, constraints_size(0xB5006BB1)
, constraints(nullptr)
, comment("comment")
, marker(0xBAD00DABBAD00DAB)
{}
//---------------------------------------------
// SOURCE FILE function_call.cpp USING THE MISALIGNED STRUCTURE
void CDefaultLogbookSet::AddDoubleLogBookToSet()
{
SRowLogBookDescriptor descr;
int i1 = offsetof(SRowLogBookDescriptor,key) ;
int i2 = offsetof(SRowLogBookDescriptor,name) ;
int i3 = offsetof(SRowLogBookDescriptor,ui_name) ;
int i4 = offsetof(SRowLogBookDescriptor,type) ;
int i5 = offsetof(SRowLogBookDescriptor,physical_quantity) ;
int i6 = offsetof(SRowLogBookDescriptor,unit_of_measure) ;
int i7 = offsetof(SRowLogBookDescriptor,constraints_size) ;
int i8 = offsetof(SRowLogBookDescriptor,constraints) ;
int i9 = offsetof(SRowLogBookDescriptor,comment) ;
int i10 = offsetof(SRowLogBookDescriptor,marker);
size_t test1 = descr.name.capacity();
size_t test2 = descr.ui_name.capacity();
descr.comment = "";
descr.name = "new_name";
descr.physical_quantity = 0xaa;
descr.type = 0x55;
descr.ui_name = "new_ui_name";
descr.unit_of_measure = "new_unit";
}
//---------------------------------------------
I have a struct which contains 32bits integers, strings, and a pointer. I am well aware that the alignment layout of the struct would lead to wasted bytes due to padding. I have instrumented the constructor of the struct in order to highlight where each field is being mapped into memory.
The struct is then laid on the stack in the AddDoubleLogBookToSet function, I save all the offsets for the fields in the struct, I checkout string capacity, filled in with values, then function exits.
As soon as I try to assign a value to the name field, I get a BAD_ACCESS exception. I am attaching 2 screenshots taken from the XCode debugger when I actually got the exception. There you can see the expected offsets for struct attributes, as well as you can see that the debugger actually accesses the attributes at a memory location where they are actually not stored.
I just checked with the debugger that when I execute the constructor the debugger 'sees' the struct members appropriately (I havent attached a screenshot for this).
Now... it appears to me that there is some sort of compilation difference between function_call.cpp and struct_definition.cpp in terms of packing and/or alignement. I have checked multiple times that each pragma pack in the code is appropriately cleared everytime, and apparently reviewing the code, all is ok.
Let me add that the same c++ code being compiled in Xcode is being compiled and executed smoothly on different Windows releases(PCs) compiled through Visual Studio 2017. The investigation started because of a wide array of different crashes all related to the library containing the offending code (there are several different structs in that library). Last but not least, the iPhone application has been executing fine for a long time, then a couple fo weeks ago it stopped executing correctly.
and here is the question: can someone help me out in identifying WHY the 2 source files are being compiled differently?
Thanks in Advance
Upvotes: 1
Views: 418
Reputation: 201
Well I found where the problem was located.
I created a new source file exactly equal to the offending one, further trimmed down its content in order to ease the investigation. I compiled the file and started creating instances of the class pruning code where it was causing the problem versus not causing the problem.
It ended up that there was a 'remote header' file, where packed structures were declared, that had include directives INSIDE the pragma pack(s). Taking those include away from special packing, made the compilation consinstent again across all the files. The include tree was particularly harmful in the Xcode compilation process, compared with the Visual Studio compilation process.
Took only a few days to find out -.-'
Upvotes: 1