Я столкнулся с ошибкой, которая поставила меня в тупик. Я сузил его до проблемы с командой pragma pack
в GCC (в частности, RHEL Linux, GCC v.4.4.7), которую можно воссоздать в небольшом примере, показанном ниже. Похоже, что в этом случае GCC вычисляет неправильное смещение, что проявится как сбой в цикле. Удаление пакета pragma также устраняет ошибку, но в реальном приложении это приведет к использованию большого количества дополнительных гигабайт памяти, что нежелательно.
В приведенном ниже примере вам нужно будет скомпилировать с включенной оптимизацией (O3), чтобы столкнуться с ошибкой. Я также предоставил пример элемента (cMagic) в структуре, который можно удалить, что изменит выравнивание структуры и предотвратит появление ошибки.
Я взглянул на сгенерированную сборку и считаю, что это может быть ошибка компилятора. Я пропустил что-то еще? Может ли кто-нибудь подтвердить эту ошибку или дать какие-либо сведения?
Crash.cpp:
/* Platform Version Info:
* gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
* uname: 2.6.32-504.16.2.el6.x86_64 #1 SMP Tue Mar 10 17:01:00 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux
*
* Compiling:
* Must use -O3 for compiling and linking
* CXX= g++ -g -O3 -fPIC -rdynamic -Wall -Wno-deprecated -DDEBUG
* CPP= g++ -g -O3 -fPIC -rdynamic -Wall -Wno-deprecated -DDEBUG
*
* Notes:
* This appears to be an optimization and alignment issue.
* Getting rid of a byte in Place (cMagic) causes the program to complete successfully.
*
*/
#include <stdlib.h>
#include <iostream>
using namespace std;
#pragma pack(push,1) // Structures must be packed tightly
#define MAGICCONSTANT 17
struct Place {
int iFoo;
char cMagic; // GCC doesn't like cMagic. Disillusion it and everything is OK
int aiArray[MAGICCONSTANT];
};
#pragma pack(pop)
int main(int argc, const char *argv[])
{
Place *pPlace = new Place; // Place must be on the heap... so new, calloc, malloc, etc
for (int c = 0; (c < MAGICCONSTANT); c++) {
pPlace->aiArray[c] = 0;
}
delete pPlace;
cout << "Complete!" << endl;
return 0;
}
Макетфайл:
CXX= g++ -g -O3 -fPIC -rdynamic -Wall -Wno-deprecated -DDEBUG
CPP= g++ -g -O3 -fPIC -rdynamic -Wall -Wno-deprecated -DDEBUG
OBJS= Crash.o
SRCS= Crash.cpp
TARG= crash
debug:: ${TARG}
all:: ${TARG}
${TARG}: ${OBJS}
${CPP} -o ${TARG} ${OBJS} ${LDFLAGS} ${LIBS}
clean::
rm -f ${TARG} ${OBJS} ${TARG}.core core
График дизассемблирования (сгенерированный ASM-код):
volatile
, он использует развернутую последовательность инструкцийMOV
, которые снова не восприимчивы. УвеличениеMAGICCONSTANT
до 129 создает цикл, но все еще с инструкциямиMOV
, поэтому проблема не возникает. - person Jester   schedule 28.07.2015