Rational Developer for System z
Enterprise PL/I for z/OS, Version 3.8, プログラミング・ガイド

CONTROLLED 変数の検出

CONTROLLED 変数は本質的に LIFO スタックであり、それぞれの CONTROLLED 変数は、そのスタックの先頭を指す「アンカー」 を持っています。 CONTROLLED 変数を検出する秘訣はこのアンカーの位置を検出すること であり、下記のように、その位置はコンパイラー・オプションによって異なります。

CONTROLLED 変数に関するこの説明の残りの部分では、プログラム・ソース は上記と同じプログラムですが、ストレージ・クラスが CONTROLLED に変更されています。

Compiler Source
  Line.File
     2.0      test: proc options(main);
     3.0
     4.0        dcl a fixed bin(31) controlled;
     5.0        dcl b fixed bin(31) controlled;
     6.0
     7.0        on error
     8.0          begin;
     9.0            call plidump('TFBHC');
    10.0          end;
    11.0
    12.0        allocate a, b;
    13.0        a = 0;
    14.0        b = 29;
    15.0        b = 17 / a;

NORENT WRITABLE を指定した場合

コンパイラー MAP オプションの結果は、この場合も、実際には右側にもう 1 つ列 があること、列の間のスペースはもっと離れていることを除き、以下のようになります。

* * * * *   S T O R A G E   O F F S E T   L I S T I N G   * * * * *
 IDENTIFIER DEFINITION ATTRIBUTES

 A          1-0:4      Class = static,  Location = 8 : 0x8 + CSECT ***TEST2
 B          1-0:5      Class = static,  Location = 12 : 0xC + CSECT ***TEST2

注: これらの行は、(A および B それ自体の場所ではなく) A および B のアンカーの場所を記述しています。 したがって、A のアンカーはコンパイル単位 TEST の静的 CSECT の中の 16 進オフセット 08 の位置にあり、B のアンカーは 16 進オフセット 0C の位置にあることになります。

PLIDUMP が B オプションを指定して呼び出されている場合、 現行の呼び出しチェーン内のそれぞれのコンパイルごとに、静的ストレージ の 16 進ダンプが含まれています。 これは、以下のようになります (これも、右側の列が省略されています)。

Static for procedure TEST    Timestamp: . . .

  +000000 0FC00A88  0FC00DB0 0FC00AA8 102B8A30 102B8A50
  +000020 0FC00AA8  0FC00A88 00444042 00A3AE01 0FC009B0
  +000040 0FC00AC8  6E3BFFE0 00000000 00000000 00000000

したがって、A のアンカーは 102B8A30 にあり、B のアンカーは 102B8A50 にあることになります。 しかし、CONTROLLED 変数があるため、これらのストレージは ALLOCATE ステートメント を使用して取得されており、そのため、これらのアドレスはヒープ・ストレージ内を指しています。 しかし、PLIDUMP が H オプションを指定して呼び出されている場合は、 ヒープ・ストレージの 16 進ダンプが含まれることになります。 これは、以下のようになります (これも、右側の列が省略されています)。

Enclave Storage:
  Initial (User) Heap
    +000000 102B7018  C8C1D5C3 0FC0F990 0FC0F990 00000000
      . . .
    +001A00 102B8A18  102B7018 00000020 0FC00A90 00000014
                     00000000 00000000 00000000 00000000
    +001A20 102B8A38  102B7018 00000020 0FC00A94 00000014
                      00000000 00000000 0000001D 00000000

A のアンカーが 102B8A30 にあったので、A は 16 進 00000000 を持ち、B のアンカーが 102B8A50 にあったので、B は (予想通りの) 16 進 0000001D を持つことになります。

NORENT NOWRITABLE(FWS) を指定した場合

これらのオプションを指定したコンパイラー MAP オプション の結果は、この場合も、実際には右側にもう 1 つ列 があること、列の間のスペースはもっと離れていることを除き、以下のようになります。

 * * * * *   S T O R A G E   O F F S E T   L I S T I N G   * * * * *
 IDENTIFIER DEFINITION ATTRIBUTES

 A          1-0:4      Class = automatic,  Location = 236 : 0xEC(r13)
 B          1-0:5      Class = automatic,  Location = 240 : 0xF0(r13)

注: これらのオプションを指定した場合、CONTROLLED 変数の位置を指定するために、追加の 間接指示のレベルがあり、そのため、上記の行は A および B のアンカーのアドレスの位置 を記述しています。 したがって、A のアンカーのアドレスはブロック TEST の AUTOMATIC 内の 16 進 EC の位置にあり、一方 B のアンカーは 16 進 F0 にあることになります。

PLIDUMP が B オプションを指定して呼び出されているため、 現行の呼び出しチェーン内のそれぞれのブロックごとに、自動ストレージ の 16 進ダンプが含まれています。 これは、以下のようになります (これも、右側の列が省略されています)。

 Dynamic save area (TEST): 102973C8
  +000000 102973C8  10000000 10297188 00000000 8FC007DA
          ....
  +0000E0 102974A8  0FC00998 00000000 00000000 102B8A40
                    102B8A28 10297030 102977D0 8FDF3D7E

したがって、A のアンカーのアドレスは 102B8A40 になり、B のアンカー のアドレスは 102B8A28 になります。

PLIDUMP が H オプションも指定して呼び出されているので、 ヒープ・ストレージの 16 進ダンプが含まれることになります。 これは、以下のようになります (これも、右側の列が省略されています)。

 Enclave Storage:
    Initial (User) Heap
      +000000 102B7018  C8C1D5C3 0FC0F990 0FC0F990 00000000
        . . .
      +001A00 102B8A18  102B7018 00000018 00000000 0FC00A78
                        102B8A80 00000000 102B7018 00000018
      +001A20 102B8A38  102B8A20 0FC00A74 102B8A60 00000000
                        102B7018 00000020 102B8A40 00000014
      +001A40 102B8A58  00000000 00000000 00000000 00000000
                        102B7018 00000020 102B8A28 00000014
      +001A60 102B8A78  00000000 00000000 0000001D 00000000
                     00000000 00000000 00000000 00000000

B のアンカーのアドレスが 102B8A28 にあり、B のアンカー が 102B8A80 にあるので、B は、予想通り 16 進 0000001D、つまり 10 進 29 になります。

NORENT NOWRITABLE(PRV) を指定した場合

これらのオプションを指定してコンパイルした場合の MAP リストは、以下のようになります。

* * * * *   S T O R A G E   O F F S E T   L I S T I N G   * * * * *
 IDENTIFIER DEFINITION ATTRIBUTES

 ***TEST3     1-0:4  Class = ext def,  Location = CSECT ***TEST3
 ***TEST4     1-0:5  Class = ext def,  Location = CSECT ***TEST4
_PRV_OFFSETS  1-0:1  Class = static,   Location = 8 : 0x8 + CSECT ***TEST2

ここでのキーは、この出力の最後の行です。 PRV_OFFSETS は、それぞれの CONTROLLED 変数についての PRV テーブル 内でのオフセットを保持する静的テーブルです。 この静的テーブルは、MAP オプションが指定された場合にのみ生成されます。

このテーブルを解釈するために、コンパイラーは、ブロック名テーブルのすぐ後に、通常は小さな 別のリストも生成します。このリストは、このサンプルでは、以下のようになります。

           PRV Offsets

    Number   Offset Name
         1        8 A
         1        C B

このテーブルには、名前が示された CONTROLLED 変数ごとに、ランタイム _PRV_OFFSETS テーブルでの 16 進オフセットがリストされます。 ブロック番号 (最初の列) を使用して、同じ名前であるが、異なるブロックに宣言されている変数 を区別することができます。

_PRV_OFFSETS テーブルは静的ストレージ内 (16 進オフセット 8) にあり、PLIDUMP が B オプションを指定して呼び出されたため、以下に示すようなダンプ出力が表示されます。

Static for procedure TEST    Timestamp: . . .
  +000000 10908EC8  02020240 00000005 6DD7D9E5 6DD6C6C6
                    00000000 00000004 D00000A0 00100000
  +000020 10908EE8  6E3BFFE0 00000000 00000000 00000000
                    00000000 90010000 00000000 00000000

したがって、PRV テーブル内の A のオフセットは 0 になり、PRV テーブル内の B のオフセットは 4 になります。_PRV_OFFSETS テーブルの最初の 8 バイトを占めている目印「_PRV_OFF」にも注目してください。

PRV テーブルは、常に CAA 内のオフセット 4 の位置にあり、PLIDUMP が H オプション を指定して呼び出されたため、ダンプ出力に表示され、以下のようになります。

Control Blocks Associated with the Thread:
  CAA: 0A7107D0
   +000000 0A7107D0  00000800 0ADB7DE0 0AD97018 0ADB7018
                     00000000 00000000 00000000 00000000

したがって、PRV テーブルのアドレスは 0ADB7DE0 になり、ヒープ・ストレージ内の ダンプ出力にも表示されます。

 Enclave Storage:
    Initial (User) Heap
      +000000 102B7018  C8C1D5C3 0FC0F990 0FC0F990 00000000
        . . .
      +000DC0 0ADB7DD8  00000000 00000000 0ADB8A38 0ADB8A58
                        0ADB7018 00000488 00000000 00000000

したがって、PRV テーブルには 0ADB8A38 0ADB8A58 などが入って おり、_PRV_OFFSETS テーブルから得られたとおり、PRV テーブル内での A のオフセットは 0 になり、B のオフセットは 4 になります。 これらは、それぞれ A と B のアドレスでもあります。

これらのアドレスは、ダンプ内のヒープ・ストレージにも表示されます。

  Enclave Storage:
    Initial (User) Heap
      +000000 102B7018  C8C1D5C3 0FC0F990 0FC0F990 00000000
        . . .
      +001A00 0ADB8A18  00000000 00000000 0ADB7018 00000020
                        00000000 00000014 0A7107D4 00000000
      +001A20 0ADB8A38  00000000 00000000 0ADB7018 00000020
                        00000004 00000014 0A7107D4 00000000
      +001A40 0ADB8A58  0000001D 00000000 00000000 00000000
                     00000000 00000000 00000000 00000000

したがって、A のアドレスは 0ADB8A38 で、その 16 進は予想通りの 00000000 になり、B のアドレスが 0ADB8A58 なので、 その 16 進値も予想通りの 0000001D になります。


Terms of use | Feedback

This information center is powered by Eclipse technology. (http://www.eclipse.org)