Я портирую на cygwin программу на FORTRAN / C, которая использует подпрограммы C для создания общей области памяти, позволяющей различным независимым подпрограммам FORTRAN обмениваться данными. Программа компилируется и нормально работает в Linux с компиляторами g77 / gcc. Я компилирую cygwin 1.7.33-2 (0.280 / 5/3) с gfortran / gcc (4.8.3).
Одна процедура C создает раздел разделяемой памяти определенного пользователем размера. Кажется, это работает нормально, хотя мне пришлось добавить две строки в файл sys / shm.h:
#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
Кажется, что функции библиотеки shm возвращают разумную информацию (размер страницы).
Каждая подпрограмма FORTRAN затем вызывает подпрограмму C для поиска общей памяти, при этом подпрограмма C возвращает указатели на две позиции в разделе, предназначенном для различных типов данных:
#define PAGESIZE 1024
int findshm(
char **pptr, /* Address of the parameter pointer */
float **cptr) /* Address of the data pointer */
.... calls to shm library functions ....
shmaddr = 0;
p = shmat(shmid, shmaddr, (SHM_R | SHM_W));
/* Store the pointers */
*pptr = p;
*cptr = (float *) (p + PAGESIZE);
return npages;
Вызывающий код FORTRAN выглядит так:
integer pptr, cptr
integer npages
npages = findshm(pptr, cptr)
Хотя общий размер созданного раздела памяти npages
в порядке, объем памяти после cptr слишком мал на cygwin (но не в Linux), и программа вылетает из-за больших наборов данных с
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Думая, что это может иметь отношение к различным базовым типам данных для указателей (integer vs char / float) в коде C и FORTRAN, я попытался изменить определения типов указателей в подпрограммах FORTRAN на
byte pptr
real*4 cptr
и все это компилируется и запускается, но дает точно такую же ошибку времени выполнения и не объясняет, почему программа работает в Linux.
Не уверен, что я могу сделать на этом этапе (на что обращать внимание, где получить помощь), поэтому вклад приветствуется.
Изменить
Оказывается, в разделе кода с пометкой
.... calls to shm library functions ....
есть линия
shmid = shmget(key, PAGESIZE, IPC_ALLOC);
с параметрами, определенными ранее как PAGESIZE=512
и IPC_ALLOC=0
, которые вызвали проблему. Вызов в Linux, кажется, возвращает shmid, связанный с ключом, без выполнения выделения памяти, тогда как в cygwin он приводит к выделению памяти до предела 4 КБ, что приводит к ошибке seg.
shm_open(3)
сmmap(2)
) обычно немного лучше для работы в современных системах * nix, которые ее предоставляют. (Не уверен, что это делает cygwin.)shmat(2)
является частью более старого интерфейса разделяемой памяти System V. - person Ulfalizer   schedule 08.04.2015