COBOL에서 중복 파일 열기 및 닫기 감지

COBOL에서 중복 파일 열기 및 닫기를 감지하는 방법: 정적 분석 접근법

인컴 2026 년 7 월 22 일 , , ,

COBOL에서 파일 처리는 겉보기에는 매우 간단합니다. 환경(ENVIRONMENT) 부서에서 파일을 선언하고, 데이터(DATA) 부서에서 레코드 레이아웃을 정의하고, 프로시저(PROCEDURE) 부서에서 OPEN, READ, WRITE, CLOSE 문을 사용하면 됩니다. 네 가지 동사, 하나의 생명주기. 하지만 문제는 COBOL 프로그램이 단순한 상태를 유지하는 경우가 드물다는 것입니다. 수십 년에 걸친 유지보수 과정에서 논리, 예외 처리 경로, 조건 분기, PERFORM 호출 등이 누적됩니다. 처음에는 깔끔하게 한 번 열고 한 번 닫는 패턴으로 시작했던 것이, 하나의 실행 경로에서 파일이 두 번 열리거나, 파일이 열려 있지 않을 때에도 CLOSE 문이 실행되거나, CLOSE 문을 완전히 건너뛰고 분기하는 오류 종료 루틴이 생겨나는 등, 점점 더 복잡해집니다.

이러한 문제들은 당장 눈에 띄지 않습니다. 프로그램은 컴파일되고, 테스트한 입력값에 대해서는 오류 없이 실행되는 경우가 많습니다. 예상치 못한 입력 조합에서는 조용히 오류가 발생하거나, 배치 처리 창 성능이 서서히 저하되어 아무도 원인과 결과를 연결시키지 못합니다. 하지만 정적 분석을 통해 이러한 문제가 발생하기 전에 발견할 수 있습니다.

모든 언어에서 정보 유출 감지

SMART TS XL 코드베이스 전체에 걸쳐 오래 지속되는 참조 체인과 무한 데이터 구조를 매핑합니다.

더 많은 정보

파일 상태 관련해서 꼭 알아둬야 할 네 가지 결함

탐지 메커니즘을 살펴보기 전에, 여러분이 찾아야 할 문제의 명확한 분류 체계를 먼저 제시하겠습니다. 모든 COBOL 파일 문제가 동일한 것은 아닙니다.

결함실행 시간에 무슨 일이 일어날까요?심각도
더블 오픈이미 열려 있는 파일을 다시 열려고 하면 파일 상태 코드 41이 발생하거나 비정상 종료됩니다. 높음
사전 열림 없이 닫기한 번도 열어보지 않은 파일을 닫으면 → 파일 상태 코드 42 또는 비정상 종료 발생 높음
정상 종료 시 닫기 버튼이 누락되었습니다.STOP RUN 명령 실행 후 파일이 열려 있는 경우 운영체제가 파일을 닫지만, 버퍼가 플러시되지 않으면 데이터 손실 위험이 있습니다.중급
오류 종료 시 CLOSE가 누락되었습니다.프로그램이 파일을 연 상태에서 비정상 종료됨 → VSAM 파일의 레코드 손상 가능성 있음 높음
반복적인 열기/닫기 동작매 반복마다 파일을 열고 닫음 → 심각한 I/O 오버헤드중간 고

핵심 요점: 가장 심각한 결함인 OPEN 호출 두 번과 OPEN 호출 없이 CLOSE 호출이 발생하는 경우, 즉각적인 런타임 오류 또는 데이터 무결성 위험이 발생합니다. 성능 결함(루프 수준의 open/close 호출)은 오류를 전혀 발생시키지 않고, 원인을 파악하지 못한 배치 작업 속도 저하만 초래합니다.

수동으로 찾기 어려운 이유는 무엇일까요?

문제는 패턴을 파악하는 것이 아닙니다. 모든 개발자는 파일을 두 번 열면 안 된다는 것을 알고 있습니다. 진짜 문제는 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.

모든 실행 경로를 추적하지 않고도 결함을 찾아낼 수 있습니까? WS-ERROR-FLAG 내부는 1로 설정되어 있습니다. PROCESS-ONE-RECORD (아마도 호출된 서브프로그램에 의해) 제어 흐름은 다음과 같습니다. ERROR-EXIT파일을 닫고 중지하는 것입니다. 맞습니다. 하지만 만약 WS-ERROR-FLAG is 지원 설정되면 루프가 완료됩니다. PROCESS-RECORDS 반환하고, TERMINATION 실행되며, 이는 또한 종료됩니다. CUSTOMER-FILE닫힘 2개, 열림 1개. 런타임 파일 상태 42.

이것은 간단한 세 부분으로 구성된 프로그램입니다. 하지만 실제 프로그램은 스무 개의 부분으로 이루어져 있고, 조건부 PERFORM 호출, 레거시 코드의 GO TO 문, 그리고 다른 루틴을 호출하는 예외 처리 루틴까지 포함합니다. 수동 추적은 오류 발생 가능성이 높을 뿐만 아니라, 실제로 실행하기 어렵습니다.


정적 분석 모델은 파일 상태를 어떻게 저장하나요?

정적 분석은 프로그램의 제어 흐름 그래프를 구성하고 모든 경로를 따라 파일 상태를 전파함으로써 이러한 결함을 감지합니다 .

이 분석에서는 각 파일에 세 가지 가능한 값을 가진 상태 변수를 할당합니다.

  • CLOSED파일이 열리지 않았거나 성공적으로 닫혔습니다.
  • OPEN파일이 열려 있고 아직 닫히지 않았습니다.
  • UNKNOWN상태를 정적으로 결정할 수 없습니다(예: 분기 조건부 개방이 완전히 분석되지 않은 경우).

각 OPEN 문에서 분석은 다음 사항을 확인합니다. 이 파일이 이미 해당 상태인지 여부 OPEN? 만약 그렇다면 → 이중 개방 결함입니다.

각 CLOSE 문에서: 이 파일이 현재 상태인지 확인합니다. CLOSED or UNKNOWN? 닫힘 → 열린 결함 없이 닫힘.

STOP RUN 또는 EXIT PROGRAM으로 이동하는 각 경로에서 파일이 여전히 해당 상태에 있는지 확인합니다. OPEN? 그렇다면 → 누락된 유사 결함입니다.

반복문의 경우, 분석에서는 OPEN 또는 CLOSE 문이 반복문 헤더에 의해 지배되는지, 즉 모든 반복에서 실행되는지 확인합니다.

조심해: 분석 도구에게 가장 어려운 경우는 공유 루틴에 대한 PERFORM 호출입니다. ERROR-HANDLER PERFORM 함수는 프로그램 내 서로 다른 12곳에서 호출되며, PERFORM 호출 시점의 파일 상태에 따라 내부 종료 여부가 결정됩니다. ERROR-HANDLER 정확한지 또는 오류가 있는지 여부를 판단합니다. PERFORM 체인을 통해 상태를 전파하지 않는 분석기는 실제 결함을 놓치는 오탐(false negative)이나 올바른 코드를 잘못 판단하는 오양성(false positive)을 발생시킬 수 있습니다.


루프 레벨 OPEN/CLOSE: 오류 코드 없이 발생하는 성능 결함

이 패턴은 런타임 오류나 파일 상태 이상을 발생시키지 않습니다. 다만 실행 속도가 매우 느려, 필요 이상으로 몇 배나 느릴 수 있습니다.

코볼

      *> 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.

파일이 영역별로 물리적으로 분할되어 있지 않은 한, 이 접근 방식은 불필요한 오버헤드를 발생시킵니다. 실제로는 파일을 한 번 열고 모든 레코드를 읽은 다음 메모리 또는 로직을 통해 필터링을 적용하는 것이 더 효율적입니다.

VSAM 파일에 대한 각 OPEN 작업에는 카탈로그 조회, ACB 초기화 및 버퍼 풀 할당이 포함됩니다. 각 CLOSE 작업에는 버퍼 플러시, 카탈로그 업데이트 및 ACB 해제가 포함됩니다. 리전이 10개인 파일의 경우 이 과정이 한 번이 아닌 10번 반복됩니다. 레코드가 10,000개이고 리전이 1,000개인 파일의 경우 계산량이 엄청나게 증가하게 됩니다.

코볼

      *> 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.

정적 분석은 루프 지배적인 OPEN 및 CLOSE 문을 식별함으로써 이를 감지합니다. 즉, 루프 본문의 모든 실행에서 OPEN 또는 CLOSE 문이 실행되는 경우를 말합니다. 이러한 감지를 위해서는 제어 흐름 그래프가 단순히 문장 순서가 아닌 루프 구조를 나타내야 합니다.


파일 상태: 프로그램의 파일 상태 신호입니다(확인 시).

모든 COBOL 파일 작업은 FILE-CONTROL 항목에 정의된 FILE STATUS 필드를 설정합니다. OPEN, READ, WRITE 및 CLOSE 작업 후 매번 FILE STATUS를 확인하는 프로그램은 런타임에 모든 파일 상태 이상을 감지하고 대응할 수 있습니다. FILE STATUS를 무시하는 프로그램은 눈을 감고 작동하는 것과 같습니다.

체크리스트: 모든 COBOL 개발자가 알아야 할 파일 상태 코드

  • 00성공적으로 완료됨
  • 10파일 끝 (읽기: 더 이상 레코드가 없습니다)
  • 35파일을 찾을 수 없습니다(OPEN INPUT: 파일이 존재하지 않습니다).
  • 41파일이 이미 열려 있습니다(OPEN 상태의 파일에 대해 OPEN을 실행).
  • 42파일이 열려 있지 않습니다 (닫힌 상태의 파일에 대해 CLOSE 또는 READ 명령을 실행함).
  • 47열려 있지 않은 파일에 대해 읽기 시도가 이루어졌습니다. 입력 또는 입출력
  • 48, 열려 있지 않은 파일에 쓰기 시도(OUTPUT, IO 또는 EXTEND)
  • 97파일이 성공적으로 열렸습니다 (IBM 특정 환경).

코볼

       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.

조심해: 흔히 발생하는 유지 관리 오류는 FILE-CONTROL 항목에 FILE STATUS를 선언하면서도 참조하지 않는 것입니다. WS-CUST-FILE-STATUS 프로시저 영역에 있습니다. 이 필드는 모든 파일 작업 후에 채워지지만, 코드가 이를 확인하지 않으면 프로그램은 오류를 무시하고 실행됩니다. 정적 분석을 통해 이러한 패턴(FILE STATUS가 선언되었지만 조건 논리에서 참조되지 않음)을 식별할 수 있습니다.


실제 COBOL 코드에서 결함을 유발하는 세 가지 패턴

패턴 1: 공유 오류 종료 문제

프로그램은 여러 처리 섹션으로 구성되며, 각 섹션에는 자체 오류 처리기가 있습니다. 일부 오류 처리기는 반환하기 전에 파일을 닫습니다. 정상 종료 루틴 또한 파일을 닫습니다. 오류가 발생하고 복구 과정이 오류 처리기를 지나쳐 진행될 경우, 파일이 두 번 닫히게 됩니다.

코볼

       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.

The GO TO TERMINATION 제어권을 직접 이전합니다 TERMINATION자체적으로 실행하는 CLOSE CUSTOMER-FILE파일 상태 42.

해결 방법: 중앙 집중식 종료 루틴 하나를 사용합니다. 모든 종료 경로에서 동일한 루틴을 호출하며, 이 루틴은 파일을 닫기 전에 파일이 열려 있는지 확인합니다.

패턴 2: 조건부 OPEN

파일은 특정 처리 모드가 활성화된 경우에만 조건부로 열립니다. 하지만 닫기 작업은 무조건적으로 수행되며, 파일이 열리지 않은 실행 경로를 포함하여 모든 실행 경로에서 발생합니다.

코볼

       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.

이 결함은 테스트가 항상 전체 모드로 실행될 경우 테스트 과정에서 발견되지 않습니다. 하지만 프로덕션 환경에서 첫 번째 부분 모드 실행 시에 나타납니다.

패턴 3: 컴파일 단위 전반에 걸쳐 실행

CALL을 사용하여 서브프로그램을 호출하는 프로그램에서, 메인 프로그램에서 열린 파일이 서브프로그램으로 전달되어 서브프로그램이 파일을 닫은 후, 메인 프로그램이 다시 파일을 닫는 경우가 발생할 수 있습니다.

코볼

      *> Main program
       CALL 'SUBPROG1' USING CUSTOMER-FILE-STATUS
       *> SUBPROG1 closes CUSTOMER-FILE internally
       CLOSE CUSTOMER-FILE    *> double close

이 패턴은 프로시저 간 분석을 필요로 하며 , 단순한 프로그램 내 분석으로는 감지할 수 없는 CALL 경계를 넘어 파일 상태를 추적하여 서브프로그램의 동작을 파악해야 합니다.


정적 분석기가 이 작업을 제대로 수행하기 위해 필요한 것

모든 정적 분석 도구가 COBOL 파일 상태 분석을 동일한 수준으로 지원하는 것은 아닙니다. 다음은 도구의 기능을 평가하기 위한 체크리스트입니다.

해당 도구는 PERFORM 체인을 지원합니까? COBOL 프로그램은 PERFORM을 사용하여 명명된 단락과 섹션을 호출합니다. PERFORM 대상 내부의 파일 작업은 호출자의 상태 추적에서 확인할 수 있어야 합니다.

해당 도구는 인라인 PERFORM VARYING(루프)을 처리할 수 있습니까? 루프 감지는 루프가 지배적인 OPEN/CLOSE 작업을 식별하는 데 필요합니다.

GO TO 문을 통한 상태 추적이 가능한가요? 기존 COBOL 프로그램은 GO TO 문을 광범위하게 사용합니다. 제어 흐름 그래프에서 GO TO 문을 추적할 수 없는 분석기는 특정 유형의 결함을 놓칠 수 있습니다.

COPY 및 REPLACE 작업을 처리합니까? 파일 처리 코드는 종종 COPY 멤버에 있습니다. 분석 전에 COPY 멤버를 확장하지 않는 분석기는 포함된 코드에 정의된 작업을 놓칠 수 있습니다.

FILE STATUS 사용 여부를 확인합니까? 완전한 분석은 FILE STATUS가 선언되었는지 여부뿐만 아니라 각 작업 후에 실제로 확인되었는지 여부도 확인합니다.

이 프로그램은 프로시저 간 분석을 수행합니까? 파일 작업을 수행하는 호출된 서브프로그램은 프로그램 간 상태 종속성을 생성합니다. 진정한 코드 커버리지를 위해서는 호출 체인을 추적해야 합니다.

핵심 요점: 단일 단락이나 섹션 내에서만 검사하는 도구는 대부분의 실제 결함을 놓칠 수 있습니다. 실제 운영 환경에서 중요한 결함, 즉 발견하는 데 수년이 걸리고 진단하는 데 몇 시간이 걸리는 결함은 여러 섹션, 조건 분기 및 호출 루틴에 걸쳐 있는 결함입니다.


결과를 어떻게 활용할 것인가: 우선순위 설정 프레임워크

정적 분석을 통해 파일 결함이 발견될 때, 모든 결함이 동일한 중요성을 갖는 것은 아닙니다. 결함을 분류하는 방법은 다음과 같습니다.

(다음 배치 실행 전에) 즉시 수정하십시오.

  • 파일 상태 코드 41이 비정상 종료를 유발하는 실행 경로에서 이중 OPEN을 실행하면 오류가 발생합니다.
  • 프로덕션 환경에서 실행되는 경로에서 OPEN 없이 CLOSE를 사용합니다.
  • VSAM 파일의 오류 종료 경로에 CLOSE 명령이 누락되어 쓰기 무결성 위험이 있습니다.

다음 스프린트 일정:

  • 루프 중심의 OPEN/CLOSE 동작으로 배치 윈도우에 상당한 영향을 미침
  • 중요 파일(감사, 거래, 보고서)에 대한 파일 상태 확인이 누락되었습니다.
  • 다중 모드 프로그램에서 조건부 열기와 무조건 닫기

다음 현대화 과정에서 추적 및 처리될 사항:

  • 파일 상태 선언 누락
  • 정상적인 종료 경로에서만 닫기 버튼을 사용하십시오 (운영체제에서 처리하지만 권장하지 않는 방식입니다).
  • 여러 프로그램에 걸쳐 변경 사항을 조정해야 수정이 가능한 절차 간 결함

방법 SMART TS XL COBOL 파일 상태를 분석합니다.

SMART TS XL의 정적 코드 분석 이 도구는 환경 내 모든 COBOL 프로그램의 제어 흐름 모델을 구축합니다. COPY 멤버를 확장하고, PERFORM 체인을 따라가며, GO TO 문을 추적하고, 모든 조건문의 모든 분기를 통해 파일 상태를 전달합니다. 이는 패턴 매칭 방식의 스캔이 아니라, 프로그램 실행 과정에서 도달 가능한 모든 지점에서 프로그램이 실제로 수행하는 작업을 구조적으로 모델링하는 것입니다.

애플리케이션 종속성 매핑 기능은 이를 프로시저 간 차원으로 확장합니다. COBOL 프로그램이 파일 작업을 수행하는 서브프로그램을 호출할 때, 종속성 맵은 해당 관계를 나타내어 컴파일 단위 경계를 넘나드는 분석을 가능하게 합니다. 메인 프로그램과 호출된 서브프로그램에 걸쳐 있는 이중 OPEN 결함은 프로그램 내 분석에서는 볼 수 없는 방식으로 구조 모델에서 확인할 수 있습니다.

엔터프라이즈 검색 기능을 통해 대규모로 실행 가능한 결과를 얻을 수 있습니다. 특정 데이터 세트를 여는 모든 프로그램, CLOSE 문을 포함하는 모든 COPY 멤버, OPEN 문을 포함하는 PERFORM 타겟이 있는 모든 프로그램을 수백만 줄의 COBOL 코드에서 단 몇 초 만에 찾을 수 있습니다. 배치 워크로드를 클라우드로 마이그레이션하려는 현대화 팀에게 이 검색 기능은 몇 주가 걸리던 수동 감사 작업을 목표 지향적인 쿼리로 바꿔줍니다.

JCL 확장 기능은 운영 컨텍스트를 추가합니다. 즉, 어떤 JCL 작업 단계에서 각 프로그램이 호출되는지, 각 DD 문이 어떤 데이터 세트를 참조하는지, 그리고 COBOL 코드의 파일 처리가 JCL에 정의된 물리적 데이터 세트와 어떻게 연결되는지를 알 수 있습니다. JCL에서 중요 출력 데이터 세트로 정의된 파일에 대한 CLOSE 결함은 임시 작업 파일에 대한 동일한 결함보다 우선순위가 높으며, 이러한 우선순위를 파악하려면 각 COBOL 프로그램의 JCL 컨텍스트를 알아야 합니다.


더 넓은 관점에서 보면, 파일 상태는 단지 하나의 차원일 뿐이다.

중복된 파일 작업은 보다 일반적인 문제의 구체적인 사례입니다. 수십 년에 걸쳐 발전해 온 COBOL 프로그램에는 파일 상태, 스위치 상태, 카운터 상태와 같은 상태 종속적인 동작이 포함되어 있는데, 이러한 동작은 전체 제어 흐름 그래프를 통해 가능한 모든 실행 경로를 추적해야만 정확하게 이해할 수 있습니다.

이러한 유형의 코드에 대한 사람의 검토는 느리고 불완전하며 일관성이 없습니다. 개발자마다 발견하는 결함이 다르고, 같은 개발자라도 같은 프로그램을 두 번 검토하면 다른 결함을 발견할 수 있습니다. 정적 분석은 체계적입니다. 피로감이나 추측 없이 모든 프로그램의 모든 경로에 항상 동일한 규칙을 적용합니다.

대규모 COBOL 포트폴리오를 관리하는 팀에게 있어, 지속적인 유지 관리, 레거시 현대화 프로그램 또는 규정 준수 감사 등 어떤 목적이든 체계적인 파일 상태 분석의 이점은 단순히 결함을 발견하는 데 그치지 않습니다. 포트폴리오가 완벽하게 분석되었으며, 남아 있는 결함이 숨겨진 것이 아니라 정확히 파악되었다는 확신을 얻을 수 있다는 것이 진정한 이점입니다.