📌 このページの使い方

各落とし穴は独立しています。作業中に発生した問題の症状から該当する項目を探して参照してください。

最適化によるコード境界の消失

⚠️ 症状:シンボルがない / 段落名が消えている
原因

コンパイラの最適化(インライン展開・デッドコード除去)によって、元のソースに存在していた段落名やサブルーチンがバイナリから消えることがあります。特に最適化レベルが高い(-O2 以上)場合に発生します。

対処

再コンパイル時は最適化を無効化(-O0)してシンボルを保持するようにしてください。元のモジュールが最適化ビルドの場合、シンボルが完全に一致しないことは許容し、入出力比較テストで等価性を確認することに注力してください。

EBCDIC・文字コード・行末コードの罠

⚠️ 症状:ファイル転送後にソースが文字化けする / コンパイルエラーになる
原因

メインフレーム(z/OS)のテキストファイルは EBCDIC エンコーディングを使用しています。FTP や SCP でファイルを転送する際に ASCII/UTF-8 への変換が正しく行われないと文字化けします。また、COBOL ソースは固定長80桁形式(カラム1-72がコード、73-80はシーケンス番号)が前提の場合があります。

対処
Shell — EBCDIC → ASCII 変換
# iconv で EBCDIC → UTF-8 変換(IBM037 は EBCDIC US)
iconv -f IBM037 -t UTF-8 source.cbl > source_utf8.cbl

# 行末コードを CRLF → LF に変換
sed -i 's/\r//' source_utf8.cbl

# FTP での転送時はテキストモードを明示する
ftp -n mf-host <<EOF
user userid password
ascii
get 'HLQ.SRC.COBOL(MYPROG)' myprog.cbl
quit
EOF

コンパイラ方言(IBM拡張など)への対応

⚠️ 症状:IBM Enterprise COBOL の構文が GnuCOBOL でコンパイルエラーになる
原因

IBM Enterprise COBOL には標準 COBOL にない拡張構文(EXEC SQLEXEC CICSSERVICE RELOADTITLE 文など)があります。これらは GnuCOBOL では認識されません。

対処

IBM 拡張構文を含む行は *> でコメントアウトして動作確認を進め、必要であれば GnuCOBOL の同等機能(EXEC SQL なら esql プリプロセッサ)に置き換えます。ただし移植・置換作業は PART 09 のモダナイゼーション工程として別途計画してください。

Shell — IBM拡張構文を一覧化
# EXEC SQL / EXEC CICS の行を抽出
grep -in "EXEC\s\+\(SQL\|CICS\)" src/**/*.cbl

# IBM 固有の SERVICE RELOAD
grep -in "SERVICE\s\+RELOAD" src/**/*.cbl

# TITLE 文
grep -in "^\s*TITLE\b" src/**/*.cbl

コピーブック不足によるコンパイルエラー

⚠️ 症状:COPY 文でコンパイルエラー「member not found」
原因

COPY 文で参照しているコピーブックが -I で指定したライブラリパスに存在しない。

対処

コンパイルリストの展開済みソースからコピーブックの内容を逆生成します。

Shell — 不足コピーブックの検出と対処
# ソース中のCOPY参照を全件抽出
grep -riho "COPY\s\+['\"]\\?[A-Z0-9-]\+" src/ | grep -oE "[A-Z0-9-]{2,}$" | sort -u > required_copybooks.txt

# 実在するコピーブックを列挙
find copybook/ -type f | xargs -I{} basename {} .cpy | sort -u > existing_copybooks.txt

# 不足しているコピーブックを表示
comm -23 required_copybooks.txt existing_copybooks.txt

動的 CALL が見つからない

⚠️ 症状:実行時に「program not found」エラーが発生する
原因

動的 CALL(CALL WS-PROG-NAME のように変数でプログラム名を指定)は静的解析で検出できません。実行時に環境変数 COB_LIBRARY_PATH で指定したディレクトリに対象モジュールが存在しない場合に発生します。

対処
Shell — 動的CALL検出と実行時パス設定
# 動的 CALL の変数名を抽出(静的CALL除外)
grep -iE "CALL\s+[A-Z][A-Z0-9-]*\b" src/**/*.cbl | grep -v "CALL\s*'"

# 実行時ライブラリパスの設定
export COB_LIBRARY_PATH=./lib:./sub

# 動的ロードで見つからないモジュールを COB_SET_TRACE で特定
COB_SET_TRACE=Y ./myprogram 2>&1 | grep "CALL\|not found"

次の章では…

PART 09 では、分離・検証が完了した後の次のステップ(Git管理・モダナイゼーション・ドキュメント化)を解説します。

→ PART 09 — 分離後の次のステップへ