DOS WATCOM Stackoverflow
« | 10 Jun 2023 | »Auf die Frage, warum meine Grafikdemo funktioniert und meine Commandline-Tools auf der DOS Plattform häufig crashen, gibt es eine Antwort:
Der Command Line Parser löst Stack-Overflows aus.
Aber warum?
Das beste am Umstieg von DOS auf
Windows NT war, dass man
bei Crashes nicht mehr dauernd den Reset-Knopf drücken musste. Ich nannte
solche DOS Programme damals einfach: Schlecht programmiert.
Denn sie funktionierten und scheiterten abhängig vom verfügbaren
konventionellen Arbeitsspeicher … und der war mit seinem 640 KB Maximum
nicht gerade groß.
Als meine eigenen DOS Kompilate scheiterten, obwohl sie unter Windows und Linux durch alle Tests kamen, stürzte mich das fast in eine Krise. Denn was bringt mir die Portierung von Code auf die DOS Plattform, wenn dann am Ende nichts läuft?
Doch ein zufälliger Blick in die von Watcom
generierten .map
Dateien zeigten auf, dass nur 2 KB Stack im Programm reserviert werden.
Und da am gleichen Datensegment auch noch andere Dinge wie globale Variablen
liegen können führt es zwangsläufig zu Überschneidungen, wenn der Stack seine
engen Grenzen sprengt.
Lösung: Stack vergrößern
Die notwendige Anpassung der Linkerflags war schnell gefunden, als ich
wusste, wo das Problem herkam:
opt stack=32768
vergrößert den reservierten Stackbereich auf 32 KB,
was im Endeffekt ausreichte.
In CMake hängt man das einfach
an die Variable CMAKE_EXE_LINKER_FLAGS
an:
1set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} opt stack=32768")
Fazit
Kleiner Fix, große Wirkung.
Da im GATE Projekt Strings bzw. Stringausschnitte nicht zwingend NUL
-
terminiert sind, müssen Inhalte vor der Übergabe an externe C-Funktionen
(zB. Dateipfade) in einen Puffer kopiert werden, der dann mit einem \0
endet, und das passiert meist auf dem Stack, der somit schnell über 2K
anwachsen kann.
Ich muss aber eingestehen, dass mir mit diesen Crashes vor Augen geführt wurde, dass einige Design-Entscheidungen nicht ideal für bestimmte Plattformen sind. Denn klassische DOS Anwendungen kamen mit wenigen Bytes auf dem Stack aus.
Ob gleich das Problem nun gelöst ist, werde ich im Hinterkopf mal durchdenken, ob ich nicht vielleicht ganz allgemein zu viel auf dem Stack arbeite.