Если опция сборки GCC с '-mms-bitfields', значение 'epoll_event.data.u64' может быть усечено до 4-байтового значения через 'epoll_wait' - PullRequest
0 голосов
/ 21 сентября 2018

Если опция сборки GCC с -mms-bitfields, значение epoll_event.data.u64 может быть усечено до 4-байтового значения с помощью epoll_wait.

У меня есть пример для сервера сокетов, использующего epoll и Iочень странно, когда я делаю ставку с -mms-bitfields, я не могу получить оригинальное 8-байтовое значение в epoll_event.data.u64.Я не знаю, почему, и могу ли я как-то это исправить?

Код следующий:

...
    {
        epoll_event ev;
        ev.events = EPOLLIN | EPOLLET;

        ev.data.u64 = 0x123456789abcdef0;

        printf("epoll_ctl add:size=%ld, ptr=%p, u64=%lu\n", sizeof(ev.data.ptr), ev.data.ptr, ev.data.u64);

        nRetCode = epoll_ctl(nEpollHandle, EPOLL_CTL_ADD, nSocket, &ev);
        printf("epoll_ctl retcode=%d\n", nRetCode);
        SOCKET_JMP_ERROR(nRetCode >= 0);
    }

    // test wait
    {
        int nRetCount = 0;
        int nRemainEventCount = 1;
        epoll_event EpollEvent;
        epoll_event * pEpollEvent = &EpollEvent;

        nRetCount = epoll_wait(nEpollHandle, pEpollEvent, nRemainEventCount, 0);
        printf("epoll_wait nRetCount=%d\n", nRetCount);
        SOCKET_JMP_ERROR(nRetCount >= 0);

        printf("epoll_wait wait:size=%ld, ptr=%p, u64=%lu\n", sizeof((pEpollEvent->data).ptr), (pEpollEvent->data).ptr, (pEpollEvent->data).u64);

    }
...

И сборка без -mms-bitfields, вывод сообщения такой:

epoll_ctl add:size=8, ptr=0x123456789abcdef0, u64=1311768467463790320
epoll_ctl retcode=0
epoll_wait nRetCount=1
epoll_wait wait:size=8, ptr=0x123456789abcdef0, u64=1311768467463790320

Если опция сборки с -mms-bitfields, сообщение:

epoll_ctl add:size=8, ptr=0x123456789abcdef0, u64=1311768467463790320
epoll_ctl retcode=0
epoll_wait nRetCount=1
epoll_wait wait:size=8, ptr=0x9abcdef0, u64=2596069104

Это версия GCC gcc -v:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-linux/4.8.5/lto-wrapper
Target: x86_64-linux
Configured with: ../configure -build=x86_64-linux -enable-checking=release -enable-languages=c,c++ -disable-multilib --with-gmp --with-mpfr --with-mpc
Thread model: posix
gcc version 4.8.5 (GCC)

Тогда ОСCentOS 6.5:

Linux version 2.6.32-431.el6.x86_64 (mockbuild@c6b8.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Nov 22 03:15:09 UTC 2013

Может кто-нибудь объяснить эту проблему, пожалуйста?Спасибо ....

1 Ответ

0 голосов
/ 21 сентября 2018

-mms-bitfields изменяет способ размещения структур и в некоторых случаях может привести к несовместимости структур, определенных в системных заголовках, с вашей системной библиотекой ABI.Скорее всего, это причина того, что epoll ведет себя некорректно, когда используется * 1003. *

При компиляции 32-битного кода вы можете применить структуру структуры MS к отдельным структурам, используя __attribute__((ms_struct)), что может бытьлучший путь вперед, например:

#include <stdio.h>

struct a
{
  short a :16;
  int   : 0;
  short b :16;
} __attribute__((ms_struct)) aa;

int main()
{
  printf("sizeof struct a = %d\n", (int)sizeof(struct a));
  printf("sizeof aa = %d\n", (int)sizeof(aa));
  return 0;
}

Это печатает:

sizeof struct a = 8
sizeof aa = 8

Без __attribute__((ms_struct)) (и без -mms-bitfields) вместо этого он сообщает размер 6.

...