Was ist der Unterschied zwischen einem Segmentierungsfehler und einem Stapelüberlauf?

Lesezeit: 3 Minuten

Benutzeravatar von AruniRC
AruniRC

Wenn wir beispielsweise eine rekursive Funktion aufrufen, werden die aufeinanderfolgenden Aufrufe im Stack gespeichert. Aufgrund eines Fehlers, wenn es unendlich weitergeht, ist der Fehler jedoch „Segmentierungsfehler“ (wie auf GCC zu sehen).

Hätte es nicht “Stapelüberlauf” sein sollen? Was ist dann der grundlegende Unterschied zwischen den beiden?

Übrigens, eine Erklärung wäre hilfreicher als Wikipedia-Links (das durchgegangen, aber keine Antwort auf eine bestimmte Frage).

  • Bei Overflow-Zeug geht es um Programmierfragen, bei Fault-Zeug um Server. oO

    – P Schweb

    21. April 2010 um 18:13 Uhr

  • @Pavel: Was hat SIGSEGV mit Servern zu tun? Obwohl Serveranwendungen einen Segmentierungsfehler verursachen können, hat das wirklich nichts mit der Serververwaltung zu tun, sondern mit Programmierung.

    – Nathan Osmann

    21. April 2010 um 18:17 Uhr

  • @George: Serverfehler.com und schwups.

    – kennytm

    21. April 2010 um 18:20 Uhr

  • Ich denke, es ist eine Posix-Einschränkung, es unterstützt SIGSTKFLT nicht.

    – Hans Passant

    21. April 2010 um 18:22 Uhr

Benutzeravatar von kennytm
kennytm

Stapelüberlauf ist [a] Ursache, Segmentierungsfehler ist die Folge.


Zumindest auf x86 und ARM ist der “Stack” ein Stück Speicher, der für das Platzieren lokaler Variablen und Rückgabeadressen von Funktionsaufrufen reserviert ist. Wenn der Stapel erschöpft ist, wird auf den Speicher außerhalb des reservierten Bereichs zugegriffen. Aber die App hat den Kernel nicht nach diesem Speicher gefragt, daher wird ein SegFault zum Speicherschutz generiert.

Moderne Prozessoren verwenden Speichermanager, um Prozesse voreinander zu schützen. Der x86-Speichermanager verfügt über viele Legacy-Funktionen, von denen eine die Segmentierung ist. Die Segmentierung soll verhindern, dass Programme den Speicher auf bestimmte Weise manipulieren. Beispielsweise könnte ein Segment als schreibgeschützt markiert sein und der Code würde dort abgelegt, während ein anderes Segment schreib-/lesbar ist und dort Ihre Daten abgelegt werden.

Während eines Stapelüberlaufs erschöpfen Sie den gesamten Speicherplatz, der einem Ihrer Segmente zugewiesen ist, und Ihr Programm beginnt dann, in Segmente zu schreiben, die der Speichermanager nicht zulässt, und dann erhalten Sie einen Segmentierungsfehler.

  • Ich bin mir ziemlich sicher, dass Unix diesen Begriff verwendet hat, lange bevor er in die Nähe von x86 kam …

    – SamB

    1. Dezember 2013 um 6:12 Uhr

  • @SamB Ich sehe nicht, wo die Antwort etwas anderes behauptet. “Der x86-Speichermanager hat viele Legacy-Features, eine davon ist die Segmentierung” != “Die von x86 erfundene Segmentierung”.

    – J Bentley

    25. Januar 2014 um 15:22 Uhr


  • Die von x86 verwendete Segmentierung (die Segmentregister) unterscheidet sich vollständig von der vom Betriebssystem durchgeführten “Segmentierung” des Adressraums. Segmentierungsfehler hat nichts mit Segmentregistern zu tun. Obwohl sie lange Zeit Teil von x86 waren, sind Segmentregister immer noch sehr wichtig für die Funktionsweise von x86 in modernen Betriebssystemen.

    – Seifenkiste

    25. Januar 2014 um 15:41 Uhr

  • Ich bin mir nicht sicher, ob ich deinen Punkt verstehe, SoapBox. Segmentierung ist ein Konzept, das mit Segmentregistern in x86 implementiert wird. Die Register werden verwendet, um den Adressraum in Segmente aufzuteilen, wie z. B. das Codesegment, das Datensegment, das Stapelsegment und das Extrasegment. Ein Stack-Überlauf tritt auf, wenn Ihr Stack dem Stack-Segment “entkommt”. Ich habe Probleme, die Inkonsistenz zu identifizieren, auf die Sie hinweisen möchten.

    – ajs410

    5. Februar 2014 um 23:47 Uhr

  • Auf allen modernen Betriebssystemen sind die Segmentregister CS, DS, SS so eingerichtet, dass sie effektiv ignoriert werden (die zusätzlichen Register ES, FS, GS können Ausnahmen sein, die für spezielle Zwecke verwendet werden). Segmentierungsfehler resultieren nicht aus dem Überlaufen eines CPU-Segments, sondern aus dem Zugriff auf eine ungültige Seite.

    – Benutzer253751

    21. Mai 2015 um 2:34 Uhr

Der Aufrufstapel wird überlaufen, aber das Ergebnis des Überlaufs ist, dass schließlich aufrufbezogene Werte in den Speicher geschoben werden, der nicht Teil des Stapels ist, und dann – SIGSEGV!

Ein Stapelüberlauf kann sich entweder als explizite Stapelüberlaufausnahme (je nach Compiler und Architektur) oder als Segmentierungsfehler, dh ungültiger Speicherzugriff, manifestieren. Letztendlich ist ein Stack-Überlauf das Ergebnis von zu wenig Stack-Speicherplatz, und ein mögliches Ergebnis von zu wenig Stack-Speicherplatz ist das Lesen oder Schreiben in Speicher, auf den Sie nicht zugreifen sollten. Daher ist bei vielen Architekturen das Ergebnis eines Stapelüberlaufs ein Speicherzugriffsfehler.

1389900cookie-checkWas ist der Unterschied zwischen einem Segmentierungsfehler und einem Stapelüberlauf?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy