2012-04-12 15 views
3

Ich habe ein Ada-Programm für Linux auf Ubuntu 5.4 (GNAT 3.4) mit dem folgenden Befehl zusammengestellt:Ada Programm unter Linux: SIGSEGV wegen fehlender Datei?

gnatmake -O3 myprogram -bargs -static 

Wenn ich das Programm auf dem Ubuntu-Rechner laufe funktioniert es dann, in Ordnung. Aber auf einem anderen Rechner (Linux Webserver), erhalte ich die folgende Fehlermeldung, wenn ich strace versuchen:

execve("./myprogram", ["./myprogram"], [/* 15 vars */]) = 0 
brk(0)         = 0x811e000 
access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or directory) 
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f8000 
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory) 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f7000 
set_thread_area({entry_number:-1 -> 6, base_addr:0xb76f7680, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 
--- SIGSEGV (Segmentation fault) @ 0 (0) --- 
+++ killed by SIGSEGV +++ 

Was bedeutet das? Verstehe ich es richtig, dass das Programm nicht ausgeführt werden kann, weil zwei Dateien (ld.so.nohwcap und ld.so.preload) fehlen? Wie kann ich diesen Fehler vermeiden? Gibt es eine Möglichkeit, diese Dateien beim Kompilieren in das Programm einzubinden?

+1

Der Ausgang Sie sieht übertragen nicht notwendigerweise - und wahrscheinlich auch nicht - bedeutet, dass eine Verbindung zwischen dem SegV und den fehlenden Dateien besteht. Das wirst du die ganze Zeit in Strace sehen; Es ist nur das System, das z.B. eine Preload-Bibliothek, die möglicherweise nicht vorhanden ist. gdb ist ein besseres Werkzeug zum Aufspüren von Segvs, wenn Sie Debugging-Symbole in Ihrem Programm haben. Es ist lange her, dass ich ADA debugged habe, also bin ich mir nicht sicher, wie ich das genau machen soll. – jimw

+0

Haben Sie auch das Programm auf dem Webserver erstellt, oder kopieren Sie die Binärdatei über? Wenn letzteres, versuche es dort zu bauen. – jimw

+0

Ich habe die Binärdatei kopiert. Dies ist jedoch notwendig, da GNAT auf dem Webserver fehlt. Und ich darf dort keine neuen Pakete installieren. – caw

Antwort

4

Was bedeutet das?

Es bedeutet, dass Ihr Programm versucht, zu dereferenzieren einem NULL Zeiger und starb mit SIGSEGV

Habe ich es richtig verstehe, dass das Programm nicht in der Lage ist, weil zwei Dateien ausführen (ld.so.nohwcap und ld .so.preload) fehlen?

Nein: Es ist völlig normal, dass diese Dateien nicht existieren und Ihr Problem nichts mit ihnen zu tun hat.

  1. Das Tool zum Debuggen wie diese Probleme ist gdb. strace ist nur selten für solche Debugging nützlich.
  2. Entgegen der landläufigen Meinung sind vollstatische ausführbare Dateien (wie die, die Sie erstellten) weniger portable auf Linux, dann dynamisch verknüpfte. Insbesondere haben Sie sich wahrscheinlich Warnungen Link Zeit, ähnlich wie diese:

    Using 'initgroups' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

    Wenn ja, und wenn Versionen von glibc installiert auf Ihrem Build und Webserver Maschinen unterschiedlich sind, dann ist das genau Ihr Problem . Ignorieren Sie solche Warnungen nicht (und verlinken Sie Ihre ausführbaren Dateien nicht mit -static Flag).

Update:

Ist es möglich, nur das fehlende libgnat in das Programm aufgenommen werden?

Es kann möglich sein: Was möchten Sie ist für die letzte Verbindungslinie tun arrangieren wie folgt aussehen:

gcc ... -Wl,-Bstatic -lgnat -Wl,-Bdynamic ... 

Ich weiß nicht, wie das mit gnatmake zu erreichen.

Eine andere, vielleicht einfachere Alternative: Haben Sie überlegt, libgnat-3.4.so.1 auf dem Server zu installieren?

+0

Ich habe diese Warnung nicht gesehen. Aber jetzt habe ich das Programm ohne die Flags "-static" und "-bargs" neu kompiliert. Die "strace" -Ausgabe war länger und enthielt nicht mehr den "SIGSEGV KILL". Es sah also besser aus. Aber als ich die Abhängigkeiten mit 'ldd' überprüft habe, hieß es' linux-gate.so.1 => (0xffffe000) libgnat-3.4.so.1 => nicht gefunden libgcc_s.so.1 => /lib/libgcc_s.so. 1 (0xb786c000) libc.so.6 => /lib/libc.so.6 (0xb7726000) /lib/ld-linux.so.2 (0xb7893000) '. Wie kann ich das beheben? Ist es möglich, nur das fehlende 'libgnat' in das Programm aufzunehmen? – caw

+0

Vielen Dank für die Antwort und die Zugabe! Das Auflösen der Abhängigkeit ist wirklich wichtig, da diese Abhängigkeit der einzige Unterschied zwischen der 'ldd'-Ausgabe für mein Programm und der vorkompilierten ist, die funktioniert. Also, wenn ich die Abhängigkeit von libgnat resoliere, wird das Programm (wahrscheinlich) ausgeführt. – caw

+0

Ich glaube, ich habe das Problem gefunden: Ich habe 'gnat-3.4' installiert, was von' gcc-3.4' abhängt. Aber ich habe nicht nur 'gcc-3.4', sondern auch' gcc-4.0' auf diesem System. Vielleicht verwendet der Compiler die Version 4.0, die zu neu ist. Könnte das die Ursache sein? – caw

1

Denken Sie auch daran, dass das Verschieben eines Programms, das auf einem Linux - Rechner kompiliert wurde (Ubuntu 5.4) zu einem anderen (der Webserver) kann verschiedene Dateiabhängigkeiten haben. Vor allem, wenn sie auf verschiedenen Distributionen basieren. Hier ist eine Beschreibung der ld.so. * Dateien: scroll to the bottom.

Versuchen Sie Jimw Vorschlag und bauen Sie das Programm auf dem Webserver. GNAT 3.4 ist eine ältere Version, daher ist es möglicherweise nicht für die Verwendung auf dem Webserver verfügbar. Denken Sie auch daran, Employee Russian Ratschlag - verwenden Sie nicht die -static Flagge. Sie können Ihr Programm auf Ubuntu ohne das -static Flag versuchen und neu kompilieren und die neue Version auf dem Webserver ausführen, aber dies kann den Fehler möglicherweise nicht beheben.

Wenn die Neukompilierung und/oder Kompilierung auf dem Webserver nicht funktioniert, müssen Sie gdb verwenden, um Ihr Programm zu debuggen. Oder du kannst einen Teil des Codes hier posten und sehen, ob jemand dir helfen kann.

+0

Danke! Kompilieren des Programms ohne die '-static'-Flagge half. Schließlich löste das Kopieren aller fehlenden Abhängigkeiten und das Setzen des LD_LIBRARY_PATH den Rest des Problems. – caw

2

Der Output Sie von strace sehen, ist der dynamische Linker in Bibliotheken versuchen

  1. ich Ihnen empfehlen verlinken zu können LDD dies zeigt Ihnen die Abhängigkeiten
  2. Fix die Abhängigkeiten zu laufen, wenn das funktioniert nicht
  3. wenn Sie es verwenden, um die Option -g neu kompilieren später zu debuggen
  4. wenn es noch keinen Gebrauch gdb laufen und führen Sie es, wenn es mit SIGSEV Typ beendet in dem

Side Hinweis: Achten Sie darauf, die CPU „genau“ das gleiche ist, sonst wird es auf der neuen Maschine neu kompilieren, und dass Sie die ausführbare Datei als binäre

The Man Page which is nice to be read

+0

'ldd' sagt' statisch verbunden', da ich den Parameter '-static' verwendet habe. – caw

+0

Danke für diese allgemeinen und hilfreichen Tipps! – caw

Verwandte Themen