Menu

libaal build error

BratSinot
2017-10-23
2017-11-21
  • BratSinot

    BratSinot - 2017-10-23

    With GCC 7.2.0 and glibc-2.26 build fails.
    In file include/aal/types.h declaration from 29 to 45 line conflict with stdint.h from C99, because #ifndef __int8_t_defined check not work.

    libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -D_REENTRANT -D_FILE_OFFSET_BITS=64 -O3 -W -Wall -Wuninitialized -Wno-unused-parameter -Wredundant-decls -MT libaal_la-list.lo -MD -MP -MF .deps/libaal_la-list.Tpo -c list.c -o libaal_la-list.o >/dev/null 2>&1
    mv -f .deps/libaal_la-list.Tpo .deps/libaal_la-list.Plo
    /bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include   -D_REENTRANT -D_FILE_OFFSET_BITS=64 -O3 -W -Wall -Wuninitialized -Wno-unused-parameter -Wredundant-decls -MT libaal_la-malloc.lo -MD -MP -MF .deps/libaal_la-malloc.Tpo -c -o libaal_la-malloc.lo `test -f 'malloc.c' || echo './'`malloc.c
    libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -D_REENTRANT -D_FILE_OFFSET_BITS=64 -O3 -W -Wall -Wuninitialized -Wno-unused-parameter -Wredundant-decls -MT libaal_la-malloc.lo -MD -MP -MF .deps/libaal_la-malloc.Tpo -c malloc.c  -fPIC -DPIC -o .libs/libaal_la-malloc.o
    In file included from /usr/include/sys/types.h:156:0,
                     from /usr/include/stdlib.h:279,
                     from malloc.c:15:
    /usr/include/bits/stdint-intn.h:27:19: error: conflicting types for 'int64_t'
     typedef __int64_t int64_t;
                       ^~~~~~~
    In file included from ../include/aal/libaal.h:17:0,
                     from malloc.c:6:
    ../include/aal/types.h:35:33: note: previous declaration of 'int64_t' was here
     typedef long long int           int64_t;
    
     
  • BratSinot

    BratSinot - 2017-11-10

    So, somewhere in the OpenSUSE mailing list, this problem was easily fixed by replacing typedef by stdint.h.

     
  • Edward Shishkin

    Edward Shishkin - 2017-11-11

    Great, we'll release libaal-1.0.7
    Thanks!

     
  • Edward Shishkin

    Edward Shishkin - 2017-11-18

    У меня (fedora 26, glibc-2.25, gcc-7.21) с этим патчем uint64_t определяется как unsigned long, т.е. 32 бита, что не есть хорошо. До меня glibc-2.26 пока ещё не докатилась, но, видать, надо будет это фиксить как-то по другому..

     
    • BratSinot

      BratSinot - 2017-11-19

      Это крайне странно, т.к. stdint.h гарантирует (точнее стандарт C99/C11) указанные размеры.
      В моем случае uint64_t определен как "typedef unsigned long long uint64_t;"
      Попробую на виртуальной машине Fedora'у поднять и посмотреть.

       

      Last edit: BratSinot 2017-11-19
  • Edward Shishkin

    Edward Shishkin - 2017-11-19

    Точнее, reiser4progs у меня при сборке флудит warnings-ами, что uint64_t, blk_t, и другие производные типы определены как long. Если таким fsck-еем почекать большой раздел, то беда будет..

     
    • BratSinot

      BratSinot - 2017-11-19

      Хм, странно, только что поставил Fedora 26 и никаких ошибок без патча и с патчем (предупреждений насчет типов тоже небыло).
      Как появится время перепроверю насчет multilib'а (принудительно указать -m32 / -m64), может проблема в нем.

       
    • BratSinot

      BratSinot - 2017-11-19

      Действительно, проблема проявляется только на glibc 2.26, в рассылках Debian'а тот-же патч что и в OpenSUSE, и в NixOS.
      Правда в них еще убирают макросы связанные с va и добавляют stdio.h.

      Как временный вариант можно добавить проверку на версию glibc.

       

      Last edit: BratSinot 2017-11-19
      • Edward Shishkin

        Edward Shishkin - 2017-11-20

        Ну, можно вставить compile-time проверку, что sizeof(blk_t) == 8. Подобное в ядре есть, тут тоже не помешает.

         
        • BratSinot

          BratSinot - 2017-11-20

          А можете лог сборки показать с патчем? А то так и не получилось подобные предупреждения поймать.

           
  • Edward Shishkin

    Edward Shishkin - 2017-11-20

    Да, конечно.

     
    • BratSinot

      BratSinot - 2017-11-20

      А, так это нормально, он ругается на %llu, а не на размер типа. Т.е. синтаксический анализатор проверяет по имени типа, а не размеру (по крайней мере в GCC, насчет clang и прочих не проверял).
      Например на amd64 следующий код:

      printf("%d %d\n", sizeof(uint64_t), sizeof(long unsigned int));
      

      выдаст "8 8", а на 32-х битной "8 4" (можете проверить собрав с флагами -m32 / -m64). В стандартах C все эти типы указаны как "at least", т.е. есть минимальный диапазон который они обязаны иметь, а сам размер не прописан.
      Только начиная с C99 появился заголовок stdint.h где типы конкретного размера 100% на любой платформе и компиляторе (если он стандарт поддерживает) будут иметь указанный размер.

      А что касается функций printf() / scanf(), то дополнительно появился заголовок inttypes.h, где есть макросы вида PRIu64 / SCNu64. Используются они как-то так:

          uint64_t a;
      
          scanf("%" SCNu64, &a);
          printf("%" PRIu64, a);
      

      Короче говоря в случае printf() проблем не будет.

       

      Last edit: BratSinot 2017-11-20
      • Edward Shishkin

        Edward Shishkin - 2017-11-20

        Да, действительно: я был уверен, что та машина - "8 4". Сейчас проверил - "8 8".
        Спасибо!

         
    • BratSinot

      BratSinot - 2017-11-20

      А если собирать с доп. флагом -Wconversion, то можно увидеть еще больше возможных ошибок. Например в коде много функций указаны не через XintN_t, а через обычные типы. Например misc_str2long() в "libreiser4/profile.c" возвращает тип long long и, соотвественно, вылазит много ошибок наподобие:

      busy.c:552:18: предупреждение: преобразование в «uint32_t {aka unsigned int}» из «long long int» может изменить значение [-Wconversion]
      ctx->blksize = misc_str2long(params[7], 0);

      Как вариант я могу по старому описанию в aal/types.h "прошерстить" libaal и reiser4progs, заменив все на XintN_t и в printf() на PRIxN. Правда если где-то undefined behaviour вылезет (или наоборот уйдет и из-за этого ошибка получится) непонятно как определить.

       

      Last edit: BratSinot 2017-11-20
      • Edward Shishkin

        Edward Shishkin - 2017-11-20

        Да, как-то стремновато. А если кто-нибудь на старой системе, где нет того заголовка, захочет новый релиз собрать? Давайте уж будем по-старинке явно приводить... ))

         
        • BratSinot

          BratSinot - 2017-11-20

          Ну вообще на неэкзотических компиляторах / системах как в types.h указано, так оно и есть. Т.е. тот-же int на -m32 / m64 занимает 4 байта (хотя в стандарте он вообще прописан как минимум 2 байта).
          Так что заместо вручную прописанных typedef, наверное имеет смысл таки использовать stdint.h и не трогать int / long long и прочие.
          По крайней мере когда в коде писалось uint64_t наверняка имелось в виду именно оно, а при сборке ошибок кроме printf() я не заметил.

           

          Last edit: BratSinot 2017-11-20
  • Edward Shishkin

    Edward Shishkin - 2017-11-20

    config.log

     
  • Edward Shishkin

    Edward Shishkin - 2017-11-20

    Против stdint.h ничего не имею. Я не хочу новомодные макросы для printf ))

     
  • Edward Shishkin

    Edward Shishkin - 2017-11-20

    То есть ваш патч мы приложим, я warning-сы я предлагаю фиксить явным приведением. Напр.: aal_error("Failed to read the block (%llu).", (unsigned long long) blk);

     
    • BratSinot

      BratSinot - 2017-11-20

      Насчет "новомодности" inttypes.h это громко сказано, стандарт то в 1999 году приняли. Так-что тот-же glibc без этого заголовка будет наверное времен libc.so.5 =)
      Явным приведением, так явным. Все равно это в printf(), наврятли там кто-то в fsck будет использовать format string injection. Как будет время подправлю все printf'ы.

       

      Last edit: BratSinot 2017-11-20
  • Edward Shishkin

    Edward Shishkin - 2017-11-21

    Я закоммитил в libaal всё что накопилось: https://github.com/edward6/libaal

     
    • BratSinot

      BratSinot - 2017-11-21

      А вот с приведением типов в printf() придется подождать. Прежупреждений там крайне много, быстро все не сделать.

       
  • Edward Shishkin

    Edward Shishkin - 2017-11-21

    Не, это оставьте, я сам сделаю. Спасибо!

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.