Frage

Wir verwenden einen Legacy -Compiler, der auf GCC 2.6.0 basiert, um Kompilierung für einen alten mitgesetzten Prozessor zu überqueren, den wir noch verwenden (ja, es wird seit 1994 immer noch verwendet!). Der Ingenieur, der den GCC -Anschluss für diesen Chip gemacht hat, ist längst weitergegangen. Obwohl wir in der Lage sind, die Quelle GCC 2.6.0 von irgendwo im Web wiederherzustellen, ist der für diesen Chip festgelegte Änderung in den Hallen der Unternehmensgeschichte verschwunden. Wir haben uns bis vor kurzem durcheinander gebracht, als der Compiler immer noch lief und produzierbare ausführbare Produkte produziert hat, aber ab Linux Kernel 2.6.25 (und auch 2.6.26) fehlschlägt es bei der Nachricht gcc: virtual memory exhausted... auch wenn er ohne Parameter ausgeführt wird oder nur mit -v. Ich habe mein Entwicklungssystem (ab 2.6.26) mit dem 2,6.24 -Kernel neu gestartet und der Compiler funktioniert erneut (Neustart mit 2.6.25).

Wir haben ein System, das wir bei 2,6.24 nur zum Zwecke der Builds für diesen Chip halten, aber ein bisschen freigelegt fühlen, falls die Linux -Welt weitergeht, bis zu dem Punkt, dass wir ein System, das läuft, nicht mehr wieder aufbauen können Der Compiler (dh unser 2,6.24 -System stirbt und wir können nicht 2.6.24 für ein neues System installieren und ausführen, da einige der Softwareteile nicht mehr verfügbar sind).

Hat jemand Ideen für das, was wir mit einer moderneren Installation tun können, um diesen Legacy -Compiler zum Laufen zu bringen?

Bearbeiten:

Um einige der Kommentare zu beantworten ...

Leider sind es die Quellcodeänderungen, die für unseren Chip verloren sind, der verloren geht. Dieser Verlust ereignete sich über zwei große Unternehmens -Reorgs und mehrere Sysadmins (einige davon haben wirklich ein Chaos hinterlassen). Wir verwenden jetzt die Konfigurationskontrolle, aber das schließt die Scheunentür für dieses Problem zu spät.

Die Verwendung eines VM ist eine gute Idee und kann das sein, was wir am Ende tun. Danke für diese Idee.

Schließlich versuchte ich Strace, wie kurzerhielt vorgeschlagen wurde, und stellte fest, dass der letzte Systemaufruf BRK () war, der einen Fehler auf dem neuen System zurückgab (2,6,26 Kernel) und den Erfolg des alten Systems (2,6,24 Kernel) zurückgab. Dies würde darauf hinweisen, dass mir der virtuelle Speicher wirklich ausgeht, außer dass TCSH "Limit" die gleichen Werte für alte und neue Systeme zurückgibt, und /proc /meminfo zeigt, dass die neuen Systeme etwas mehr Speicher und etwas mehr Swap -Speicherplatz haben. Vielleicht ist es ein Problem der Fragmentierung oder wo das Programm geladen wird?

Ich habe einige weitere Nachforschungen angestellt und in Kernel 2.6.25 wurde "BRK -Randomisierung" hinzugefügt CONFIG_COMPAT_BRK ist angeblich standardmäßig aktiviert (was die BRK -Randomisierung deaktiviert).

Bearbeiten:

OK, MEHR INFO: Es sieht wirklich so aus, als ob die Randomisierung von BRK der Schuldige ist, das Legacy GCC ruft BRK () an, um das Ende des Datensegments zu ändern, und das fällt jetzt fehl, was dazu führt, dass das Legacy GCC "Virtual Memory erschöpft" meldet. Es gibt einige dokumentierte Möglichkeiten, die BRK -Randomisierung zu deaktivieren:

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

  • sudo sysctl -w kernel.randomize_va_space=0

  • eine neue Hülle mit starten mit setarch i386 -R tcsh (oder "-r -l")

Ich habe sie ausprobiert und sie scheinen einen Effekt zu haben, als der BRK () -Rendungswert unterschiedlich ist (und immer gleich) als ohne sie (ohne Kernel 2.6.25 und 2.6.26), aber der BRK (), aber der BRK () scheitert immer noch, so dass das Legacy GCC immer noch fehlschlägt :-(.

Außerdem habe ich festgelegt vm.legacy_va_layout=1 und vm.overcommit_memory=2 ohne Veränderung, und ich habe mit dem neu gestartet vm.legacy_va_layout=1 und kernel.randomize_va_space=0 Einstellungen gespeichert in /etc/sysctl.conf. Immer noch keine Veränderung.

Bearbeiten:

Verwendung kernel.randomize_va_space=0 Auf Kernel 2.6.26 (und 2.6.25) führt zu dem folgenden BRK () -Anruf, der von gemeldet wird strace legacy-gcc:

brk(0x80556d4) = 0x8056000

Dies zeigt an, dass der BRK () fehlgeschlagen ist, aber es sieht so aus, als ob es fehlgeschlagen ist, da das Datensegment bereits über das hinausgeht, was angefordert wurde. Mit Objdump kann das Datensegment bei 0x805518c enden, während das fehlgeschlagene BRK () angibt, dass das Datensegment derzeit bei 0x8056000 endet:

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

Bearbeiten:

Um den Kommentar von Echo Ehephient unten wiederzugeben: "So seltsam, GCC als binär ohne Quelle zu behandeln"!

Mit Strace, Objdump, GDB und meinem begrenzten Verständnis von 386 Assembler und Architektur habe ich das Problem auf den 1. Malloc -Aufruf im Legacy -Code aufgeführt. Das Legacy GCC nennt Malloc, das NULL zurückgibt, was zu der "Virtual Memory erschöpften" Nachricht auf Stderr führt. Dieser Malloc ist in libc.so.5 und nennt Getenv ein paar Mal und ruft BRK () an ... ich denke, den Haufen zu erhöhen ... was fehlschlägt.

Aus diesem Grund kann ich nur vermuten, dass das Problem mehr als die BRK -Randomisierung ist oder ich die BRK -Randomisierung trotz der Randomize_va_space = 0 und Legacy_va_Layout = 1 SysCTL -Einstellungen nicht vollständig deaktiviert habe.

War es hilfreich?

Lösung

Installieren Sie Linux + das alte GCC auf einer virtuellen Maschine.

Andere Tipps

Haben Sie die Quellen Für diesen benutzerdefinierten Compiler? Wenn Sie die Baseline 2.6.0 wiederherstellen können (und das sollte relativ einfach sein), sollte Diff und Patch Ihren Änderungssatz wiederherstellen.

Was ich dann empfehlen würde, ist die Verwendung dieser Änderung, um eine neue Version gegen aktuelle GCC zu erstellen. Und stellen Sie es dann unter Konfigurationskontrolle ein.

Entschuldigung, will nicht schreien. Es ist nur, dass ich die meisten von 30 Jahren dasselbe gesagt habe.

Können Sie strace das gcc-2.6.0 ausführbar? Es kann so etwas wie Lesen tun /proc/$$/maps, und verwirrt werden, wenn sich die Ausgabe auf unbedeutende Weise ändert. Ein ähnliches Problem war kürzlich bemerkt zwischen 2,6.28 und 2,6.29.

Wenn ja, können Sie hacken /usr/src/linux/fs/proc/task_mmu.c oder um es gibt an, um die alte Ausgabe wiederherzustellen oder einige einzurichten $LD_PRELOAD fälschen gcc in eine andere Datei lesen.

Bearbeiten

Seit du erwähnt hast brk...

CONFIG_COMPAT_BRK macht den Standard kernel.randomize_va_space=1 Anstatt von 2, aber das randomisiert immer noch alles andere als den Haufen (brk).

Sehen Sie, ob Ihr Problem verschwindet, wenn Sie echo 0 > /proc/sys/kernel/randomize_va_space oder sysctl kernel.randomize_va_space=0 (gleichwertig).

Wenn ja, fügen Sie hinzu kernel.randomize_va_space = 0 zu /etc/sysctl.conf oder hinzufügen norandmaps zur Kernel -Befehlszeile (gleichwertig) und sei wieder glücklich.

Ich stieß auf Dies und dachte über dein Problem nach. Vielleicht können Sie einen Weg finden, mit der Binärdatei zu spielen, um es in das ELF -Format zu bewegen? Oder kann es irrelevant sein, aber das Spielen mit Objdump kann Ihnen weitere Informationen liefern.

Können Sie sich die Prozessspeicherkarte ansehen?

Also habe ich etwas ausgearbeitet ... es ist keine vollständige Lösung, aber es kommt an dem ursprünglichen Problem vorbei, das ich mit dem Legacy GCC hatte.

Auf jeden LIBC -Aufruf in die .plt (Prozedurverknüpfungstabelle) Breakpoints einstellen Ich sehe, dass Malloc (in libc.so.5) Getenv () aufruft, um zu erhalten:

    MALLOC_TRIM_THRESHOLD_
    MALLOC_TOP_PAD_
    MALLOC_MMAP_THRESHOLD_
    MALLOC_MMAP_MAX_
    MALLOC_CHECK_

Also habe ich diese Web-gesucht und festgestellt Dies was beriet

    setenv MALLOC_TOP_PAD_ 536870912

Dann funktioniert das Legacy GCC !!!!

Aber nicht zu Hause kostenlos, es hat den Link im Build vorgegangen, bevor es gescheitert ist. Mit dem Legacy NLD gibt es etwas weiter, das wir haben :-( Es wird berichtet:

    Virtual memory exceeded in `new'

IN /ETC/SYSCTL.CONF Ich habe:

    kernel.randomize_va_space=0
    vm.legacy_va_layout=1

Es funktioniert immer noch gleich, wenn

    kernel.randomize_va_space=1
    vm.legacy_va_layout=0

aber nicht wenn

kernel.randomize_va_space=2

Es gab einen Vorschlag, "LDD" zu verwenden, um die gemeinsam genutzten Bibliotheksabhängigkeiten zu sehen: Das Legacy GCC braucht nur LIBC5, aber das Legacy NLD braucht auch libg ++. So.27, libstdc ++. Eine LIBC5-Version von libg ++. So.27 (libg ++ 27-Altdev?) Und was ist mit LIBC5-compat?

Also, wie gesagt, noch nicht zu Hause frei ... näher kommen. Ich werde wahrscheinlich eine neue Frage zum NLD -Problem stellen.

Bearbeiten:

Ich wollte diese Antwort ursprünglich nicht auf "akzeptieren", da ich immer noch ein Problem mit dem entsprechenden Legacy -Linker habe, aber um diese Frage zumindest für diese Frage endgültig zu finanzieren, überdenken ich diese Position.

Vielen Dank an Sie gehen aus:

  • AN0NYM0USCORWARD für den Vorschlag, eine VM zu verwenden (was letztendlich zur akzeptierten Antwort werden kann)
  • Einkünftig für die Verwendung von Strace und Hilfe bei der Verwendung von Stackoverflow
  • Shodanex für die Verwendung von Objdump

Bearbeiten

Unten finden Sie das letzte Zeug, das ich gelernt habe, und jetzt werde ich die VM -Lösung akzeptieren, da ich sie nicht ganz anders lösen konnte (zumindest in der dafür zugeordneten Zeit).

Die neueren Kerne haben ein config_compat_brk Build -Flag, mit dem LIBC5 verwendet werden kann. Das Aufbau eines neuen Kernels mit dieser Flag nicht alle Pfade folgen). Es gibt auch einen weiteren dokumentierten Weg, um die LIBC5 zur Laufzeit zu ermöglichen (und nicht zum Kernel -Build -Zeit): sudo sysctl -W kernel.randomize_va_space = 0. Dies macht jedoch keinen vollständigen Job und einige (die meisten?) LIBC5 -Apps werden immer noch brechen, z. B. unserem Legacy Compiler und Linker. Dies scheint auf einen Unterschied in den Annahmen zwischen den neueren und älteren Kerneln zurückzuführen zu sein. Ich habe den Linker Binary gepatcht, um zu glauben, dass er einen größeren BSS -Abschnitt hat, um das Ende des BSS auf eine Seitengrenze zu bringen, und dies funktioniert auf dem neueren Kernel, wenn der sysctl var kernel.randomize_va_space = 0. Dies ist keine zufriedenstellende Lösung für mich, da ich blind eine kritische binäre ausführbare Datei patchiere und obwohl das Ausführen des Patched-Linker auf dem neueren Kernel eine bitidentische Ausgabe des ursprünglichen Linkers auf dem älteren Kernel erbrachte, das beweist das nicht Einige andere Linker -Eingaben (dh wir ändern das zu verknüpfte Programm) erzeugen ebenfalls identische Ergebnisse.

Könnten Sie nicht einfach ein Disc-Bild erstellen, das erneut installiert werden kann, wenn das System stirbt? Oder eine VM machen?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top