Dies ist ja soweit auch korrekt.
Aber wie alles im Leben werden die Welten schon mal gemischt.
Solange du in der reinen COBOL-Welt bist ist ja auch fast alles OK.

Per Definition war einmal ein Programm das erste in der Rununit.
Bis jemand auf die Idee kam, das Programm mal aus einem anderen COBOL aufzurufen.
Der wunderte sich dass der Aufruf nie zurückkam, da das Programm nun mal einen STOP RUN ausführte.

Umgedreht wurde ein COBOL-Unterprogramm aus einem CLP im Batch aufgerufen.
Das Unterprogramm wusste dies aber nicht und machte nach dem EXIT PROGRAM weiter.
Nun muss man wissen, dass ein "PERFORM LABEL" kein echter Unterprogrammaufruf ist.
Der Compiler generiert einen GOTO "hinter den Perform" am Ende des LABEL/SECTION (ein EXIT mitten in einer SECTION ist wirkungslos).
Folgender Code führt dann zu einer Endlosschleife:

MAIN SECTION.
MAIN-000.
PERFORM SUB
EXIT PROGRAM.

SUB SECTION.
SUB-000.
* mach was
SUB-999.
EXIT.

Der Perform generiert hinter SUB-999 einen GOTO auf das EXIT PROGRAM-Statement.
Der EXIT PROGRAM ist wirkungslos da ja erstes Programm in der RUN UNIT.
Das Programm macht bei SUB SECTION einfach weiter.
Der interne GOTO ist noch aktiv, das Programm macht bei EXIT PROGRAM weiter.

Ein simpler GOBACK oder ein STOP RUN nach dem EXIT PROGRAM hätte das verhindert.