Question

Nous utilisons un compilateur héritage, basé sur gcc 2.6.0, pour une compilation croisée pour un vieux processeur incrustée nous utilisons toujours (oui, il est encore en usage depuis 1994!). L'ingénieur qui a fait le port gcc pour cette puce a depuis longtemps évolué. Bien que nous pourrions être en mesure de récupérer la source gcc 2.6.0 de quelque part sur le web, le jeu de changement pour cette puce a disparu dans les couloirs de l'histoire de l'entreprise. Nous avons embrouillé le long jusqu'à récemment que le compilateur a couru encore et produit executables réalistes, mais à partir du noyau linux 2.6.25 (et 2.6.26), il échoue avec le message gcc: virtual memory exhausted ... même lorsqu'il est exécuté sans paramètre ou avec seulement -v . J'ai redémarré mon système de développement (à partir 2.6.26) en utilisant le noyau 2.6.24 et le compilateur fonctionne à nouveau (avec le redémarrage 2.6.25 ne fonctionne pas).

Nous avons un système que nous gardons à 2.6.24 juste pour le but de faire construit pour cette puce, mais se sentent un peu exposée au cas où le monde linux passe au point que nous ne pouvons plus longtemps reconstruire un système qui exécutera le compilateur (ie notre système 2.6.24 meurt et nous ne pouvons pas obtenir 2.6.24 pour installer et exécuter sur un nouveau système, car certaines des parties de logiciels ne sont plus disponibles).

Est-ce que quelqu'un a des idées pour ce que nous pourrions être en mesure de le faire à une installation plus moderne pour obtenir ce compilateur héritage à exécuter?

Modifier :

Pour répondre à certains des commentaires ...

Malheureusement, ce sont les changements de code source qui sont spécifiques à notre puce qui sont perdus. Cette perte a eu lieu sur deux grandes reorgs de l'entreprise et plusieurs administrateurs système (deux ou trois qui a vraiment laissé un gâchis). Nous utilisons maintenant le contrôle de configuration, mais ferme la porte de la grange trop tard pour ce problème.

L'utilisation d'une machine virtuelle est une bonne idée, et peut-être ce que nous finissons par faire. Je vous remercie de cette idée.

Enfin, j'ai essayé strace comme ephemient suggéré et a constaté que le dernier appel système a été BRK () qui a renvoyé une erreur sur le nouveau système (noyau 2.6.26) et retourné succès sur l'ancien système (noyau 2.6.24). Cela indiquerait que je suis vraiment à court de mémoire virtuelle, sauf que tcsh « limite » renvoie les mêmes valeurs sur les systèmes anciens et nouveaux, et / proc / meminfo montre les nouveaux systèmes a un peu plus de mémoire et un peu plus d'espace d'échange. Peut-être qu'il est un problème de fragmentation ou lorsque le programme est en cours de chargement?

Je l'ai fait quelques recherches et « randomization BRK » a été ajouté dans le noyau 2.6.25, mais CONFIG_COMPAT_BRK est censé être activé par défaut (ce qui désactive randomization BRK).

Modifier :

OK, plus d'informations: Il ressemble vraiment randomization BRK est le coupable, l'héritage gcc appelle BRK () pour changer la fin du segment de données et qui ne maintenant, ce qui provoque l'gcc héritage à signaler « mémoire virtuelle épuisée ». Il existe quelques moyens documentés pour désactiver randomization BRK:

  • sudo echo 0 > /proc/sys/kernel/randomize_va_space

  • sudo sysctl -w kernel.randomize_va_space=0

  • Démarrage d'une nouvelle coque avec setarch i386 -R tcsh (ou "-R -L")

Je les ai essayé et ils semblent avoir un effet en ce que la valeur de retour BRK () est différent (et toujours le même) que sans eux (essayé à la fois le noyau 2.6.25 et 2.6.26), mais le BRK () échoue encore si le gcc héritage ne parvient toujours pas :-(.

En outre, j'ai mis vm.legacy_va_layout=1 et vm.overcommit_memory=2 sans changement, et je l'ai redémarré avec les paramètres de vm.legacy_va_layout=1 et kernel.randomize_va_space=0 enregistrés dans /etc/sysctl.conf. Toujours pas de changement.

Modifier :

Utilisation kernel.randomize_va_space=0 sur le noyau 2.6.26 (et 2.6.25) les résultats de l'appel étant rapporté par strace legacy-gcc BRK () suivant:

brk(0x80556d4) = 0x8056000

Ceci indique la BRK () a échoué, mais il semble que cela a échoué car le segment de données se termine déjà au-delà de ce qui a été demandé. En utilisant objdump, je peux voir le segment de données devrait se terminer à 0x805518c alors que le BRK a échoué () indicates que le segment de données se termine actuellement à 0x8056000:

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  080480d4  080480d4  000000d4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .hash         000001a0  080480e8  080480e8  000000e8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .dynsym       00000410  08048288  08048288  00000288  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynstr       0000020e  08048698  08048698  00000698  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .rel.bss      00000038  080488a8  080488a8  000008a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .rel.plt      00000158  080488e0  080488e0  000008e0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .init         00000008  08048a40  08048a40  00000a40  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  7 .plt          000002c0  08048a48  08048a48  00000a48  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  8 .text         000086cc  08048d10  08048d10  00000d10  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  9 .fini         00000008  080513e0  080513e0  000093e0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .rodata       000027d0  080513e8  080513e8  000093e8  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 11 .data         000005d4  08054bb8  08054bb8  0000bbb8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 12 .ctors        00000008  0805518c  0805518c  0000c18c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 13 .dtors        00000008  08055194  08055194  0000c194  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 14 .got          000000b8  0805519c  0805519c  0000c19c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 15 .dynamic      00000088  08055254  08055254  0000c254  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .bss          000003b8  080552dc  080552dc  0000c2dc  2**3
                  ALLOC
 17 .note         00000064  00000000  00000000  0000c2dc  2**0
                  CONTENTS, READONLY
 18 .comment      00000062  00000000  00000000  0000c340  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
no symbols

Modifier :

Pour faire écho à la remarque de ephemient ci-dessous: « si étrange pour traiter GCC comme binaire sans source »

Ainsi, en utilisant strace, objdump, gdb et ma compréhension limitée de 386 assembleur et l'architecture que j'ai tracé le problème au 1er appel malloc dans le code existant. Les appels gcc héritage malloc, qui renvoie NULL, qui se traduit par le message « mémoire virtuelle épuisé » sur stderr. Ce malloc est en libc.so.5, et il appelle getenv un tas de fois et finit par BRK () appelle ... Je suppose que d'augmenter le tas ... qui échoue.

De cela, je ne peux que supposer que le problème est plus randomization BRK, ou je n'ai pas randomization BRK totalement invalide, malgré les randomize_va_space = 0 et legacy_va_layout = 1 paramètres sysctl.

Était-ce utile?

La solution

Installer linux + l'ancien gcc sur une machine virtuelle.

Autres conseils

Avez-vous des sources pour ce compilateur personnalisé? Si vous pouvez récupérer la ligne de base 2.6.0 (et qui devrait être relativement facile), puis diff et patch devrait récupérer votre jeu de changement.

Qu'est-ce que je recommande donc utilise ce changement pour construire une mis en nouvelle version contre à jour gcc. ET PUIS METTEZ SOUS CONTRÔLE DE CONFIGURATION.

Désolé, ne signifie pas crier. Il est juste que j'ai dit la même chose pour la plupart de 30 ans.

Pouvez-vous strace l'exécutable gcc-2.6.0? Il peut faire quelque chose comme la lecture /proc/$$/maps, et se confondre lorsque les changements de sortie de manière insignifiante. Un problème similaire était récemment remarqué entre 2.6.28 et 2.6.29.

Si oui, vous pouvez pirater /usr/src/linux/fs/proc/task_mmu.c ou à peu près à restaurer l'ancienne sortie, ou mettre en place une $LD_PRELOAD à gcc faux dans la lecture d'un autre fichier.

Modifier

Puisque vous avez mentionné brk ...

CONFIG_COMPAT_BRK rend le kernel.randomize_va_space=1 par défaut au lieu de 2, mais encore tout autre randomizes que le tas (brk).

Voyez si votre problème disparaît si vous echo 0 > /proc/sys/kernel/randomize_va_space ou sysctl kernel.randomize_va_space=0 (équivalent).

Si, ajoutez kernel.randomize_va_space = 0 à /etc/sysctl.conf ou ajouter norandmaps à la ligne de commande du noyau (équivalent), et être heureux à nouveau.

Je suis tombé sur cette et pensé à votre problème . Peut-être que vous pouvez trouver un moyen de jouer avec le binaire pour le déplacer vers le format ELF? Ou peut-être il est hors de propos, mais jouer avec objdump peut vous fournir plus d'informations.

Pouvez-vous jeter un oeil à la carte mémoire du processus?

Je travaille quelque chose ... ce n'est pas une solution complète, mais il ne se passé le problème d'origine, j'ai eu avec le gcc héritage.

Mettre des points d'arrêt à chaque appel libc dans le .plt (tableau de liaison de procédure) Je vois que malloc (en libc.so.5) appelle getenv () pour obtenir:

    MALLOC_TRIM_THRESHOLD_
    MALLOC_TOP_PAD_
    MALLOC_MMAP_THRESHOLD_
    MALLOC_MMAP_MAX_
    MALLOC_CHECK_

Je web et a trouvé ces cherchai cette qui a conseillé

    setenv MALLOC_TOP_PAD_ 536870912

alors le gcc héritage WORKS !!!!

Mais pas à la maison libre, il se leva sur le lien dans la construction avant d'échouer, donc il y a quelque chose d'aller plus loin avec la NLD, nous avons :-( héritage Il rapporte:

    Virtual memory exceeded in `new'

Dans /etc/sysctl.conf je:

    kernel.randomize_va_space=0
    vm.legacy_va_layout=1

Il fonctionne toujours le même si

    kernel.randomize_va_space=1
    vm.legacy_va_layout=0

mais pas si

kernel.randomize_va_space=2

Il a été suggéré d'utiliser « ldd » pour voir les dépendances des bibliothèques partagées:.. Gcc héritage n'a besoin que libc5, mais le NLD héritage doit également libg ++ so.27, libstdc ++ so.27, et libm.so.5 apparemment, il y a une version libc5 de libg ++. so.27 (libg ++ 27 altdev ??) Qu'en est-libc5-compat?

Alors, comme je le disais, pas encore la maison sans ... se rapprocher. Je vais probablement poster une nouvelle question sur le problème NLD.

Modifier :

J'allais d'abord à ne pas « accepter » cette réponse car il me reste encore un problème avec l'éditeur de liens existants correspondant, mais pour obtenir une finalité sur cette question au moins, je repense cette position.

Merci-toi aller vers:

  • an0nym0usc0ward pour la suggestion d'utiliser une machine virtuelle (qui peut finalement devenir la réponse acceptée)
  • ephemient pour suggérer en utilisant strace, et aider à l'utilisation stackoverflow
  • shodanex pour suggérer à l'aide objdump

Modifier

Voici la dernière des choses que j'ai appris, et maintenant je vais accepter la solution VM puisque je ne pouvais pas résoudre pleinement d'une autre manière (au moins dans le temps imparti pour cela).

Les nouveaux noyaux ont un drapeau de construction de CONFIG_COMPAT_BRK pour permettre libc5 à utiliser, on peut donc supposer la construction d'un nouveau noyau avec ce drapeau va résoudre le problème (et en regardant à travers le src du noyau, il semble que ce sera, mais je ne peux pas être sûr puisque je ne l'ai pas suivi tous les chemins). Il y a aussi une autre façon documentée pour permettre l'utilisation libc5 lors de l'exécution (plutôt que lors de la compilation du noyau): sudo sysctl -w kernel.randomize_va_space = 0. Cela fait cependant pas faire un travail complet et certains (la plupart?) des applications libc5 vont encore se briser, par exemple notre compilateur héritage et éditeur de liens. Cela semble être dû à une différence dans les hypothèses d'alignement entre les nouveaux noyaux et plus. J'ai patché le binaire éditeur de liens pour faire croire qu'il a une plus grande section bss, afin d'amener la fin de la bss jusqu'à une limite de page, et cela fonctionne sur le nouveau noyau lorsque le sysctl var kernel.randomize_va_space = 0. Ce n'est pas une solution satisfaisante pour moi depuis que je suis ragréage à l'aveuglette un exécutable binaire critique, et même si l'exécution de l'éditeur de liens patché sur le nouveau noyau produit une sortie identique bit à la piste de liaison d'origine sur le noyau plus ancien, qui ne prouve pas que une autre entrée de liaison (autrement dit, nous changeons le programme étant lié) produira également des résultats identiques.

Pouvez-vous pas simplement faire une image de disque qui peut être réinstallé si le système meurt? ou faire une machine virtuelle?

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