PLIDUMP サブルーチン

目的

プログラムで使用している記憶域の選択した部分のフォーマットされたダンプを作成できます。

構文

CALL PLIDUMP (character-string-expression 1,character-string-expression 2);

パラメーター

character-string-expression 1 は、次の 1 つ以上の文字で構成されるダンプ オプション文字列です。
注: 互換性のために、有効な IBM PL/I 文字列の使用が許可されますが、使用できるのは次の文字列オプションだけです。
C 続行します。ダンプの完了後にルーチンが続行されます。
F ランタイムがアクセスした KSDS ファイルのキー情報をダンプに追加します。
H PLIDUMP でヒープ データを表示します。
S 停止します。エンクレーブがダンプで終了します。
T TRACEBACK。

Tおよび C がデフォルトのオプションです。

character-string-expression 2 は、ダンプのヘッダーとして出力される最大 80 文字のユーザー識別文字列です。

説明

PLIDUMP は、現在の場所までの呼び出しパスに関する情報およびその他のデータをダンプし、フォーマットされたダンプを生成します。

PLIDUMP でできるだけ多くの情報を取得するには、次のいずれかの方法を出力として使用します。

  • CODEWATCH_STBPATH を設定します。
  • 実行中の .dll と同じディレクトリに .stb ファイルを配置します。

PLIDUMP を使用してシンボルおよびソース行の情報を生成するには、-deb を使用してプログラムをコンパイルし、必要な .stb ファイルを生成します。この情報は、テストから運用に移行する際に役立ちます。

PLIDUMP では、PL/I ランタイムがアクセスした KSDS ファイルの KEY 情報も提供できます。

次に、PLIDUMP を呼び出して、言語環境ダンプを生成する PL/I ルーチンの例を示します。この例では、メイン ルーチンの PLIDMP が PLIDMPA を呼び出し、その後 PLIDMPA が PLIDMPB を呼び出します。PLIDUMP の呼び出しは、ルーチン PLIDMPB で作成されます。

%PROCESS MAP GOSTMT SOURCE STG LIST OFFSET LC(101);
 PLIDMP: PROC OPTIONS(MAIN) ;

   Declare   (H,I) Fixed bin(31) Auto;
   Declare   Names Char(17) Static init('Bob Teri Bo Jason');
   H = 5;	 I = 9;
   Put skip list('PLIDMP Starting');
   Call PLIDMPA;

     PLIDMPA: 	PROC;
       Declare (a,b) Fixed bin(31) Auto;
       a = 1;	 b = 3;
       Put skip list('PLIDMPA Starting');
       Call PLIDMPB;

         PLIDMPB:  PROC;
           Declare  1 Name auto,
             2 First   Char(12) Varying,
             2 Last    Char(12) Varying;
           First = 'John';
           Last = 'Thompson';
           Put skip list('PLIDMPB Starting');
           Call PLIDUMP('TBFC','PLIDUMP called from procedure PLIDMPB');
           Put Data; 
         End PLIDMPB;
     End PLIDMPA;
 End PLIDMP;

次の例では、2 つの異なる場所で F オプションを指定して PLIDUMP を呼び出しています。

 DemoBlks: proc options (main);
   
    /********************************************/
    /* Files                                    */
    /********************************************/    
    dcl KSDSFILE     file 
     env(VSAM GENKEY KEYLOC(31) KEYLENGTH(6) recsize(80));        
    dcl NOTTHERE     file;
    dcl SYSUT1       file record input;    

    /********************************************/
        /* Variables                                */
    /********************************************/
    dcl eof_sysut1   bit(1) init('0'b);
    dcl good_record  bit(1);
    dcl mykey        char(06);
    dcl myrec1       char(80);      
    dcl sysut1_rec   char(100) varying;    
                
    on error
      begin;
        on error system;
        call PLIDUMP('FS'); 
      end;

    on key(KSDSFILE)
      begin;
        good_record = '0'b;
        put skip list('KSDSFILE record not found');
        call PLIDUMP('FC'); 
      end;

    on undefinedfile(NOTTHERE);
      begin;
      end;

    on endfile(SYSUT1) eof_sysut1 = '1'b;

    call PLITEST('shlib DEMOBLKS.dll;env DEMOBLKS;br mylabel;br %exit[det;q];c','',1);
        mylabel:

    open file(SYSPRINT);
    open file(SYSUT1);    
    open input file(NOTTHERE);     
    open file(KSDSFILE) update keyed;
      
    /* Call PLIDUMP w/o 'F' option to demonstrate no  */
        /* File Control blocks generated in first PLIDUMP */

    call PLIDUMP('C');    

    /* Run until an ERROR is encountered and generate a PLIDUMP */        
        /* that can be used to diagnose the cause of the problem   */
        /* Note:  There are intentionally more than one problem   */
        /*        generated in this demo in order to show all     */
        /*        functionality                                   */

    put skip list('Starting DEMOBLKS Key processing');
    put skip;

    read file(SYSUT1) into (sysut1_rec);                  
    do while(^eof_sysut1);
        good_record = '1'b;
        read file(KSDSFILE) into (myrec1) key(substr(sysut1_rec,1,6));
        if (good_record) then
            put skip list('processing KSDSFILE record: ' || myrec1);
        read file(SYSUT1) into (sysut1_rec);              
    end;

    put skip list('Did you find what went wrong??');    

    close file(KSDSFILE);
    close file(SYSUT1);

 end DemoBlks;

この例を実行すると、最後に実行された操作がすべてのファイルで表示されます。

また、操作に関する追加情報として「ファイル状態」バイトの情報もオプションで表示されます。具体的には、この例の実行時には 9/13 (無効なファイル名) が表示され、読み取りでレコードが見つからなかったことを示す「23」も表示されます。これらのファイル状態は COBOL ファイル状態バイトに対応しており、「9」で始まる場合はランタイム エラーとなります。それらの情報へのハイパーリンクを設定すると非常に便利です。

最後の入出力操作の結果は VSAM ファイルのバッファーに格納されます。QSAM ファイルのバッファーには、最後のファイル入出力操作で使用された実際のバッファーが含まれている場合があります。これは、スタックに自動で割り当てられたがアドレスが有効でなくなっている変数の存在によるものと考えられます。アドレスは動的に割り当てられ、後に解放されました。指定アドレスのすべての対象を表示するよう試行されますが、この対象が信頼できるかどうかはプログラムの構造や PLIDUMP を呼び出した時点の呼び出しスタックの内容次第です。QSAM ファイルのバッファーに常に信頼できる情報が格納されるようにするには、読み取りと書き込みに常に STATIC 変数を使用するようにしてください。

0 または 1 として表示される「varying item」フィールドは、PLIDUMP の実行時に表示されるバイト長のペアがある理由の特定に役立つことがあります。

制約事項

32 ビット Windows のみ:

シナリオ 1:
COBOL1 calls 
               PLISUB1 calls 
                              PLISUB2 calls PLIDUMP()

このシナリオでは、PLISUB1 および PLISUB2 のすべての情報が含まれていますが、COBOL1 が存在することと PLISUB1 が呼び出されたことはどちらも示されていません。

シナリオ 2:
PLIMAIN calls 
COBOL1 calls 
                              PLISUB1 calls 
                                             PLISUB2 calls PLIDUMP() 

このシナリオでは、PLISUB1 および PLISUB2 のすべての情報が含まれていますが、PLIMAIN や COBOL1 が存在することは示されていません。