`pragma pack(push, 1)` 在 GCC 4.4.7 中崩溃。可能的编译器错误?
`pragma pack(push, 1)` crashes in GCC 4.4.7. Possible compiler bug?
我遇到了一个让我难过的错误。我已将其缩小为 GCC(特别是 RHEL Linux、GCC v.4.4.7)中 pragma pack
命令的问题,可以在下面显示的小示例案例中重新创建该问题。看起来 GCC 在这种情况下计算了错误的偏移量,这将表现为循环内的崩溃。删除 pragma pack 也可以消除错误 - 但在实际应用程序中,这将导致使用许多额外的千兆字节内存,这是不可取的。
在下面的示例中,您需要在启用优化 (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 代码):
考虑使用 __attribute__ ((packed));
而不是 #pragma pack(1)
。 IIRC,这个版本的 GCC 对待它有点不同。
我遇到了一个让我难过的错误。我已将其缩小为 GCC(特别是 RHEL Linux、GCC v.4.4.7)中 pragma pack
命令的问题,可以在下面显示的小示例案例中重新创建该问题。看起来 GCC 在这种情况下计算了错误的偏移量,这将表现为循环内的崩溃。删除 pragma pack 也可以消除错误 - 但在实际应用程序中,这将导致使用许多额外的千兆字节内存,这是不可取的。
在下面的示例中,您需要在启用优化 (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 代码):
考虑使用 __attribute__ ((packed));
而不是 #pragma pack(1)
。 IIRC,这个版本的 GCC 对待它有点不同。