Нераспределенная разница в доступе к памяти в Solaris и Linux - PullRequest
1 голос
/ 07 апреля 2011

Я написал программу для Linux (x86,32-bit), все работает нормально. Но когда я пытаюсь скомпилировать и запустить тот же исходный код на Solaris (SPARC, 64-bit), я получаю ошибку шины (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, чтобы попытаться предотвратить разницу в выравнивании между этими двумя машинами.

Ответы [ 4 ]

3 голосов
/ 07 апреля 2011

Машина Solaris работает на оборудовании, которое предъявляет более жесткие требования к выравниванию, чем, скажем, x86?

Ваш комментарий в ответе pmg подразумевает, что вы отключили заполнение, что вызовет именно такую ​​ошибкуНапример, SPARC .

3 голосов
/ 07 апреля 2011

Вы не можете взять адрес не-char элемента упакованной структуры и получить доступ к элементу через этот указатель. В общем случае никогда не следует использовать упакованные структуры . Они представляют собой серьезный запах кода и указывают на то, что вы, вероятно, делаете что-то ужасно неправильно. Если вы настаиваете на сохранении упакованной структуры, несмотря на все соображения здравого смысла, вы можете использовать промежуточные переменные и передать их адреса в scanf, а затем присвоить в struct.

0 голосов
/ 07 апреля 2011

SIGBUS обычно указывает на исключение выравнивания или попытку доступа к памяти, которая физически не существует (возможно, какой-то несуществующий адрес в пространстве MMIO какого-либо устройства).

Linux во многих архитектурах эмулирует невыровненные загрузки / хранилища, для SPARC посмотрите на arch/sparc/kernel/unaligned.c и arch/sparc/kernel/una_asm.S.В Linux / ARM есть sysctl, который позволяет вам выбирать, аварийно завершить / записать в журнал и эмулировать / эмулировать в режиме безлимитного доступа к памяти.По-видимому, в Linux / SPARC нет аналога sysctl.

0 голосов
/ 07 апреля 2011

Как определяется ваша структура?

Как это?

struct X {
  char name[MAXNAME],
  short race,
  unsigned class,
  unsigned id,
  char guild[MAXGUILD],
  /* possibly more members ... */
};

Если это не так, спецификация преобразования scanf не соответствует аргументам.

...