Pourquoi la bibliothèque compilée sur deux machines légèrement différentes se comporte-t-elle légèrement différentes?

StackOverflow https://stackoverflow.com/questions/1268101

Question

Voici la configuration:

Mon collègue a une machine Fedora X64_86 avec un compilateur croisé GCC 4.3.3 (de Buildroot). J'ai une machine Ubuntu 9.04 X64_86 avec le même compilateur croisé.

Mon collègue a construit une application de bibliothèque + test qui fonctionne sur une machine de test, j'ai compilé la même bibliothèque et TestApp et il se bloque sur la même machine de test.

Pour autant que je sache, GCC construit contre UCLIBC compilé compilé à Buildroot, donc, même code, même compilateur. Quels types de différences de machines hôtes auraient un impact sur la compilation croisée?

Tout aperçu apprécié.

MISE À JOUR: Pour clarifier, les compilateurs sont identique. Le code source de la bibliothèque et de TestApp est identique. La seule différence est que le testapp + lib a été compilé sur différentes machines.

Était-ce utile?

La solution

Si votre code se bloque (je suppose que vous obtenez un sigsegv), il semble y avoir un bogue. C'est probablement une sorte de comportement non défini, comme utiliser un pointeur pendant ou écrire sur une limite de tampon.

Le point malheureux d'un comportement indéfini est qu'il peut travailler sur certaines machines. Je pense que vous vivez un tel événement ici. Essayez de trouver le bug et vous saurez ce qui se passe :-)

Autres conseils

De quelle manière cela se bloque-t-il? Pouvez-vous être plus précis, fournir des sorties, des codes de retour, etc ... Avez-vous essayé de brancher certains printf () utiles?

Et, je pense que nous avons besoin de plus de détails ici:

  1. Le lien TestApp vers la bibliothèque?

  2. La bibliothèque est-elle statique ou dynamique?

  3. La bibliothèque est-elle dans le chemin de recherche de la bibliothèque, ou avez-vous ajouté son répertoire à ld.so.conf?

  4. Suivez-vous des procédures d'installation pour la bibliothèque et TestApp?

  5. Les deux bibliothèques et TestApps Bit-for-Bit sont-ils compatibles? Vous attendez-vous à ce qu'ils soient?

  6. Utilisez-vous le même utilisateur que votre collègue, avec le même environnement et les mêmes autorisations?

Évidemment, quelque chose n'est pas identique.

Essayez d'utiliser Objdump et ses nombreuses options, en particulier -D, pour déterminer ce qui est différent.

Vous n'en avez pas fait un point, donc je vais deviner que les binutilles sont la différence. C'est l'ensemble des outils utilisés dans la construction de binaires. Il comprend LD, AS et Objdump.

Les compilateurs croisés ont besoin de leur propre ensemble de binutilles pour l'architecture cible. Cependant, contrairement à GCC, je ne pense pas que les outils de binutils fassent une construction à double bootstrap et vérifient l'étape, il est donc possible qu'une certaine différence par rapport à l'environnement de construction X86_64 d'origine y ait fait.

J'essaierais de construire à nouveau les packages Binutils pour ARM, en utilisant le CrossCompiler ARM. Voyez si cela fait une différence.

C'est quelque chose que j'ai vu dans les installations régulières de X86 Gentoo Stage1: Après avoir installé le système et les compilateurs de bootstrap installés et mis à jour, un utilisateur de Gentoo est bien recommandé pour reconstruire le système encore en utilisant les outils mis à jour.

Quelle est votre cible (la machine de test)?

Utilisez-vous les compilateurs fournis en distribution? Ils ont généralement un ensemble assez important de patchs appliqués au GCC, par exemple sur Gentoo, il y a environ 20 patchs, Fedora et Ubuntu ne seront pas si différents. Cependant, tous les correctifs ne sont pas bons à 100% :-( afin que les compilateurs puissent en réalité différer.

Vous pouvez rechercher une version "Vanilla" de GCC sur votre distribution, peut-être qu'il fait l'affaire.

Je connaissais quelqu'un qui avait une expérience similaire à l'université. Fondamentalement, dans un laboratoire de machines identiques, son projet a travaillé sur sa boîte de développement, mais s'est horriblement écrasé sur la boîte des professeurs. C'étaient deux machines qui étaient le même arc, exécutant la même version du système d'exploitation.

Il se résumait quelque part à un pointeur non initialisé.

Il avait du code qui ressemblait à:

if(p == NULL) {
    p = f();
}

Étant donné que P était membre d'une classe qui a été allouée sur le tas, sa valeur était effectivement aléatoire et était parfois nul, faisant que la chose fonctionne bien ... le problème était que quelquefois et sur quelques Machines, la mémoire de P était nul sur le démarrage du programme, mais sur la boîte du professeur, ce n'était pas le cas. Le correctif était bien sûr pour initialiser correctement P TP NULL et tout allait bien.

Vous ressentez peut-être quelque chose comme ça. Ou un type de comportement non défini Ce qui est une façon sophistiquée de dire "cela peut ou non fonctionner comme prévu pour une raison ou pas du tout"

En tant que coup de couteau dans l'obscurité, je rechercherais des variables non initialisées. Assurez-vous que toutes les variables locales et globales se voient attribuer une valeur. Vérifiez que les constructeurs ont des initialiseurs pour tous les membres de données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top