Legacy GCC Compiler -Probleme
-
13-09-2019 - |
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.
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?