2009-08-12 9 views
3

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

Mon collègue a une machine Fedora x64_86 avec un compilateur croisé gcc 4.3.3 (à partir 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 test de bibliothèque + qui fonctionne sur une machine de test, j'ai compilé la même bibliothèque et testapp et il plante sur la même machine de test.

Pour autant que je sache, gcc est construit avec ucLibc compilé par buildroot, donc, même code, même compilateur. Quels types de différences de machines hôtes auraient une incidence sur la compilation croisée?

Un aperçu apprécié.

Mise à jour: Pour clarifier, les compilateurs sont identiques. Le code source pour la bibliothèque et testapp est identique. La seule différence est que testapp + lib a été compilé sur des machines différentes.

+0

Il est difficile de savoir sans être en mesure d'inspecter les machines ou le code. Pouvez-vous nous parler de la nature de l'accident? Quel type d'accident est-ce? Cela se passe-t-il dans votre code ou dans une bibliothèque qui en dépend? –

+0

Si tout est identique, à quel point les fichiers de sortie sont-ils différents? –

+0

Comment ça s'est passé, avez-vous trouvé le problème? – Johan

Répondre

6

Si votre code plante (je suppose que vous obtenez un sigsegv), il semble y avoir un bug. Il s'agit probablement d'un comportement indéfini, comme l'utilisation d'un pointeur suspendu ou l'écriture sur une limite de tampon.

Le point malencontreux du comportement indéfini est que peut fonctionner sur certaines machines. Je pense que vous rencontrez un tel événement ici.Essayez de trouver le bogue et vous saurez ce qui se passe :-)

+0

Juste pour clarifier, c'est le code _same_, qui a été compilé sur deux machines différentes avec le même compilateur. Il se comporte différemment cependant. – EightyEight

+5

Cela ne contredit pas ce que dit ebo. Un comportement indéfini n'est pas défini et peut être affecté par absolument n'importe quoi, par ex. versions légèrement différentes des bibliothèques dynamiques que le compilateur utilise sur différents systèmes d'exploitation. Je parierais de l'argent que ce bug est ramené à un comportement indéfini. –

+1

C'est exactement ce à quoi ressemble un comportement non défini. –

1

Quelle est votre cible (la machine de test)?

Utilisez-vous les compilateurs fournis par la distribution? Ils ont généralement un assez grand nombre de patches appliqués à gcc, par exemple sur gentoo il y a environ 20 patches, fedora et ubuntu ne seront pas si différents. Tous les correctifs sont 100% bien, mais :-( Ainsi, les compilateurs peuvent différer en réalité.

Vous pouvez rechercher une version « vanille » de gcc sur votre distribution, peut-être le tour est joué.

+0

L'arc cible est le bras Le code est compilé avec un compilateur identique fourni par buildroot – EightyEight

3

Pouvez-vous être plus précis, fournir une sortie, des codes de retour, etc ... Avez-vous essayé de brancher quelques printf() utiles?

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

  1. Est-ce que testapp est lié à la bibliothèque? ?

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

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

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

  5. Les deux bibliothèques et testapps sont-elles compatibles bit à bit? Voulez-vous qu'ils soient? Exécutez-vous en tant que le même utilisateur que votre collègue, avec le même environnement et les mêmes autorisations?

+0

L'application se bloque avec un segfault.Je ne sais pas si c'est intéressant, je suis plus intéressé à comprendre d'où vient cette différence. 1. Oui, les liens d'application vers la bibliothèque. 2. C'est une bibliothèque partagée. 3. La bibliothèque est trouvée via LD_LIBRARY_PATH 4. J'ai compilé la bibliothèque et testapp et je l'ai laissé dans leurs répertoires d'origine. 5. Je ne suis pas sûr de savoir ce que signifie bit pour peu compatible. Ils sont compilés pour la même arche, le même compilateur. 6. Oui, il s'agit d'un périphérique intégré, donc je cours en tant que root. – EightyEight

+0

Doh, désolé pour le formatage moche. – EightyEight

+1

Avez-vous utilisé ldd pour vous assurer que les deux testapps sont liés aux mêmes bibliothèques sur la cible? Je ne suis pas sûr de ce que vous voulez dire sur pt. 4. Quels sont les répertoires originaux? Etant donné qu'il s'agit d'une cible croisée, vous devez compiler sur une machine et la déployer sur la cible (machine de test). Déployez-vous exactement de la même manière que votre collègue? –

3

É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'avez pas insisté, alors je vais deviner que binutils fait la différence. C'est l'ensemble des outils utilisés dans la construction des binaires. Il inclut ld, as et objdump.

Les compilateurs croisés ont besoin de leur propre ensemble de binutils pour l'architecture cible. Cependant, contrairement à GCC, je ne crois pas que les outils binutils effectuent une étape de construction et de vérification à double bootstrap, il est donc possible qu'une différence par rapport à l'environnement de construction x86_64 original l'ait fait.

Je tenterais à nouveau de construire les paquets binutils pour ARM, en utilisant le compilateur ARM. Voyez si cela fait une différence.

Il est quelque chose que je l'ai vu dans stage1 Gentoo régulière x86 installe aussi: après avoir obtenu le système d'amorçage et compilateurs installés et mis à jour, un utilisateur Gentoo est bien recommandé de reconstruire le système à nouveau en utilisant les outils mis à jour.

+0

Les binutils sont identiques sur les deux machines car ils ont été compilés par buildroot. Note intéressante sur la recompilation des outils, merci. – EightyEight

1

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 effondré horriblement sur la boîte des professeurs. C'étaient deux machines qui étaient la même arche, exécutant la même version de l'OS.

Il s'est réduit jusqu'à un pointeur non initialisé quelque part.

Il avait un code qui ressemblait à:

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

Puisque p était membre d'une classe qui a été alloué sur le tas, sa valeur était effectivement aléatoire et parfois était NULL fait, ce qui rend chose fonctionne bien. Le problème était que parfois et sur certaines machines, la mémoire pour p était NULL au démarrage du programme, mais sur la boîte du prof, ce n'était pas le cas. Le correctif était bien sûr d'initialiser correctement p tp NULL et tout allait bien.

Vous rencontrez peut-être quelque chose comme ça. Ou un certain type de comportement non défini qui est une façon élégante de dire « il peut ou peut ne pas fonctionner comme prévu pour toute raison du tout »

1

Comme un coup de poignard dans le noir, je cherche des variables non initialisées . Assurez-vous qu'une valeur est affectée à toutes les variables locales et globales. Vérifiez que les constructeurs ont des initialiseurs pour TOUS les membres de données.

Questions connexes