Solaris和Linux上未对齐的内存访问差异

我在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包来尝试防止这两台机器之间的对齐差异。     
已邀请:
您不能获取压缩结构的非
char
元素的地址,并通过该指针访问该元素。通常,您不应该使用压缩结构。它们是一种严重的代码味道,表明你可能正在做一些可怕的错误。如果您坚持保持打包结构,尽管所有请求理智,您可以使用中间变量并将其地址传递给
scanf
,然后分配到
struct
。     
Solaris计算机是否在比x86更难对齐要求的硬件上运行? 你在pmg的回答中的评论意味着你已经关闭了填充,这将触发那种错误,例如: SPARC。     
你的结构是如何定义的? 像这样?
struct X {
  char name[MAXNAME],
  short race,
  unsigned class,
  unsigned id,
  char guild[MAXGUILD],
  /* possibly more members ... */
};
如果不同,则
scanf
转换规范与参数不匹配。     
SIGBUS
通常表示对齐异常或尝试访问实际上不存在的内存(可能是某些设备的MMIO空间中某些不存在的地址)。 许多架构中的Linux模拟未对齐的加载/存储,对于SPARC,请查看
arch/sparc/kernel/unaligned.c
arch/sparc/kernel/una_asm.S
。 Linux / ARM有一个sysctl,它允许您选择是否在未对齐的内存访问时以静默方式崩溃/记录和模拟/模拟。显然,Linux / SPARC没有等效的sysctl。     

要回复问题请先登录注册