I am using icpc/icc/ifort 16.0 to compile a C++/C/Fortran application (about 500 kSLOC) on a Linux machine, with the default optimization level (-O2). I am running into a crash that I have trouble explaining.
I have a class C that is part of an inheritance chain (say C -> B -> A); the base classes have some virtual methods and a virtual destructor. At some point during the execution of the code, an object of class C is instantiated for the first time:
C *c = new C(/*some parameters*/);
The constructor invokes some virtual methods of C and the code segfaults. The reason seems to be that the vtables are full of garbage, as shown by the following excerpt from my gdb session:
Program received signal SIGSEGV, Segmentation fault. 0x0000000000000000 in ?? () (gdb) up #1 0x00000000006c49b0 in C::method (this=0x21ccde0, foo=42) (gdb) info vtbl this warning: can't find linker symbol for virtual table for `C' value warning: found `C::_ZTV1C(void)' instead vtable for 'C' @ 0x12efa38 (subobject @ 0x21ccde0): : 0x6c0c68 <C::method2()> : 0x6c0cf8 <C::method3()> : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x6c36fa <C::method4()> : 0x6c3a26 <C::method5()> : 0x6c41d6 <C::method5()> vtable for 'A' @ 0x12efe78 (subobject @ 0x21ccfd8): : 0x0 : 0x0 : 0x0 : 0x0 : 0x0 : 0x0
I can confirm that the vptr values are wrong by inspecting the output of `nm -C`. For what it's worth, the vptr for C is off by only 136 bytes (should be 0x12eff00); the vptr for A is way off.
The same source code runs without a hitch when compiled with icpc/icc/ifort v15.1, icpc/icc/ifort v16.4 and several versions of the GNU suite.
Does this ring a bell for anyone? Perhaps it is a known bug of Intel compilers around v16.0? (Yes, I am aware of the First Rule of Programming). Otherwise, I am at a loss about how I should debug this. I cannot exclude that some of my application code is somehow corrupting the memory, although I ran it under valgrind and no invalid memory access were detected.
I am painfully trying to disassemble the code between the call to operator new() and the call to the constructor, hoping to spot the place where the vptr is incorrectly initialized. Do you have any simpler suggestions for debugging this?
Thank you for reading!
I could narrow it down further to the following icc versions:
So, if it is a bug, it should have appeared sometime between 15.1 and 15.6 and disappeared in 16.3.
A further detail: I have tested several compiler versions and I found the following:
If this was a compiler bug, it would seem it was fixed in v16.3.