Verständnisfrage Stack Overflow
-
Danke für eure Hilfen
Durch wen wird diese Größe den genau bestimmt, kann der Nutzer dem Compiler diese vorgeben ?
Gruß
-
Die Stack-Größe kann man beim Thread erstellen selbst angeben (stack_size/dwStackSize, 0=Standard-Stackgröße):
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx
http://msdn.microsoft.com/de-de/library/kdzttdcb%28v=vs.80%29.aspxAnsonsten könnte interessant sein:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686774%28v=vs.85%29.aspx
-
Gast31415 schrieb:
Ich hatte bzgl. Stack- und Heapgröße das Bild im Kopf, in der beide Speicher gegeneinader Laufen, wie hier zu sehen:
http://www.andrew.cmu.edu/course/15-412/ln/proccontext.jpg
Aber C++ scheint das dann intern iregndwie anders zu verwalten oder?
Das Bild stammt aus der Computersteinzeit. Damals war es vielleicht richtig, heute ist es das nicht mehr.
So wie da abgebildet kann es nämlich nur funktionieren, wenn es pro Prozess nur einen Thread und nur einen Heap gibt.
Beides ist heute nicht mehr der Fall.
-
Doch, die Laufen auch heute noch gegeneinander. Das war auch das Problem mit der Ende 2010 entdeckten Sicherheitslücke im X-Server. Kann mich nicht im Detail erinnern, aber es ging glaub ich darum, dass wenn der Heap zu stark anwächst und der Abstand zum Stack zu klein wird, der Stack in den Heap hineinwächst.
-
Mechanics schrieb:
Doch, die Laufen auch heute noch gegeneinander. Das war auch das Problem mit der Ende 2010 entdeckten Sicherheitslücke im X-Server. Kann mich nicht im Detail erinnern, aber es ging glaub ich darum, dass wenn der Heap zu stark anwächst und der Abstand zum Stack zu klein wird, der Stack in den Heap hineinwächst.
Das ist unmöglich. Denn der Satck wächst durch eine ´Guardpage und die letzte Guardpage erlaubt keinen Zugriff. Erfolgt ein Zugriff auf diese Seite gibts den Stackoverflow.
-
Martin Richter schrieb:
Mechanics schrieb:
Doch, die Laufen auch heute noch gegeneinander. Das war auch das Problem mit der Ende 2010 entdeckten Sicherheitslücke im X-Server. Kann mich nicht im Detail erinnern, aber es ging glaub ich darum, dass wenn der Heap zu stark anwächst und der Abstand zum Stack zu klein wird, der Stack in den Heap hineinwächst.
Das ist unmöglich. Denn der Satck wächst durch eine ´Guardpage und die letzte Guardpage erlaubt keinen Zugriff. Erfolgt ein Zugriff auf diese Seite gibts den Stackoverflow.
Naja, lies es dir selber durch, wenn es dich im Detail interessiert:
http://www.invisiblethingslab.com/resources/misc-2010/xorg-large-memory-attacks.pdf
-
@Mechanics
Der Exploit basiert auf einer Sicherheitslücke in Linux. Nämlich dass der für den Stack reservierte Adressraum bei Bedarf vollständig mit Speicher hinterlegt wird. EDIT: wurde, gibt ja mittlerweile nen entsprechenden Patch /EDITMit dem auf dem Bild dargestellten Anachronismus hat das aber nichts zu tun.
-
Ich weiß jetzt nur, wie Windows das handhabt, bei Linux bin ich mir nicht sicher (wird aber wohl gleich sein ...). Wenn ein Prozess gestartet wird, bekommt er zunächst einmal einen Heap vom OS bereitgestellt, dort kann dann der Prozess schon mal ein bisschen globalen Speicher belegen - ein Stack existiert hier noch gar nicht, der wird erst angelegt, wenn für den Prozess ein Thread gestartet wird. Erst mit dem Starten des Threads wird dann dein Code ausgeführt, und da die Ausführung in einem imperativen (funktionsorientierten) Kontext stattfindet, muss hier ein Thread existieren, der den Callstack, die Parameter und eventuelle Zeiger auf Speicherbereiche im Heap sicherstellt. Der Kernel ist da eine kleine Ausnahme, der hat vollen Zugriff auf den Speicher und die Systemresourcen und kann daher auch ohne 'Prozess', wie Windows ihn für Programme im Userspace definiert, ausgeführt werden, da direkt zu Anfang der Code im Master Boot Record ausgeführt wird und zu diesem Zeitpunkt das Schloss namens Betriebssystem mit Multithreading und Prozessverwaltung noch gar nicht existiert. Schön kann man das an MS-DOS sehen, das nur einen Prozess gleichzeitig ausführen konnte - das Prozesshandling ist eigentlich nur eine Emulation des Kernels.
Gut, also zunächst kommt ein bisschen Heap mit Initialisierung von Speicher und Code, der zum Ausführen deines Programms gebraucht wird, und dann erst wird der Thread gestartet. Zu jedem Thread gehört ein Stack (in diesem Zusammenhang bevorzuge ich den Terminus 'Callstack', da hier nicht nur Daten, sondern auch der gesamte Verlauf des bisher ausgeführten Codes zu ermitteln ist - die Funktionen müssen ja auch wissen, wohin sie denn nun springen sollen, nachdem eine Funktion abgearbeitet ist). Ein Prozess kann mehrere Heaps und Threads mit Ihren Callstacks haben, und die Threads können auf die Heaps des Prozesses zugreifen (hier sollte der Zugriff syncronisiert oder zumindest threadsicher gestaltet werden, wie zum Beispiel, wenn man jedem Thread zu Anfang eine Liste mit Daten gibt und diese abgearbeitet werden müssen, dann brauchen die Ausführungen keinen gemeinsamen Zugriff und man kann sich die Extra-Tipperei sparen) - aber die Thread können/sollten nur auf Ihren eigenen Callstack zugreifen. Da gibt es allerdings auch Ausnahmen - man kann in einem globalen Zeiger die Adresse einer Variablen in Callstack A sichern und dann in Thread B verwenden, aber hier verletzen wir dann im schlimmsten Fall den syncronisierten Zugriff auf gemeinsame Variablen - das ist so, als würden zwei Schüler während eines Tests immer wieder auf dem Blatt des anderen rumkritzeln.
Ob jetzt die Größe des Callstacks immer zu Anfang gegeben sein muss, weiß ich nicht - da
CreateThread
in der Win-API allerdings einen Parameter für diese Größe übernimmt, gehe ich stark davon aus. In diesem Fall kann der Stack kaum in den Speicher des Heaps schreiben, denn vorher würde der Kernel dies bemerken und einen StackOverflow oder AccessViolation-Fehler bemerken. Zudem kann man in den Linkeroptionen (zur Verdeutlichung: der Linker an sich bestimmt, was das Programm am Ende machen darf - Stack-Commit-Größe, Heap-Max-Size - einfach mal schauen)-
-
Was wolltest Du uns jetzt damit sagen?
-
Mechanics schrieb:
Naja, lies es dir selber durch, wenn es dich im Detail interessiert:
http://www.invisiblethingslab.com/resources/misc-2010/xorg-large-memory-attacks.pdf
Und was hat das bitte mit Windows API zu tun?
Kurz und gut: Auf einem Windows-System kann (augrund der Guardpages) der Stack nimals in den Heap hineinlaufen.