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

HTML ist die zentrale Grundlage für die Entwicklung von WEB-Standards

HTML-zentrierte Front-End-Entwicklung entspricht p...

Lösung für die in Firefox oder IE nicht ermittelte Spannweite

Code kopieren Der Code lautet wie folgt: <html...

HTML+CSS-Implementierungscode für abgerundete Rechtecke

Mir war langweilig und plötzlich fiel mir die Impl...

Reines CSS, um einen bewölkten Wettersymboleffekt zu erzielen

Wirkung Die Wirkung ist wie folgt ​ Umsetzungside...

MySQL Workbench herunterladen und verwenden Tutorial detaillierte Erklärung

1. MySQL Workbench herunterladen Workbench ist ei...

MySQL Dezimalzahl unsigned Update negative Zahlen in 0 umgewandelt

Heute habe ich bei der Überprüfung des Parallelit...

Beispielcode zum automatischen Umbrechen des Pre-Tags

Das Pre-Element definiert vorformatierten Text. In...

So benennen Sie die Tabelle in MySQL um und worauf Sie achten müssen

Inhaltsverzeichnis 1. Tabellenmethode umbenennen ...

So speichern Sie „false“ oder „true“ in MySQL

Boolescher MySQL-Wert, speichert „false“ oder „tr...

Analysieren Sie die Prinzipien und Methoden der MySQL-Replikation und -Optimierung

1. Einleitung MySQL verfügt über eine Replikation...

So blockieren Sie IP und IP-Bereich in Nginx

Vorne geschrieben Nginx ist nicht nur ein Reverse...