LINUX.ORG.RU

Несоответствие реализации в Linux стандарту

 , ,


0

3

Есть такая структура - struct cmsghdr, в POSIX и мануале (cmsg(3)) написано, что первый её член имеет тип socklen_t. При этом в ядре лялекса и glibc этот член объявлен с типом size_t, чей размер несколько больше. Если писать на C, то всё в принципе в порядке, но при написании биндингов начинается адский ад. В частности, при написании биндингов к recvmsg/sendmsg для хаскелла я убил несколько часов на поиск этой ошибки - да, я знаю, что в линуксе нельзя доверять документации.

Собственно вопрос - что делать?

Варианты:

  • Попытаться продвинуть исправление в linux kernel и glibc. Почти невозможно, так как это ломает ABI для юзерспейса или же вносит костыль в ядро.
  • Таскать костыль в коде. Очень не хочется этого делать просто из-за того, что у разработчиков лялекса ошибки в ДНК.

Из bits/socket.h

struct cmsghdr
{
    size_t cmsg_len;		/* Length of data in cmsg_data plus length
				   of cmsghdr structure.
				   !! The type should be socklen_t but the
				   definition of the kernel is incompatible
				   with this.  */
...
Думаю, комментарии излишни :))

joy4eg ★★★★★
()
Ответ на: комментарий от joy4eg

Думаю, комментарии излишни :))

Из man 3 cmsg:

struct cmsghdr {
    socklen_t cmsg_len;    /* data byte count, including header */
    int       cmsg_level;  /* originating protocol */
    int       cmsg_type;   /* protocol-specific type */
    /* followed by unsigned char cmsg_data[]; */
};

Думаю, комментарии излишни.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от Deleted

код в линуксе - стандарт де факто /thread

Из-за таких как ты мы до сих пор не можем избавиться от Microsoft Office и еле еле избавились от Internet Explorer. Стандарты де-факто, хрен ли.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от joy4eg

Я об этом написал в оригинальном посте.

hateyoufeel ★★★★★
() автор топика

Так если

в ядре лялекса и glibc

размер переменной на самом деле больше, чем надо, как ты умудрялся передавать в ней неверное значение? Или просто поля в сформированной из биндинга структуре корраптились из-за (в итоге) неверных смещений?

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

просто поля в сформированной из биндинга структуре корраптились из-за (в итоге) неверных смещений?

Вот это. Когда я засунул printk в ядро в нужные места, выяснилось, что в верхней половине переменной полная хрень.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

таскать костыль в коде, получается. Выпиливание из ядра это поломка ABI, и комментарий в хедере, думаю, шрам от чьих-то безуспешных попыток это продвинуть.

Где может выстрелить костыльность этого метода? На ум приходит только портирование на не-linux

Adonai ★★★
()
Ответ на: комментарий от hateyoufeel

Вернее, остальные поля были в порядке, так как hsc2hs генерировал корректные смещения. Только в cmsg_len в верхней половине была полная хрень, т.к. poke записывал только 32 бита. При этом всё strace показывал корректное значение (верхние 32 бита игнорировались).

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от stopitplease

В лишнем ifdef. В хаскелл функция poke для 32-битного типа заполнит только 32 бита (К.О.), остальные 32 бита поля останутся нетронутыми. Внутри и так используется портабельный тип, но при вызове системных функций приходится конвертировать.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от stopitplease

Иначе никак, походу. Не такая уж редкая ситуация

Ну почему же, можно слить glibc и linux kernel в одно дерево исходных кодов, и объявить что между релизами бинарная совместимость не гарантируется. В OpenBSD, например, так и сделано, и вроде всё ок. Проприетарный софт не работает, но проблемы негров шериф^WТео вроде не особо волнуют.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

слить glibc и linux kernel в одно дерево исходных кодов

Когда поставляют голое ядро, а не ось целиком, выходит одно недоразумение, это же очевидно.

объявить что между релизами бинарная совместимость не гарантируется

Ога, я между 3.4 и 3.6 драгонфлаем все пакеты пересобирал

stopitplease
()
Ответ на: комментарий от stopitplease

Когда поставляют голое ядро, а не ось целиком, выходит одно недоразумение, это же очевидно.

Никто ж не запрещает сборку отдельно ядра или отдельно libc. Зато, если у них будет общий код - хотя бы те же хидеры с объявлениями структур и констант, подобные этому баги будет исправить куда проще.

Ога, я между 3.4 и 3.6 драгонфлаем все пакеты пересобирал

Пересобрал? Пересобрал. Работает? Работает. Не вижу проблемы (у меня просто Gentoo).

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Пересобрал? Пересобрал. Работает? Работает. Не вижу проблемы (у меня просто Gentoo).

Долговато. Так что жена Торвыльдса немного права. Но совсем немного

stopitplease
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.