Domanda

Stiamo usando un compilatore eredità, sulla base di gcc 2.6.0, per attraversare compilare per un vecchio processore di piani integrati stiamo ancora usando (sì, è ancora in uso dal 1994!). L'ingegnere che ha fatto la porta gcc per questo chip è da tempo andato avanti. Anche se potremmo essere in grado di recuperare l'origine gcc 2.6.0 da qualche parte sul web, il set di cambiamento per questo chip ha scomparso nelle sale di storia aziendale. Abbiamo confuso insieme fino a poco tempo come il compilatore ancora correva e prodotto eseguibili praticabili, ma a partire dal kernel Linux 2.6.25 (e anche 2.6.26) non riesce con il messaggio gcc: virtual memory exhausted ... anche quando eseguito senza parametri o solo con -v . Ho ripartito il mio sistema di sviluppo (dal 2.6.26) usando il kernel 2.6.24 e il compilatore funziona di nuovo (riavvio con 2.6.25 non fa).

Abbiamo un sistema che stiamo mantenendo al 2.6.24 solo per lo scopo di fare costruisce per questo chip, ma si sentono un po 'esposto nel caso in cui il mondo Linux si muove al punto che non possiamo più ricostruire un sistema che verrà eseguito il compilatore (ad esempio il nostro sistema 2.6.24 muore e non possiamo ottenere 2.6.24 per installare ed eseguire su un nuovo sistema, perché alcune delle parti del software non sono più disponibili).

Qualcuno ha qualche idea per quello che potremmo essere in grado di fare per un impianto più moderno per ottenere questo compilatore eredità di correre?

Modifica :

Per rispondere ad alcune delle commenti ...

Purtroppo sono le modifiche al codice sorgente che sono specifici per il nostro chip che si perdono. Questa perdita si è verificato più di due importanti reorgs aziendali e diversi amministratori di sistema (un paio di che in realtà lasciato un pasticcio). Ora usiamo controllo della configurazione, ma che sta chiudendo la porta della stalla troppo tardi per questo problema.

L'uso di una VM è una buona idea, e può essere ciò che si finisce per fare. Grazie per questa idea.

Infine, ho provato strace come ephemient suggerito e ha scoperto che l'ultima chiamata di sistema è stato BRK (), che ha restituito un errore sul nuovo sistema (2.6.26 del kernel) e restituito il successo sul vecchio sistema (2.6.24 del kernel). Ciò indicherebbe che io davvero sono a corto di memoria virtuale, se non che tcsh "limite" restituisce gli stessi valori sui sistemi vecchi e nuovi, e / proc / meminfo mostra i nuovi sistemi ha un po 'più di memoria e un bel spazio di swap' di più. Forse è un problema di frammentazione o dove il programma viene caricata?

Ho fatto qualche ulteriore ricerca e "brk randomizzazione" è stato aggiunto nel kernel 2.6.25, tuttavia CONFIG_COMPAT_BRK è presumibilmente attivata per impostazione predefinita (che disabilita BRK randomizzazione).

Modifica :

OK, ulteriori informazioni: Sembra veramente BRK randomizzazione è il colpevole, il gcc legacy sta chiamando BRK () per modificare la fine del segmento di dati e che ora non riesce, causando il gcc legacy a riferire "memoria virtuale esaurita". Ci sono alcuni modi per disabilitare documentati BRK randomizzazione:

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

  • sudo sysctl -w kernel.randomize_va_space=0

  • iniziare una nuova shell con setarch i386 -R tcsh (o "-R -L")

li ho provato e che sembrano avere un effetto in quanto il valore di ritorno brk () è diverso (e sempre lo stesso) che senza di loro (provato sia su kernel 2.6.25 e 2.6.26), ma il brk () non riesce ancora così l'eredità gcc non riesce ancora :-(.

Inoltre ho impostato vm.legacy_va_layout=1 e vm.overcommit_memory=2 senza alcun cambiamento, e ho riavviato con le impostazioni vm.legacy_va_layout=1 e kernel.randomize_va_space=0 salvati in /etc/sysctl.conf. Ancora nessun cambiamento.

Modifica :

Utilizzando kernel.randomize_va_space=0 sul kernel 2.6.26 (e 2.6.25) genera il seguente brk () chiamata viene riportato da strace legacy-gcc:

brk(0x80556d4) = 0x8056000

Indica il brk () fallito, ma sembra che non è riuscito perché il segmento dei dati si conclude già al di là di ciò che è stato richiesto. Utilizzando objdump, posso vedere il segmento di dati dovrebbe finire al 0x805518c mentre il BRK fallito () indicates che il segmento dati attualmente termina a 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

Modifica :

Per eco il commento di ephemient di seguito: "così strano per il trattamento di GCC come un binario senza fonte"

Quindi, usando strace, objdump, gdb e la mia comprensione limitata di 386 assembler e architettura ho tracciato il problema alla chiamata malloc prima nel codice legacy. Le chiamate eredità gcc malloc, che restituisce NULL, che si traduce nel messaggio "memoria virtuale esaurito" su stderr. Questo malloc è in libc.so.5, e chiama getenv un mucchio di volte e finisce brk chiamando il numero () ... Credo che per aumentare l'heap ... che non riesce.

Da questo posso solo supporre che il problema è più di brk randomizzazione, o non ho completamente disabilitata brk randomizzazione, nonostante le randomize_va_space = 0 e legacy_va_layout = 1 sysctl impostazioni.

È stato utile?

Soluzione

Installa linux + il vecchio gcc su una macchina virtuale.

Altri suggerimenti

Avete fonti di questo compilatore personalizzato? Se è possibile ripristinare il 2.6.0 della linea di base (e che dovrebbe essere relativamente facile), quindi diff e patch dovrebbe recuperare il set di cambiamento.

Da allora mi piacerebbe consiglio è che il cambiamento utilizzando set di costruire una nuova versione contro aggiornata gcc. E poi metterlo SOTTO CONTROLLO CONFIGURAZIONE.

Siamo spiacenti, non intendo gridare. E 'solo che ho detto la stessa cosa per la maggior parte dei 30 anni.

Si può strace l'eseguibile gcc-2.6.0? Si può fare qualcosa di simile lettura /proc/$$/maps, e ottenere confusi quando le variazioni di uscita in modo insignificante. Un problema simile è stato recentemente notato tra 2.6.28 e 2.6.29.

Se è così, è possibile hack /usr/src/linux/fs/proc/task_mmu.c o giù di lì per ripristinare la vecchia uscita, o impostare alcune $LD_PRELOAD a gcc falso nella lettura un altro file.

Modifica

Dal momento che lei ha citato brk ...

CONFIG_COMPAT_BRK rende il kernel.randomize_va_space=1 di default al posto di 2, ma che rende casuale ancora tutto diverso dal mucchio (brk).

vedere se il problema va via se echo 0 > /proc/sys/kernel/randomize_va_space o sysctl kernel.randomize_va_space=0 (equivalente).

Se è così, aggiungi kernel.randomize_va_space = 0 a /etc/sysctl.conf o aggiungere norandmaps alla linea di comando del kernel (equivalente), ed essere di nuovo felice.

Mi sono imbattuto in questo e pensato circa il tuo problema . Può essere che si può trovare un modo per giocare con il binario per spostarlo in formato ELF? O può essere è irrilevante, ma giocare con objdump in grado di fornire ulteriori informazioni.

Si può avere uno sguardo alla mappa di memoria processo?

Così ho lavorato qualcosa ... non è una soluzione completa, ma non andare oltre il problema originale che ho avuto con il gcc legacy.

Mettere punti di interruzione su ogni chiamata libc nella .plt (tabella di linkage procedura) Vedo che malloc (in libc.so.5) chiama getenv () per ottenere:

    MALLOC_TRIM_THRESHOLD_
    MALLOC_TOP_PAD_
    MALLOC_MMAP_THRESHOLD_
    MALLOC_MMAP_MAX_
    MALLOC_CHECK_

Così ho cercato sul web questi e trovato questo che ha consigliato

    setenv MALLOC_TOP_PAD_ 536870912

poi il gcc eredità FUNZIONA !!!!

Ma non a casa gratuitamente, si alzò per il collegamento nella build prima di guastarsi, quindi c'è qualcosa ulteriormente andando avanti con la NLD eredità che abbiamo :-( Si riporta:

    Virtual memory exceeded in `new'

In /etc/sysctl.conf ho:

    kernel.randomize_va_space=0
    vm.legacy_va_layout=1

Ancora funziona lo stesso se

    kernel.randomize_va_space=1
    vm.legacy_va_layout=0

, ma non se

kernel.randomize_va_space=2

C'è stato un suggerimento di usare "ldd" per vedere le dipendenze delle librerie condivise:.. Il gcc eredità bisogno solo libc5, ma la NLD eredità ha bisogno anche libg ++ so.27, libstdc ++ so.27, libm.so.5 e a quanto pare c'è una versione libc5 di libg ++. so.27 (lIBG ++ 27-altdev ??) e che dire di libc5-compat?

Quindi, come ho detto, non ancora a casa gratis ... essere sempre più vicino. Io probabilmente pubblicare una nuova domanda sul problema NLD.

Modifica :

Mi è stato originariamente intenzione di astenersi dal "Accettare" questa risposta dal momento che ho ancora un problema con il corrispondente linker eredità, ma al fine di ottenere qualche definitivo su questa questione, almeno, sto ripensare quella posizione.

ringraziamento di uscire a:

  • an0nym0usc0ward per il suggerimento di utilizzare una macchina virtuale (che può in ultima analisi, diventare la risposta accettata)
  • ephemient per suggerire usando strace, e aiutare con l'utilizzo StackOverflow
  • shodanex per suggerire utilizzando objdump

Modifica

Di seguito è riportato l'ultima roba che ho imparato, e ora mi accetterà la soluzione VM perché non ho potuto pienamente risolverlo qualsiasi altro modo (almeno nel tempo previsto per questo).

I kernel più recenti hanno una bandiera CONFIG_COMPAT_BRK build per consentire libc5 da utilizzare, quindi presumibilmente la costruzione di un nuovo kernel con questo flag risolverà il problema (e guardando attraverso lo src kernel, sembra che lo farà, ma non posso essere sicuro dal momento che non ho seguito tutti i percorsi). C'è anche un altro modo documentato per permettere l'uso libc5 in fase di esecuzione (piuttosto che al kernel tempo di costruzione): sudo sysctl -w kernel.randomize_va_space = 0. Questo, però fa Non fare un lavoro completo e alcuni (la maggior parte?) app libc5 saranno ancora rompere, per esempio il nostro compilatore e linker legacy. Questo sembra essere dovuto a una differenza di ipotesi di allineamento tra i kernel più recenti e meno recenti. Ho patchato il binario linker per farlo pensare che ha una sezione BSS più grande, al fine di portare alla fine del BSS fino a un limite di pagina, e questo funziona sul più recente kernel quando lo sysctl var kernel.randomize_va_space = 0. Questa non è una soluzione soddisfacente per me dal momento che sto ciecamente patching un binario eseguibile critica, e anche se l'esecuzione del linker patch sul kernel più recenti ha prodotto un'uscita bit-identico alla corsa linker originale sul kernel più vecchie, che non prova che qualche altro ingresso linker (cioè si cambia il programma essendo legato) produrrà anche risultati identici.

Potrebbe non semplicemente fare un'immagine disco che può essere re-installato se il sistema muore? o fare una VM?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top