Размеры стандартных структур

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Размеры стандартных структур

Сообщение mike » 23.11.2009 04:23:37

Странное поведение, жил-был себе код:
Код: Выделить всё
var
  SHMI: TShmid_ds;
begin
  Data:= shmat(Handle, nil, 0);
  if PtrUInt(Data) <> PtrUInt(-1) then
    if shmctl(Handle, IPC_STAT, @SHMI) = 0 then
      begin
        Size:= SHMI.shm_segsz;

Работал нормально под Ubuntu/32, но после значительной модификации использующего этот код проекта вдруг в Size стала заноситься какая-то фигня. Первая же проверка показала неправильное заполнение полей структуры TShmid_ds.shm_perm, а значит и всего, что находится ниже нее. После нескольких попыток было выяснено, что для правильной работы, тип TIPC_Perm должен иметь такой вид:
Код: Выделить всё
type TIPC_Perm = record
  key: TKey;   
  uid: cushort;  // а не uid_t
  gid: cushort;  // а не gid_t
  cuid: cushort; // а не uid_t
  cgid: cushort; // а не gid_t
  mode: cushort; // а не mode_t
  seq: cushort;   
end;

Т.е. поля идентификаторов и режима должны быть 16-битными! В этом случае значения полей данной структуры оказываются правильными, и, соответственно, TShmid_ds.shm_segsz тоже заполняется корректной информацией.

Я просто не могу догнать, как же так могло получиться? Система одна и та же (только обновления периодически сама для себя качает), функцию вызываю ту же самую, почему же она теперь ожидает иную структуру? Как вообще в линуксе функция определяет, в каком формате и сколько байт заливать в out-параметр? Вот, например, как shm_perm описана с манах:
Код: Выделить всё
struct shmid_ds {
    struct ipc_perm shm_perm;    /* Ownership and permissions */
    size_t          shm_segsz;   /* Size of segment (bytes) */
    time_t          shm_atime;   /* Last attach time */
    time_t          shm_dtime;   /* Last detach time */
    time_t          shm_ctime;   /* Last change time */
    pid_t           shm_cpid;    /* PID of creator */
    pid_t           shm_lpid;    /* PID of last shmat()/shmdt() */
    shmatt_t        shm_nattch;  /* No. of current attaches */
    ...
};

Как вообще можно трактовать многоточие в конце структуры? Что это за деструктивные вольности?
mike
новенький
 
Сообщения: 40
Зарегистрирован: 23.02.2007 17:25:00

Re: Размеры стандартных структур

Сообщение Sergei I. Gorelkin » 23.11.2009 09:32:17

Случайно FPC не обновлялся вместе с убунтой?
Потому что оно мне очень напоминает соседний топик про сломанный semctl, который (если почитать комментарии к багрепортам) был сломан, в частности, из-за того, что в FPC переопределили типы uid_t, gid_t и иже с ними.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Размеры стандартных структур

Сообщение mike » 23.11.2009 15:17:23

Нет, ему неоткуда обновляться, ни в одном из прописанных репозитариев FPC вообще нет. А с semctl глюк другой, там 64-битная система принимает один из параметров не как указатель, а непосредственно (стал влезать в 64-разрядный Push, я так понимаю, вот и поменялся способ).

Добавлено спустя 1 час 32 минуты 34 секунды:
Я так понимаю, в линуксе вообще не приняты такие вещи как фиксированные размеры out-структур? Если почти весь софт собирается из сишных исходников, то значит при компиляции он подхватит именно те типы данных, которые объявлены в заголовках ядра данной конкретной системы. Например, если посмотреть на ipc.pp, то можно там видеть не только другую структуру TIPC_Perm для x86_64, но совсем иную -- для FreeBSD! В случае компиляции C-программы под эту систему, она просто возьмет декларацию из /usr/lib/include/sys/shm.h (или где оно там) и даже не заметит того, что типы некоторых полей этой структуры и их порядок совсем не такие как в Linux. Для других же языков нужно транслировать заголовочные файлы каждый раз, садясь за новую систему, иначе можно нарваться на добавленное вместо точек (см. выше) новое поле какой-нибудь структуры и получить проблемы с переполнением буфера в давно отлаженном коде.

Странная картина вырисовывается: бинарную совместимость не только не пытаются поддержать, ее гробят по поводу и без. А еще получается, что Unix-системы вообще не рассчитаны на то, что кто-то будет программировать в них не на C/C++ (или на managed/скриптах, интерпретаторы коих тоже написаны исключительно на этих языках и собраны под конкретной системой) и распространять программы не в исходных текстах.
mike
новенький
 
Сообщения: 40
Зарегистрирован: 23.02.2007 17:25:00

Re: Размеры стандартных структур

Сообщение Sergei I. Gorelkin » 23.11.2009 18:30:15

mike писал(а):Я так понимаю, в линуксе вообще не приняты такие вещи как фиксированные размеры out-структур?

Можно сказать, что само понятие "out-структура" не существует в языке C, там есть только указатели.
На самом деле - кто в лес, кто по дрова, в каждом пакете свое API и свои правила.

mike писал(а):Странная картина вырисовывается: ...


Совершенно верно. Именно по этой причине FPC жестко отвязан от libc и реализует большую часть ее функциональности самостоятельно, позволяя (несложным) программам работать на голом ядре, у которого бинарная совместимость более-менее поддерживается. С другой стороны, на той же solaris - libc используется и проблем не вызывает.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Размеры стандартных структур

Сообщение mike » 23.11.2009 18:44:24

Sergei I. Gorelkin писал(а):Можно сказать, что само понятие "out-структура" не существует в языке C, там есть только указатели.

Это понятно, но в WinAPI, например, принято кроме указателя на выходной параметр, сообщать системному вызову и актуальный размер этого параметра, чем и достигается определенная совместимость между API и, например, структурами с выравниванием и без, а также гарантируется невыход на пределы размера структуры, даже если системе есть что добавить.

Что касается исходной проблемы, то я уже в полном замешательстве. Тестовая программа на C показывает 32-битные размеры полей структур из sys/shm.h, создается впечатление что FPC вызывает какую-то другую функцию, ожидающую не совпадающий с объявленным в заголовках ядра формат структуры.
mike
новенький
 
Сообщения: 40
Зарегистрирован: 23.02.2007 17:25:00


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6

Рейтинг@Mail.ru