GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Ist ein „Segmentierungsfehler“ ein Systemfehler oder ein Programmfehler?

Ich führe derzeit ein statistisches Modellierungsskript aus, das eine phylogenetische ANOVA durchführt. Das Skript läuft gut, wenn ich den vollständigen Datensatz analysiere. Aber wenn ich eine Teilmenge nehme, beginnt sie zu analysieren, endet aber schnell mit einem Segmentierungsfehler. Ob das an einem Problem meinerseits (z. B. zu kleiner Beispieldatensatz für die Analyse) und/oder einem Fehler im Skript liegen könnte oder ob dies etwas mit meinem Linux-System zu tun hat, kann ich durch Googeln nicht wirklich herausfinden. Ich habe gelesen, dass es mit dem Schreiben von Daten in den Speicher zu tun hat, aber warum ist dann mit einem größeren Datensatz alles in Ordnung? Ich habe versucht, mehr Informationen mit Google zu finden, aber das hat es komplizierter gemacht.

Vielen Dank für die Klärung im Voraus!

Akzeptierte Antwort:

(tl;dr:Es ist mit ziemlicher Sicherheit ein Fehler in Ihrem Programm oder einer Bibliothek, die es verwendet.)

Ein Segmentierungsfehler zeigt an, dass ein Speicherzugriff nicht zulässig war. Das heißt, basierend auf der ausgegebenen Anfrage gibt die CPU einen Seitenfehler aus, weil die angeforderte Seite entweder nicht resident ist oder Berechtigungen hat, die nicht mit der Anfrage übereinstimmen.

Danach prüft der Kernel, ob er einfach nichts über diese Seite weiß, ob sie noch nicht im Speicher ist und sie dort ablegen sollte, oder ob er eine spezielle Behandlung durchführen muss (z. B. copy-on -write Seiten sind schreibgeschützt und dies gültig Seitenfehler kann darauf hindeuten, dass wir ihn kopieren und die Berechtigungen aktualisieren sollten). Siehe Wikipedia für geringfügige vs. schwerwiegende Fehler (z. B. Paging nach Bedarf) vs. ungültige Seitenfehler.

Das Erhalten eines Segmentierungsfehlers zeigt den ungültigen Fall an:Die Seite befindet sich nicht nur nicht im Speicher, sondern der Kernel muss auch keine Abhilfemaßnahmen durchführen, da der Prozess diese Seite seines virtuellen Adressraums nicht logisch zugeordnet hat. Als solches weist dies mit ziemlicher Sicherheit auf einen Fehler entweder im Programm oder in einer seiner zugrunde liegenden Bibliotheken hin – zum Beispiel beim Versuch, in den Speicher zu lesen oder zu schreiben, der für den Prozess nicht gültig ist. Wenn die Adresse gültig gewesen wäre, hätte sie möglicherweise den Stapel beschädigt oder andere Daten überschrieben, aber ein un gelesen oder geschrieben zugeordnete Seite wird von Hardware abgefangen.

Der Grund, warum es mit Ihrem größeren Datensatz und nicht mit Ihrem kleineren Datensatz funktioniert, ist ganz spezifisch für dieses Programm:Es ist wahrscheinlich ein Fehler in der Logik dieses Programms, der aus irgendeinem Grund nur für den kleineren Datensatz ausgelöst wird (z. B. kann Ihr Datensatz eine Feld, das die Gesamtzahl der Einträge darstellt, und wenn es nicht aktualisiert wird, liest Ihr Programm möglicherweise blind in nicht zugeordneten Speicher, wenn es keine anderen Plausibilitätsprüfungen durchführt).

Es ist um mehrere Größenordnungen unwahrscheinlicher als nur ein Softwarefehler, aber ein Segmentierungsfehler kann auch ein Indikator für Hardwareprobleme sein, wie fehlerhafter Speicher, eine fehlerhafte CPU oder Ihre Hardware, die über Errata stolpert (als Beispiel siehe hier).

Siehe auch:Debian – Automatisieren der Installation einzelner Debian 8-Pakete mit interaktiven Eingabeaufforderungen?

Das Erhalten von Segfaults aufgrund fehlerhafter Hardware führt oft zu einem manchmal funktionierenden Verhalten, obwohl ein schlechtes Bit im physischen RAM bei wiederholten Ausführungen eines Programms auf die gleiche Weise zugeordnet werden kann, wenn Sie dazwischen nichts anderes ausführen. Sie können diese Möglichkeit größtenteils ausschließen, indem Sie memtest86+ booten, um nach fehlerhaftem RAM zu suchen, und Software wie Prime95 verwenden, um Ihre CPU (einschließlich der FP-Mathematik-FMA-Ausführungseinheiten) einem Stresstest zu unterziehen.

Sie können das Programm in einem Debugger wie gdb ausführen und den Backtrace zum Zeitpunkt des Segmentierungsfehlers erhalten, der wahrscheinlich den Übeltäter anzeigt:

% gdb --args ./foo --bar --baz
(gdb) r   # run the program
[...wait for segfault...]
(gdb) bt  # get the backtrace for the current thread

Linux
  1. Wie installiere ich eine ältere Version eines Programms?

  2. Wie konfiguriere ich eine benutzerdefinierte Fehlerseite?

  3. Behebung System wurde nicht mit systemd als init-Systemfehler gebootet

  4. 13 Grundlegende Linux-Systemaufrufe erklärt anhand eines lustigen Linux-Virenprogramms

  5. Wie beendet man das X11-Programm ohne Fehler?

So lösen Sie den Initramfs-Fehler in Fedora

So erstellen Sie Ihr erstes Java-Programm in Debian 10

Ihr erstes Java-Programm im Ubuntu-Terminal

So erstellen Sie eine benutzerdefinierte 404-Fehlerseite in cPanel

So beheben Sie den Fehler „Systemprogrammproblem erkannt“ unter Ubuntu

Gewusst wie:Einführung in die Programmierung – Ihr erstes Programm