Die Dateiverarbeitung in COBOL wirkt auf den ersten Blick täuschend einfach. Man deklariert eine Datei in der ENVIRONMENT DIVISION, beschreibt ihr Datensatzlayout in der DATA DIVISION und verwendet OPEN, READ oder WRITE sowie CLOSE in der PROCEDURE DIVISION. Vier Verben, ein Lebenszyklus. Das Problem ist, dass COBOL-Programme selten einfach bleiben. Über Jahrzehnte der Wartung häufen sich Logik, Ausnahmebehandlungspfade, bedingte Verzweigungen und PERFORM-Aufrufe an. Was als sauberes Muster mit einmaligem Öffnen und Schließen beginnt, mutiert stillschweigend zu etwas Komplexerem: Dateien werden innerhalb eines einzigen Ausführungspfads zweimal geöffnet, CLOSE-Anweisungen werden ausgeführt, obwohl keine Datei geöffnet ist, und Fehlerbehandlungen verlassen den Zweig, der die CLOSE-Anweisung komplett überspringt.
Keines dieser Probleme ist sofort erkennbar. Das Programm lässt sich kompilieren. Es läuft oft fehlerfrei mit den getesteten Eingaben. Bei unerwarteten Eingabekombinationen schlägt es jedoch stillschweigend fehl oder verschlechtert die Stapelverarbeitungsleistung so schleichend, dass niemand den Zusammenhang zwischen Ursache und Wirkung erkennt. Die statische Analyse deckt diese Probleme auf, bevor es dazu kommt.
Leckerkennung in allen Sprachen
SMART TS XL Bildet langlebige Referenzketten und unbegrenzte Datenstrukturen über Ihre gesamte Codebasis ab.
Mehr InfosDie vier Aktenmängel, die es wert sind, entdeckt zu werden
Bevor wir uns mit den Erkennungsmechanismen befassen, hier eine klare Kategorisierung dessen, wonach Sie suchen. Nicht alle Probleme mit COBOL-Dateien sind gleich.
| Defekt | Was passiert zur Laufzeit? | Schwere |
|---|---|---|
| Doppelt geöffnet | Öffnen einer bereits geöffneten Datei → Dateistatus 41 oder Abbruch | Hoch |
| GESCHLOSSEN ohne vorheriges ÖFFNEN | Schließen einer Datei, die nie geöffnet wurde → Dateistatus 42 oder Abbruch | Hoch |
| Fehlendes CLOSE beim normalen Beenden | Datei bleibt beim Startvorgang geöffnet → Das Betriebssystem schließt sie, aber nicht geleerte Puffer bergen das Risiko von Datenverlust. | Medium |
| Fehlende CLOSE-Anweisung beim Beenden aufgrund eines Fehlers | Programmabbruch bei geöffneter Datei → mögliche Beschädigung von VSAM-Dateien | Hoch |
| Redundantes Öffnen/Schließen in einer Schleife | Datei wird bei jeder Iteration geöffnet und geschlossen → erheblicher E/A-Overhead | Medium-High |
Wichtigste Erkenntnis: Die schwerwiegendsten Fehler, doppeltes Öffnen und Schließen ohne vorheriges Öffnen, führen zu sofortigen Laufzeitfehlern oder Gefährdungen der Datenintegrität. Die Leistungsfehler (Öffnen/Schließen auf Schleifenebene) verursachen keinerlei Fehler, sondern lediglich langsame Batch-Jobs, deren Ursache bisher nicht ermittelt werden konnte.
Warum ist das manuell so schwer zu finden?
Die Herausforderung besteht nicht darin, das Muster zu erkennen. Jeder Entwickler weiß, dass man eine Datei nicht zweimal öffnen sollte. Die Herausforderung liegt vielmehr darin, dass der COBOL-Kontrollfluss nichtlinear ist und daher eine manuelle Nachverfolgung unzuverlässig macht.
Betrachten wir ein Programm mit folgender Struktur:
Cobol
PROCEDURE DIVISION.
MAIN-LOGIC.
PERFORM INITIALIZATION
PERFORM PROCESS-RECORDS
PERFORM TERMINATION
STOP RUN.
INITIALIZATION.
OPEN INPUT CUSTOMER-FILE
OPEN OUTPUT REPORT-FILE
MOVE 0 TO WS-ERROR-FLAG.
PROCESS-RECORDS.
READ CUSTOMER-FILE INTO WS-CUSTOMER-REC
AT END MOVE 1 TO WS-EOF-FLAG
END-READ
IF WS-ERROR-FLAG = 1
PERFORM ERROR-EXIT
END-IF
PERFORM UNTIL WS-EOF-FLAG = 1
PERFORM PROCESS-ONE-RECORD
READ CUSTOMER-FILE INTO WS-CUSTOMER-REC
AT END MOVE 1 TO WS-EOF-FLAG
END-EXEC
END-PERFORM.
ERROR-EXIT.
DISPLAY 'Error in processing'
CLOSE CUSTOMER-FILE *> CLOSE here...
STOP RUN.
TERMINATION.
CLOSE CUSTOMER-FILE *> ...and CLOSE here too
CLOSE REPORT-FILE
STOP RUN.
Lässt sich der Fehler erkennen, ohne jeden Ausführungspfad zu verfolgen? Wenn WS-ERROR-FLAG ist innen auf 1 eingestellt PROCESS-ONE-RECORD (möglicherweise durch ein aufgerufenes Unterprogramm) werden die Kontrollflüsse zu ERROR-EXITDadurch wird die Datei geschlossen und der Vorgang beendet. Das ist richtig. Aber wenn WS-ERROR-FLAG is kein Frontalunterricht. Die Schleife wird beendet. PROCESS-RECORDS zurück, und TERMINATION Läufe, die auch schließen CUSTOMER-FILEZwei geschlossene, eine geöffnete Datei. Laufzeit-Dateistatus 42.
Dies ist ein einfaches Programm mit drei Abschnitten. Reale Programme umfassen zwanzig Abschnitte, bedingte PERFORM-Aufrufe, GO TO-Anweisungen in älterem Code und Ausnahmebehandlungsroutinen, die ihrerseits andere Routinen aufrufen. Manuelles Tracing ist nicht nur fehleranfällig, sondern auch nicht praktikabel.
Wie statische Analysemodelle Dateistatus
Die statische Analyse erkennt diese Fehler, indem sie einen Kontrollflussgraphen des Programms erstellt und den Dateistatus entlang jedes Pfades weitergibt.
Die Analyse ordnet jeder Datei eine Zustandsvariable mit drei möglichen Werten zu:
CLOSEDDie Datei wurde nicht geöffnet oder erfolgreich geschlossen.OPENDie Datei wurde geöffnet und noch nicht geschlossen.UNKNOWNDer Zustand kann nicht statisch bestimmt werden (z. B. bedingtes Öffnen in einem Zweig, der nicht vollständig analysiert wurde).
Bei jeder OPEN-Anweisung prüft die Analyse: Befindet sich diese Datei bereits im Zustand OPENFalls ja → doppelter OFFEN-Defekt.
Bei jeder CLOSE-Anweisung: Befindet sich diese Datei im Zustand CLOSED or UNKNOWN? Falls GESCHLOSSEN → Schließen ohne offenen Defekt.
Bei jedem Pfad zum Stoppen oder Beenden des Programms: Befindet sich noch eine Datei im Zustand OPENFalls ja → fehlender Nahfehler.
Bei Schleifen prüft die Analyse, ob eine OPEN- oder CLOSE-Anweisung von einem Schleifenkopf dominiert wird, was bedeutet, dass sie bei jeder Iteration ausgeführt wird.
Achtung: Die schwierigsten Fälle für jeden Analysator sind PERFORM-Aufrufe in gemeinsam genutzte Routinen. Wenn
ERROR-HANDLERDie Funktion wird von zwölf verschiedenen Stellen im Programm aufgerufen; der Dateistatus zum Zeitpunkt des PERFORM-Aufrufs bestimmt, ob die Datei innerhalb des Programms geschlossen wird.ERROR-HANDLERist korrekt oder fehlerhaft. Ein Analysator, der den Zustand nicht durch PERFORM-Ketten weitergibt, erzeugt entweder falsch negative Ergebnisse (übersehene echte Fehler) oder falsch positive Ergebnisse (Kennzeichnung von korrektem Code).
Der Schleifenfehler OPEN/CLOSE: Ein Leistungsdefekt ohne Fehlercode
Dieses Muster erzeugt weder einen Laufzeitfehler noch eine Dateistatusanomalie. Es läuft lediglich langsam, möglicherweise um Größenordnungen langsamer als nötig.
Cobol
*> PROBLEMATIC: file opened and closed on every iteration
PROCESS-ALL-REGIONS.
PERFORM VARYING WS-REGION-ID FROM 1 BY 1
UNTIL WS-REGION-ID > 10
OPEN INPUT CUSTOMER-FILE
PERFORM PROCESS-REGION-RECORDS
CLOSE CUSTOMER-FILE
END-PERFORM.
Sofern die Datei nicht physisch nach Regionen partitioniert ist, verursacht dieser Ansatz unnötigen Overhead. In der Praxis ist es besser, die Datei einmal zu öffnen, alle Datensätze zu lesen und die Filterung im Arbeitsspeicher oder logisch anzuwenden.
Jeder OPEN-Vorgang einer VSAM-Datei beinhaltet eine Katalogabfrage, die Initialisierung des ACB und die Zuweisung des Pufferpools. Jeder CLOSE-Vorgang leert die Puffer, aktualisiert den Katalog und gibt den ACB frei. Bei einer Datei mit zehn Regionen geschieht dies zehnmal statt nur einmal. Bei einer Datei mit 10,000 Datensätzen und tausend Regionen wird die Berechnung entsprechend aufwendig.
Cobol
*> CORRECT: open once, filter inside the loop
PROCESS-ALL-REGIONS.
OPEN INPUT CUSTOMER-FILE
PERFORM VARYING WS-REGION-ID FROM 1 BY 1
UNTIL WS-REGION-ID > 10
PERFORM PROCESS-REGION-RECORDS
END-PERFORM
CLOSE CUSTOMER-FILE.
Die statische Analyse erkennt dies, indem sie OPEN- und CLOSE-Anweisungen identifiziert, die schleifendominiert sind, d. h. bei jeder Ausführung des Schleifenkörpers wird die OPEN- oder CLOSE-Anweisung ausgeführt. Die Erkennung erfordert, dass der Kontrollflussgraph die Schleifenstruktur und nicht nur die Anweisungsfolge darstellt.
DATEISTATUS: Das Dateistatussignal Ihres Programms, falls Sie es überprüfen
Bei jeder COBOL-Dateioperation wird das im FILE-CONTROL-Eintrag definierte Feld FILE STATUS gesetzt. Ein Programm, das FILE STATUS nach jedem Öffnen, Lesen, Schreiben und Schließen prüft, kann jede Anomalie des Dateistatus zur Laufzeit erkennen und darauf reagieren. Ein Programm, das FILE STATUS ignoriert, agiert im Blindflug.
Checkliste: Dateistatuscodes, die jeder COBOL-Entwickler kennen sollte
00Erfolgreicher Abschluss10Dateiende (LESEN: keine weiteren Datensätze)35Datei nicht gefunden (OPEN INPUT: Datei existiert nicht)41Datei bereits geöffnet (OPEN für eine Datei im Status OPEN)42Datei nicht geöffnet (CLOSE oder READ für eine Datei im Status CLOSED)47Leseversuch für nicht geöffnete Datei (Eingabe oder E/A).48, Schreibversuch in nicht geöffneter Datei (OUTPUT, IO oder EXTEND)97Datei erfolgreich geöffnet (IBM-spezifisch, einige Umgebungen)
Cobol
FILE-CONTROL.
SELECT CUSTOMER-FILE
ASSIGN TO CUSTFILE
FILE STATUS IS WS-CUST-FILE-STATUS.
WORKING-STORAGE SECTION.
01 WS-CUST-FILE-STATUS PIC XX.
PROCEDURE DIVISION.
OPEN INPUT CUSTOMER-FILE
IF WS-CUST-FILE-STATUS NOT = '00'
DISPLAY 'OPEN failed: ' WS-CUST-FILE-STATUS
PERFORM ABEND-ROUTINE
END-IF.
Achtung: Ein häufiger Wartungsfehler besteht darin, den Dateistatus im Dateisteuerungseintrag anzugeben, aber nie darauf zu verweisen.
WS-CUST-FILE-STATUSIm Prozedurabschnitt wird das Feld nach jeder Dateioperation befüllt. Wird es jedoch nicht im Code geprüft, werden Fehler stillschweigend ignoriert. Eine statische Codeanalyse kann dieses Muster erkennen: Der Dateistatus ist deklariert, wird aber in der bedingten Logik nie verwendet.
Drei in der Praxis häufig auftretende COBOL-Fehlermuster
Muster 1: Das gemeinsame Fehler-Exit-Problem
Ein Programm verfügt über mehrere Verarbeitungsabschnitte, von denen jeder eine eigene Fehlerbehandlung besitzt. Mehrere Fehlerbehandlungsroutinen schließen die Datei, bevor sie zurückkehren. Auch die normale Beendigungsroutine schließt die Datei. Tritt ein Fehler auf und wird die Fehlerbehebung über die Fehlerbehandlung hinaus fortgesetzt, wird die Datei zweimal geschlossen.
Cobol
VALIDATE-RECORDS.
READ CUSTOMER-FILE INTO WS-REC
AT END MOVE 1 TO WS-EOF
END-READ
IF WS-CUST-FILE-STATUS NOT = '00' AND '10'
CLOSE CUSTOMER-FILE *> closes here on read error
PERFORM WRITE-ERROR-LOG
GO TO TERMINATION *> skips to close in TERMINATION?
END-IF.
TERMINATION.
CLOSE CUSTOMER-FILE *> double close if GO TO reached here
CLOSE REPORT-FILE
STOP RUN.
Das GO TO TERMINATION überträgt die Kontrolle direkt an TERMINATION, das seine eigenen CLOSE CUSTOMER-FILEDATEISTATUS 42.
Lösung: Verwenden Sie eine zentrale Schließroutine. Jeder Exit-Pfad ruft dieselbe Routine auf, die vor dem Schließen prüft, ob die Datei geöffnet ist.
Muster 2: Die bedingte OPEN-Anweisung
Eine Datei wird nur dann bedingt geöffnet, wenn ein bestimmter Verarbeitungsmodus aktiv ist. Das Schließen (CLOSE) hingegen erfolgt bedingungslos in jedem Ausführungspfad, auch in solchen, in denen die Datei nie geöffnet wurde.
Cobol
INITIALIZATION.
IF WS-PROCESSING-MODE = 'FULL'
OPEN OUTPUT AUDIT-FILE *> only opened in FULL mode
END-IF.
TERMINATION.
CLOSE AUDIT-FILE *> ALWAYS closes -- FILE STATUS 42 in PARTIAL mode
STOP RUN.
Dieser Fehler ist bei Tests, die immer im VOLLSTÄNDIGEN Modus ausgeführt werden, nicht sichtbar. Er tritt im Produktivbetrieb beim ersten Durchlauf im TEILWEISEM Modus auf.
Muster 3: PERFORM über Kompilierungseinheiten hinweg
In Programmen, die CALL zum Aufrufen von Unterprogrammen verwenden, kann eine im Hauptprogramm geöffnete Datei an ein Unterprogramm übergeben werden, das sie schließt, woraufhin das Hauptprogramm sie wieder schließt.
Cobol
*> Main program
CALL 'SUBPROG1' USING CUSTOMER-FILE-STATUS
*> SUBPROG1 closes CUSTOMER-FILE internally
CLOSE CUSTOMER-FILE *> double close
Dieses Muster erfordert eine interprozedurale Analyse , bei der der Dateistatus über die CALL-Grenze hinweg bis in das Verhalten des Unterprogramms verfolgt wird, was mit einer einfachen intra-prozeduralen Analyse nicht erkannt werden kann.
Was ein statischer Analysator für diese Aufgabe leisten muss
Nicht alle statischen Analysetools bieten die gleiche Tiefe bei der Zustandsanalyse von COBOL-Dateien. Hier ist eine Checkliste zur Beurteilung der Leistungsfähigkeit:
Unterstützt das Tool PERFORM-Ketten? COBOL-Programme verwenden PERFORM, um benannte Absätze und Abschnitte aufzurufen. Dateioperationen innerhalb eines PERFORM-Ziels müssen für die Statusverfolgung des Aufrufers sichtbar sein.
Kann das Tool Inline-PERFORM-VARYING-Operationen (Schleifen) verarbeiten? Die Schleifenerkennung ist erforderlich, um schleifendominierte OPEN/CLOSE-Operationen zu identifizieren.
Verfolgt es den Zustand über GO TO-Anweisungen hinweg? Ältere COBOL-Programme verwenden GO TO häufig. Ein Analysator, der GO TO-Kanten im Kontrollflussgraphen nicht verfolgen kann, übersieht ganze Fehlerklassen.
Unterstützt es COPY- und REPLACE-Operationen? Code zur Dateiverarbeitung befindet sich häufig in COPY-Membern. Ein Analysator, der COPY-Member vor der Analyse nicht erweitert, erkennt die im eingebundenen Code definierten Operationen nicht.
Wird die Verwendung von FILE STATUS überprüft? Eine vollständige Analyse prüft nicht nur, ob FILE STATUS deklariert ist, sondern auch, ob es nach jeder Operation tatsächlich überprüft wird.
Führt es eine interprozedurale Analyse durch? Aufgerufene Unterprogramme, die Dateioperationen durchführen, erzeugen programmübergreifende Zustandsabhängigkeiten. Eine vollständige Codeabdeckung erfordert das Verfolgen von Aufrufketten.
Wichtigste Erkenntnis: Ein Tool, das nur einen einzelnen Absatz oder Abschnitt prüft, übersieht die meisten Fehler in der Praxis. Die Fehler, die in der Produktion relevant sind – jene, deren Auftreten Jahre und deren Diagnose Stunden dauern kann –, erstrecken sich über mehrere Abschnitte, bedingte Verzweigungen und aufgerufene Routinen.
Was tun mit den Ergebnissen: Ein Priorisierungsrahmen
Bei der statischen Oberflächenanalyse von Defekten sind die Ergebnisse nicht alle gleichwertig. So priorisieren Sie die Ergebnisse:
Sofort beheben (vor dem nächsten Batchlauf):
- Doppeltes OPEN in einem beliebigen Ausführungspfad, bei dem FILE STATUS 41 einen Abbruch verursachen würde.
- CLOSE ohne OPEN in Pfaden, die in der Produktion ausgeführt werden
- Fehlende CLOSE-Anweisungen bei Fehlerbeendigung von VSAM-Dateien (Risiko für die Schreibintegrität)
Zeitplan für den nächsten Sprint:
- Schleifendominiertes Öffnen/Schließen mit messbarem Einfluss auf das Batch-Fenster
- Fehlende Dateistatusprüfungen bei kritischen Dateien (Audit-, Transaktions-, Berichtsdateien)
- Bedingtes Öffnen mit unbedingtem Schließen in Multimodus-Programmen
Verfolgung und Behebung im nächsten Modernisierungsdurchgang:
- Fehlende FILE STATUS-Deklarationen
- Nur auf normalen Ausgangspfaden schließen (das Betriebssystem kümmert sich darum, aber es ist keine gute Praxis).
- Interprozedurale Fehler, deren Behebung die Koordination von Änderungen in mehreren Programmen erfordert
Wie SMART TS XL Analysiert den COBOL-Dateistatus
SMART TS XL statische Code-Analyse Es erstellt ein Kontrollflussmodell für jedes COBOL-Programm in der Umgebung, indem es COPY-Elemente erweitert, PERFORM-Ketten verfolgt, GO TO-Kanten nachverfolgt und den Dateistatus durch jeden Zweig jeder Bedingung weitergibt. Es handelt sich nicht um einen Mustervergleich, sondern um ein Strukturmodell dessen, was das Programm an jedem erreichbaren Punkt seiner Ausführung tatsächlich tut.
Die Funktion zur Abbildung von Anwendungsabhängigkeiten erweitert dies auf die prozedurübergreifende Dimension: Wenn ein COBOL-Programm ein Unterprogramm aufruft, das Dateioperationen durchführt, stellt die Abhängigkeitsabbildung diese Beziehung dar und ermöglicht so Analysen, die über die Grenzen von Kompilierungseinheiten hinausgehen. Doppelte OPEN-Fehler, die sich über ein Hauptprogramm und ein aufgerufenes Unterprogramm erstrecken, sind im Strukturmodell sichtbar, was bei einer Analyse innerhalb eines Programms nicht der Fall ist.
Die unternehmensweite Suchfunktion ermöglicht die sofortige Nutzung der Ergebnisse in großem Umfang: Finden Sie innerhalb von Sekunden jedes Programm im Portfolio, das einen bestimmten Datensatz öffnet, jedes COPY-Element mit einer CLOSE-Anweisung und jedes Programm mit einem PERFORM-Ziel, das eine OPEN-Anweisung enthält – und das über Millionen von COBOL-Zeilen hinweg. Für ein Modernisierungsteam, das die Migration einer Batch-Workload in die Cloud vorbereitet, verwandelt diese Suchfunktion ein wochenlanges manuelles Audit in eine gezielte Abfrage.
Die JCL-Erweiterungsfunktion fügt den operativen Kontext hinzu: Welche JCL-Jobschritte rufen die einzelnen Programme auf, auf welche Datensätze verweist jede DD-Anweisung und wie die Dateiverarbeitung im COBOL-Code mit den in der JCL definierten physischen Datensätzen verknüpft ist. Ein CLOSE-Fehler in einer Datei, die in der JCL als kritischer Ausgabedatensatz definiert ist, hat eine höhere Priorität als derselbe Fehler in einer temporären Arbeitsdatei. Diese Priorisierung erfordert die Kenntnis des JCL-Kontexts jedes COBOL-Programms.
Die übergeordnete Erkenntnis: Der Dateistatus ist nur eine Dimension
Redundante Dateioperationen sind ein Spezialfall eines allgemeineren Problems: COBOL-Programme, die sich über Jahrzehnte entwickelt haben, enthalten zustandsabhängige Verhaltensweisen, Dateizustände, Schalterzustände, Zählerzustände, die nur dann richtig verstanden werden können, wenn jeder mögliche Ausführungspfad durch den gesamten Kontrollflussgraphen verfolgt wird.
Die manuelle Überprüfung solcher Codeabschnitte ist langsam, unvollständig und inkonsistent. Verschiedene Entwickler finden unterschiedliche Fehler. Selbst derselbe Entwickler, der dasselbe Programm zweimal überprüft, findet unterschiedliche Fehler. Die statische Codeanalyse hingegen ist systematisch: Sie wendet dieselben Regeln auf jeden Pfad in jedem Programm an, jedes Mal, ohne Ermüdung oder Annahmen.
Für Teams, die große COBOL-Portfolios verwalten – sei es für die laufende Wartung, für Modernisierungsprogramme oder für Compliance-Audits –, liegt der Nutzen einer systematischen Dateistatusanalyse nicht nur in den gefundenen Fehlern. Vielmehr bietet sie die Gewissheit, dass das Portfolio vollständig analysiert wurde und die verbleibenden Fehler bekannt und nicht etwa versteckt sind.