JCL

JCL を介した PL/I アプリケーションの実行時に発生する可能性のある異常終了コードについて説明します。
S422 異常終了
S422 異常終了の最も一般的な原因は、DISP が (NEW,CATLG) のデータセットでジョブを再実行しようとしたときに、そのデータセットがカタログにすでに存在していることです。通常、console.log または joblog で失敗したジョブを確認すると、どのファイルが原因であるかを示すメッセージが表示されます。
S806 異常終了
このエラーは、通常、CAS_BATCH_PATH 環境変数で設定されたディレクトリまたは JCL ジョブ ステップの STEPLIB で参照されるディレクトリ (あるいはその両方) にファイルが存在しないことを意味します。
注: CAS_BATCH_PATH は環境変数として設定できますが、一般には、ESCWA の [JES] タブの [JES Program Path] フィールドで設定します。

これを解決するには、次の手順に従います。

  1. 参照されるディレクトリのいずれかに .dll (Windows) または .so (UNIX) ファイルが存在することを確認してください。
    注: Linux/UNIX プラットフォーム上のファイルの場合は、ファイル拡張子の前のファイル名が大文字であることを確認してください。たとえば、PROG1 という名前のプログラムを含むファイルの名前は PROG1.so になります。
  2. プログラムが CAS_BATCH_PATH (デフォルト) から実行されているか STEPLIB から実行されているかを確認します。STEPLIB の場合、検索順序は STEPLIB で指定されたディレクトリが最初で、次に CAS_BATCH_PATH 環境変数で設定されたディレクトリが続きます。適切な命名規則のファイルが適切なディレクトリに存在することを確認してください。
  3. 特に Linux/UNIX プラットフォームでは、作成された .so ファイルが適切な形式であることを確認してください。これを行うには、file PROG1.so コマンドを発行します。これにより、PROG1.so が変更されて共有オブジェクトになり、同じディレクトリに格納されます。出力はオペレーティング システムによって異なりますが、正常に動作することがわかっている共有オブジェクトと比較して相違点を確認できます。

    (さらに、32 ビットのサーバーを作成したが共有オブジェクトが 64 ビットである場合やその逆の場合についても確認できます)

  4. 共有オブジェクトのビット体系がサーバーと同じであることを確認してください。たとえば、32 ビットのサーバーで 64 ビットの共有オブジェクトを使用している場合やその逆の場合についてです。
これらの手順を実行しても問題が解決しない場合は、依存する .so または .dll ファイルが見つからないか、同様の問題が発生している可能性があります。これらの問題を特定する最も簡単な方法は、次の COBOL RTS CTF トレースを追加することです。
  • #pgmsearch
  • #pgmload
  • #fsys
これらを追加して問題を再現すると、検索した .so または .dll ファイルと検索するためにアクセスしたディレクトリが出力に表示されます。欠落している .so または .dll ファイルが特定されると、ロードのトレースでファイル名が示されます。次に例を示します。
16:36:04.793 MF.RTS 251 3 : 8 "ZZZIWCS.so" "ZZZIWCS.so: undefined symbol: TRCIWWR"
16:36:04.793 MF.RTS 6 1 : 81 16387 "idamjrm" "MVS_JOB_STEP_RESOURCE_MGR"

太字の数字の意味を確認するには、テキスト エディターを使用して %ProgramFiles(x86)%\Micro Focus\Enterprise Developer\etc\mftrace\annotations(Windows) または /opt/microfocus/EnterpriseDeveloper\etc\mftrace\annotations(UNIX) にある MF.RTS.xml ファイルを開きます。ファイルを開いたら、1 つ目の数字と同じイベント ID を示す行を見つけます。次に例を示します。

<Event Id="251" Description="Program Load Error">

次に、引数のケースのインデックスが 2 つ目の数字と一致する行を見つけます。次に例を示します。

<ArgumentCase Index="0" Value="8" Description="Error (DLL_LOAD_FAIL)"/>

この例は、共有オブジェクト ZZZIWCS.so の DLL ロードが失敗したことを示しています。元のメッセージで指定されている理由は次のとおりです。 undefined symbol: TRCIWWR

U4038 異常終了
U4038 異常終了は、Open PL/I プログラム内で未処理の ERROR 条件が発生した場合に発生します。これは、ON ERROR ユニットがプログラムに欠落している場合に発生します。プログラム内に ON ERROR ユニットが存在する場合、戻りコードは通常は 0 になります。これは、異常終了がプログラムで適切に処理されたことを意味します。
注: CONVERSION、KEY、RECORD などの他の条件は、それらを処理する ON-unit が存在しない場合、ERROR にエスカレートされます。

この問題の一般的な原因は次のとおりです。

  • 大量の AUTOMATIC 変数を小さなスタック サイズで使用しているか、COBMAINSTACK 環境変数を設定せずに使用している。
    注: Windows プラットフォームでは、link.exe を使用して cassi.exe の設定を調整して変更を加えます。たとえば、次のコマンドでは 8 MB に設定しています。
    LINK /EDIT /STACK:8000000,8000000 cassi.exe
  • 無効なメモリ アドレスにアクセスしようとしている。
  • -defext コンパイラ指令を使用して 1 つのルーチンでコンパイルされていないファイルにアクセスしている。
VB ファイルへの WRITE 試行時の U4038 異常終了 (Windows、RH Linux、SUSE Linux)
この問題の最初の報告では、コードで次の文を実行しようとしたときに JCL ジョブ ストリームで U4038 異常終了が発生しました。
 WRITE FILE(LEGUPT) FROM (LOADREC);

LEGUPT および LOADREC の宣言は次のとおりです。

DCL LEGUPDT FILE RECORD OUTPUT ENV(VB RECSIZE(804));
 DCL LOADREC CHAR(800) VARYING;

エラーの調査として ON ERROR ユニットの ONCODE() の値を確認すると、ONCODE() の値が 99150 になっており、RECORD 条件が発生したことがわかりました。このファイルには 331 バイトしか書き込んでいないため、この可能性はないように思われます。

さらに調査したところ、次の 3 つの重要な事実が明らかになりました。

  1. LOADREC 変数で FIXED BIN(15) を最初の構造体要素とする構造体の「オーバーレイ」が使用されている。
  2. プログラムが -bigendian 指令でコンパイルされている。
  3. オーバーレイでの FIXED BIN(15) フィールドへの割り当てにより、CHAR VARYING 変数の LENGTH が手動で決定されている。

PLI CHAR VARYING は、プラットフォームのネイティブ形式 (この場合はリトル エンディアン形式) の 2 バイトの LL と、それに続く最長の文字列を含めるのに十分な長さの領域で構成されます。オーバーレイで CHAR VARYING が再定義され、BIGENDIAN の FIXED BIN(xx) データ型のデフォルトが指定されているため、331 を割り当てると長さ 19201 (x'4B01') が PL/I ランタイム システムに渡されます。LRECL の最大が 804 と定義されたファイルに 19201 バイトを書き込むことはできないため、この直後に ON RECORD 条件が発生しました。

解決方法:CHAR VARYING のオーバーレイで使用されている構造体に NATIVE 属性を追加し、LITTLEENDIAN にします。次に例を示します。

DCL 1 SCARLEG UNALIGNED BASED(P_SCARLEG),                             
     2 RECLEN  FIXED BIN(15) NATIVE,  /* RECORD LENGTH            */   
              ...
              ...

DCL 1 OTEXT  UNALIGNED  BASED(P_TEXT),                               
        2 TEXTLEN      FIXED BIN(15) NATIVE,  
            ...
            ...
ONCODE 99140: The UNDEFINEDFILE condition was raised because a DD statement was not used in (FILE=)
この形式のメッセージが表示された場合に問題の特定に役立つ注目すべき内容は、「FILE=」にそれ以上の情報がないことです。これは、通常、PL/I プログラムにおいて、コードが -DEFEXT でコンパイルされていないプロシージャからファイルの OPEN、READ、または WRITE を試行していることを示します(SYSPRINT、SYSIN、SYSOUT は、ソースを -defext でコンパイルする必要がない特殊なファイルです。SYSPRINT、SYSIN、SYSOUT にアクセスするときに -defext を使用しても問題は発生しません)。

-defext でコンパイルされている場合の有効な UNDEFINEDFILE メッセージの例と、-defext でコンパイルされていない場合の同じ例を次に示します(-defext で適切にコンパイルできないと、ファイル制御ブロックが割り当てられず、使用されているメモリが未定義になるため、トラップなどのさまざまな問題として現れる可能性があります)。

有効な UNDEFINEDFILE メッセージを含む joblog のスニペットの例:(-defext を使用した場合)
 *MSG ONCODE 99140: The UNDEFINEDFILE condition was raised because a 
DD statement was not used in (FILE=MYFILE)
無効な UNDEFINEDFILE メッセージ:(-defext を使用していない場合)
*MSG ONCODE 99140: The UNDEFINEDFILE condition was raised because a 
DD statement was not used in (FILE=)