Verstehen Sie genau den Grund für die Meldung „Keine solche Datei oder kein solches Verzeichnis“ beim Ausführen einer Datei unter Linux.

Verstehen Sie genau den Grund für die Meldung „Keine solche Datei oder kein solches Verzeichnis“ beim Ausführen einer Datei unter Linux.

1 Hintergrund

Vor kurzem habe ich untersucht, wie man ein Kompilierungssystem (das apt nicht unterstützt) im Linux-System des ZC706-ARM-Entwicklungsboards erstellt. Dabei bin ich zufällig darauf gestoßen, dass das Unternehmen ein Nvidia ARM-Entwicklungsboard mit einem Ubuntu-System (das apt unterstützt) hat. Dabei kam mir eine Idee: Kann das auf dem Nvidia-Board kompilierte Programm auf dem ZC706-Board ausgeführt werden?

2 Prozess

Auf der NVIDIA-Entwicklungsplatine generiert gcc ac a.out, kopiert es dann nach ZC706 und führt es aus. Es erscheint die Meldung „Keine solche Datei oder kein solches Verzeichnis“.

Die Gründe, auf die ich zuvor gestoßen bin, sind die folgenden:

  • Die Datei selbst existiert nicht oder die Datei ist beschädigt
  • Keine Ausführungsberechtigung (chmod 777 xxx)
  • Die Systembitnummer unterscheidet sich von der Programmbitnummer

Nach folgendem Vorgehen stellte sich jedoch heraus, dass in ZC706 der angegebene Loader für das Programm xx fehlte:

1. Dateibeschädigungen und andere Probleme beseitigen --> Kopierüberprüfung neu generieren
2. Beseitigen Sie Probleme mit den Programmberechtigungen --> chmod 777 xx && ls -all
3. Beseitigen Sie Architekturprobleme durch unanme -a
4. Verwenden Sie Befehle wie readelf file, um die Unterschiede zwischen den normal ausgeführten Dateien und den falsch ausgeführten Dateien zu vergleichen

Verifizierungsprozess:

a.out wird von NVIDIA gcc kompiliert und zc706 hat das obige Problem | b.out wird von x86 ubunut plattformübergreifend kompiliert und kann normal ausgeführt werden

Später fand ich durch Google heraus, dass der Loader dieses Phänomen auch verursachen kann. Aus dem Folgenden können wir erkennen, dass der Unterschied zwischen den beiden hauptsächlich im Interpreter liegt

Lösung:

1. Vereinheitlichen Sie die Beziehung zwischen Compiler und Bibliothek

2. Erstellen Sie einen Softlink ln -s /lib/ld-linux.so.3 /lib/ld-linux-armhf.so.3

3. Fügen Sie beim Kompilieren des Programms die Option -static hinzu, um das Programm statisch zu verknüpfen, dh verwenden Sie keine dynamischen Bibliotheken

root@tegra-ubuntu:~# readelf -h a.out
ELF-Header:
 Magie: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
 Klasse: ELF32
 Daten: 2er-Komplement, Little Endian
 Version: 1 (aktuell)
 OS/ABI: UNIX – System V
 ABI-Version: 0
 Typ: EXEC (Ausführbare Datei)
 Maschine: ARM
 Version: 0x1
 Einstiegspunktadresse: 0x8315
 Beginn der Programmheader: 52 (Bytes in Datei)
 Beginn der Abschnittsüberschriften: 4500 (Bytes in Datei)
 Flags: 0x5000402, hat Einstiegspunkt, Version5 EABI, Hard-Float ABI
 Größe dieses Headers: 52 (Bytes)
 Größe der Programmheader: 32 (Bytes)
 Anzahl der Programmköpfe: 9
 Größe der Abschnittsüberschriften: 40 (Bytes)
 Anzahl der Abschnittsüberschriften: 30
 Abschnittsüberschrift-String-Tabellenindex: 27
root@tegra-ubuntu:~# readelf -h b.out
ELF-Header:
 Magie: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
 Klasse: ELF32
 Daten: 2er-Komplement, Little Endian
 Version: 1 (aktuell)
 OS/ABI: UNIX – System V
 ABI-Version: 0
 Typ: EXEC (Ausführbare Datei)
 Maschine: ARM
 Version: 0x1
 Einstiegspunktadresse: 0x86bc
 Beginn der Programmheader: 52 (Bytes in Datei)
 Beginn der Abschnittsüberschriften: 4136 (Bytes in Datei)
 Flags: 0x5000202, hat Einstiegspunkt, Version5 EABI, Soft-Float ABI
 Größe dieses Headers: 52 (Bytes)
 Größe der Programmheader: 32 (Bytes)
 Anzahl der Programmköpfe: 8
 Größe der Abschnittsüberschriften: 40 (Bytes)
 Anzahl der Abschnittsüberschriften: 31
 Abschnittsüberschrift-String-Tabellenindex: 28
root@tegra-ubuntu:~# readelf -l hallo Welt | grep-Interpreter
readelf: Fehler: „Hallo Welt“: Keine solche Datei
root@tegra-ubuntu:~# readelf -l a.out | grep-Interpreter
   [Anfordernder Programminterpreter: /lib/ld-linux-armhf.so.3]
root@tegra-ubuntu:~# readelf -l b.out | grep-Interpreter
   [Anfordernder Programminterpreter: /lib/ld-linux.so.3] 

3 Einführung in den LD-Loader

Linux verwendet dieses ld-linux.so* (Ubuntu auf der virtuellen Maschine x86 verwendet ld-linux.so2), um andere Bibliotheken zu laden (eigentlich ist dies nur ein Link). Daher muss diese Bibliothek in linux/lib platziert werden. Für andere legen wir gemeinsam genutzte Bibliotheken normalerweise im Pfad /lib ab, der auch der Standardsuchpfad des Systems ist.

Die Suchpfadreihenfolge der gemeinsam genutzten Linux-Bibliotheken lautet:
1. Der beim Kompilieren des Zielcodes angegebene Suchpfad für dynamische Bibliotheken: Geben Sie beim Kompilieren -Wl, -rpath = Pfad an
2. Dynamischer Bibliothekssuchpfad, angegeben durch die Umgebungsvariable LD_LIBRARY_PATH
3. Dynamischer Bibliothekssuchpfad, angegeben in der Konfigurationsdatei /etc/ld.so.conf
4. Standardsuchpfad für dynamische Bibliotheken /lib
5. Der Standardsuchpfad für dynamische Bibliotheken ist /usr/lib

Beachten:

1. Einige Entwicklungsboards stellen fest, dass /etc nicht über ld.so.conf verfügt. Zu diesem Zeitpunkt wird beim Ausführen von ldconfig die Meldung „ldconfig: Warnung: Konfigurationsdatei wird ignoriert, die nicht geöffnet werden kann: /etc/ld.so.conf: Keine solche Datei oder kein solches Verzeichnis“ angezeigt.

Lösung: Fügen Sie die Bibliothek zu den Umgebungsvariablen hinzu, dann ldconfig -v (/sbin/ldconfig: relativer Pfad „–v“ zum Erstellen des Caches)

2. Gemeinsam genutzte Bibliothek kann gemeinsam genutztes Objekt nicht öffnen

Testen Sie, ob es dynamisch verknüpft ist. Wenn libtest.so aufgeführt ist, sollte der Link normal sein.

Derzeit kann libtest.so nicht gefunden werden. Es liegt ein Problem mit dem Suchpfad der dynamischen Linkbibliothek vor. Fügen Sie daher einfach den oben angegebenen Suchort der dynamischen Bibliothek hinzu.

3 Der Befehl ldconfig sucht hauptsächlich in den Standardsuchverzeichnissen (/lib und /usr/lib) und den in der Konfigurationsdatei der dynamischen Bibliothek /etc/ld.so.conf aufgeführten Verzeichnissen nach gemeinsam nutzbaren dynamischen Linkbibliotheken (das Format ist wie oben beschrieben, lib*.so*) und erstellt dann die vom dynamischen Loader (ld.so) benötigten Verbindungs- und Cachedateien.

4 LD_LIBRARY_PATH: Diese Umgebungsvariable gibt den Pfad an, in den der dynamische Linker dynamische Bibliotheken laden kann. Wenn Sie über Root-Rechte verfügen, können Sie die Datei /etc/ld.so.conf ändern und dann /sbin/ldconfig aufrufen, um dasselbe zu erreichen. Wenn Sie jedoch keine Root-Rechte haben, können Sie nur die Methode zum Ausgeben von LD_LIBRARY_PATH mit dem Bash-Befehl verwenden.)

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Zeigen Sie die abhängigen Bibliotheken von so oder ausführbaren Programmen unter Linux an
  • Implementierung eines integrierten ausführbaren C-Programms in Ubuntu zum Testen des Linux-Kerneltreibers für Android

<<:  Detaillierte Analyse klassischer Fragen zu JavaScript-Rekursionsfällen

>>:  Grafisches Tutorial zur Installation und Konfiguration von MySQL 8.0.16 winx64 unter win10

Artikel empfehlen

Einführung in die grundlegenden TypeScript-Typen

Inhaltsverzeichnis 1. Grundtypen 2. Objekttyp 2.1...

Erläuterung des Prozesses des Docker-Packaging-Node-Projekts

Als Backend-Programmierer muss ich manchmal an Fr...

Implementierungsbeispiel für die Nginx-Zugriffskontrolle

Über Nginx, eine leistungsstarke, leichte Webserv...

Vergleich der JS-Array-Loop-Methode und der Effizienzanalyse

Array-Methoden JavaScript bietet viele Array-Meth...

MySQL 8.0.20 Installations- und Konfigurations-Tutorial unter Win10

Super ausführliches Tutorial zur Installation und...

Wie implementiert MySQL ACID-Transaktionen?

Vorwort Kürzlich wurde ich in einem Interview gef...

Analyse des Prinzips und der Erstellungsmethode der temporären MySQL-Tabelle

In diesem Artikel werden hauptsächlich das Prinzi...

Verwenden Sie das Firebug-Tool, um die Seite auf dem iPad zu debuggen

Wie debuggt man eine Seite auf dem iPad? Wenn Sie ...

Tutorial zur Installation und Konfiguration der Version MySQL 5.7.23

Ich habe drei Stunden gebraucht, um MySQL selbst ...