David Madore's WebLog: Je découvre encore un bug improbable

[Index of all entries / Index de toutes les entréesLatest entries / Dernières entréesXML (RSS 1.0) • Recent comments / Commentaires récents]

↓Entry #2221 [older| permalink|newer] / ↓Entrée #2221 [précédente| permalien|suivante] ↓

(mercredi)

Je découvre encore un bug improbable

Ayant installé de nouveaux disques durs dans le PC chez mes parents, je fais ce que je fais régulièrement, à savoir compiler un Firefox. La compilation échoue sur quelque chose que je ne comprends pas du tout :

pleiades david /usr/local/src/mozilla/obj-i686-pc-linux-gnu/intl/icu/target/data $ LD_LIBRARY_PATH=../lib:../stubdata:../tools/ctestfw:$LD_LIBRARY_PATH ../bin/genrb -k -R -i ./out/build/icudt52l -s /hugetmp/mozilla/intl/icu/source/data/coll -d ./out/build/icudt52l/coll root.txt
/hugetmp/mozilla/intl/icu/source/data/coll/root.txt:15: Collation could not be built- U_FILE_ACCESS_ERROR. Make sure ICU's data has been built and is loading properly.
/hugetmp/mozilla/intl/icu/source/data/coll/root.txt:15: parse error. Stopped parsing resource with U_FILE_ACCESS_ERROR
couldn't parse the file root.txt. Error:U_FILE_ACCESS_ERROR

Comme tout bon Unixien confronté à un comportement bizarre d'un programme qu'il ne connaît même pas, j'ai le réflexe strace. Et là, les choses deviennent encore plus mystérieuses :

pleiades david /usr/local/src/mozilla/obj-i686-pc-linux-gnu/intl/icu/target/data $ strace -f -o /tmp/dump -E LD_LIBRARY_PATH=../lib:../stubdata:../tools/ctestfw:$LD_LIBRARY_PATH ../bin/genrb -k -R -i ./out/build/icudt52l -s /hugetmp/mozilla/intl/icu/source/data/coll -d ./out/build/icudt52l/coll root.txt
strace: ../bin/genrb: command not found

Comment ça, command not found ? Je n'ai aucune idée de ce que le programme ../bin/genrb est censé faire, mais je suis sûr qu'il existe et qu'il s'exécute correctement. Pourquoi strace prétend-il ne pas pouvoir le trouver ?

Et pourquoi le fait d'avoir changé les disques durs de ma machine ferait-il échouer la compilation de Firefox ?

Je vous épargne la manière dont j'ai résolu le mystère (j'ai commencé par strace strace lui-même, qui ne m'a montré aucune erreur, ce qui rendait les choses encore plus incompréhensible, et j'ai fini par patcher le truc pour afficher la valeur de errno). Le secret était que la partition /hugetmp sur laquelle je compilais faisait plus de 2To, et que j'y avais mis un système de fichier XFS. Or pour les gros systèmes de fichiers, XFS utilise des numéros d'inodes de plus que 32-bits. Mon noyau est 64-bits, donc lui n'a pas de problème avec ça, mais sur cette machine j'ai un userland de 32-bits : dans ces conditions, tout dépend de si le programme a été compilé avec -D_FILE_OFFSET_BITS=64 ou non : si ce n'est pas le cas (ce qui, apparemment, vaut pour le strace de ma Debian comme pour le programme qui échouait en premier lieu), lorsque stat() est appelé sur un fichier et qu'un des champs de la structure de retour (typiquement, la taille, ou le numéro d'inode) dépasse le type 32-bits que la structure prévoit, alors la libc produit l'erreur EOVERFLOW (qui n'apparaît pas dans le strace du strace parce que ce n'est pas le noyau qui la renvoie, c'est la libc) ; et si on se contente de regarder si stat() a réussi ou pas, on a l'impression que le fichier n'existe pas ou qu'il y a une erreur d'accès.

Moralité :

  • Tous les programmes, sur un système 32-bits, devraient être compilés avec -D_FILE_OFFSET_BITS=64 (ou en tout cas, tous ceux qui utilisent stat(), c'est-à-dire, essentiellement, tous les programmes). Ne pas le faire va provoquer les erreurs les plus bizarres et inattendues. Même si on ne manipule pas des fichiers de plus de 2Go (qui sont la cause la plus courante de EOVERFLOW).
  • Si on veut utiliser des partitions XFS de plus de 1To sur un système qui risque de faire tourner des programmes 32-bits, on a intérêt à augmenter la taille des inodes (passer à 512 bits à partir de 1To, à 1024 bits à partir de 2To, etc. ; au-delà de 8To, on ne peut plus s'en sortir). Ce n'est pas très satisfaisant, cela fera perdre de la place, mais à moins de vouloir résoudre les bugs (i.e., la non-application du premier point) de la moitié de la distribution, il faudra bien faire un choix.

Noter que contrairement à ce que prétend la doc (if no inode size is given on the command line, mkfs.xfs will attempt to choose a size such that inode numbers will be < 32 bits. If an inode size is specified, or if a filesystem is sufficently large, mkfs.xfs will warn if this will create inode numbers > 32 significant bits), mkfs.xfs n'a, lorsque j'ai créé le système de fichiers, ni choisi une taille d'inode suffisante pour rester avec des numéros d'inode de 32-bits, ni affiché d'avertissement.

↑Entry #2221 [older| permalink|newer] / ↑Entrée #2221 [précédente| permalien|suivante] ↑

[Index of all entries / Index de toutes les entréesLatest entries / Dernières entréesXML (RSS 1.0) • Recent comments / Commentaires récents]