我在linux上编写了一个程序(x86,32位),一切正常。但是当我尝试在Solaris(SPARC,64位)上编译和运行相同的源代码时,我遇到了一个总线错误(SIGBUS)来自gdb的消息如下:
gdb) where
#0 0xff2aa57c in number () from /lib/libc.so.1
#1 0xff2a9a70 in __doscan_u () from /lib/libc.so.1
#2 0xff2b0014 in vsscanf () from /lib/libc.so.1
#3 0xff2aeb90 in fscanf () from /lib/libc.so.1
#4 0x00010940 in main (argc=4, argv=0xffbff48c) at wHeap.c:22
事实证明,由于fscanf函数发生了错误,相应的代码片段如下:
while( fscanf(input,"%[^,],%hu,%u,%u,%[^\n]\n",record.name,&record.race,&record.class,&record.id,record.guild) != EOF){
......
}
基本上,我尝试从逗号分隔值文件中提取信息并将它们存储在结构数组(记录)中,例如:
Rod'rod,1,4,103026,Project Peace
Ceru,1,6,89351,World Keepers
Belget,2,9,246708,Radiant Heaters
记录结构如下:
#pragma pack(1)
typedef struct {
char name[MAXNAME];
unsigned short race;
unsigned int class;
unsigned int id;
char guild[MAXGUILD];
}record;
正如您所注意到的,我使用了pragma pack来尝试防止这两台机器之间的对齐差异。
答案 0 :(得分:3)
Solaris计算机是否在比x86更难对齐要求的硬件上运行?
你在pmg的回答中的评论意味着你已经关闭了填充,这将触发那种错误,例如: SPARC
答案 1 :(得分:3)
您不能获取压缩结构的非char
元素的地址,并通过该指针访问该元素。通常,您应该从不使用压缩结构。它们是一种严重的代码味道,表明你可能正在做一些可怕的错误。如果您坚持保持打包结构,尽管所有请求都是理智的,您可以使用中间变量并将其地址传递给scanf
,然后分配到struct
。
答案 2 :(得分:0)
你的结构是如何定义的?
喜欢这个吗?
struct X {
char name[MAXNAME],
short race,
unsigned class,
unsigned id,
char guild[MAXGUILD],
/* possibly more members ... */
};
如果不同,则scanf
转换规范与参数不匹配。
答案 3 :(得分:0)
SIGBUS
通常表示对齐异常或尝试访问实际上不存在的内存(可能是某些设备的MMIO空间中某些不存在的地址)。
许多架构中的Linux模拟未对齐的加载/存储,对于SPARC,请查看arch/sparc/kernel/unaligned.c
和arch/sparc/kernel/una_asm.S
。 Linux / ARM有一个sysctl,它允许您选择是否在未对齐的内存访问时以静默方式崩溃/记录和模拟/模拟。显然,Linux / SPARC没有等效的sysctl。