静的破損

一般に、静的破損は、無効なポインター算術、初期化されていないポインター、または z/OS と分散プラットフォームの間で受け渡されるパラメーターの違いが原因で発生します。静的破損の一般的なタイプは次の 3 つです。

静的変数の内容の破損
破損した静的変数の内容は、通常、デバッガーでの実行時に変数の内容の変更を監視し、変更が発生した時点で停止することで発見できます。原因を特定するために確認する必要があるのは、配列の境界を超えていること、PL/I 組み込み関数を使用せずに文字列の長さが操作されていることなどです。配列の境界を超える可能性があるかどうかについては、-map 指令で生成されるコンパイル リストで確認できます。

デバッグ段階で静的変数の内容の破損を診断するには、-prefix stringrange,subscriptrange を使用してアプリケーション コードをコンパイルします。これにより、上書きを検出して該当する条件を発生させる追加のコードが挿入されます。

注: -prefix stringrange,subscriptrange でのコンパイルは、パフォーマンスが大幅に低下する可能性があるため、本番用アプリケーションに使用することはお勧めしません。

PL/I 変数の記述子の意図しない破損については、診断が難しい場合があります。構造体や CONTROLLED 変数などの PL/I 変数により、変数のレイアウト、CONTROLLED 変数の世代数、現在の世代の統計など、いくつかの項目を記述する非表示の内部構造がコンパイラで作成されます。これらの内部データ構造の 1 つが意図せずに破損すると、組み込み関数にアクセスするときに予期しない SIGSEGV のエラーが発生したり、呼び出されたプロシージャの処理が記述子に依存する場合に異常終了のエラーが発生したりする可能性があります。高度な手法として、コンパイラ リストの -map および -exp オプションを使用して記述子が存在する場所を特定し、新しいコードを挿入して記述子の変更を監視するか、考えられる破損の原因を特定します。

記述子の破損
データ構造やスカラー項目の配列など、非スカラー変数が宣言されると記述子が作成されます。データ構造または静的記憶域に埋め込まれたその他の項目に関連する記述子で、それらの破損が発生する可能性があります。

記述子は、生成されたコード内に埋め込まれる非表示のデータ構造です。サブルーチンや組み込み関数を呼び出すときに使用される構造のレイアウトや配列要素の数などを記述し、渡されるデータの形状とサイズを提供します。記述子は ENTRY 宣言には表示されませんが、非スカラー項目やスカラー項目の配列に対して呼び出し規則の一部として渡されます。CHAR(*) で宣言された変数などに対しても渡されます。

-defext でコンパイルされていない STATIC EXTERNAL データ項目へのアクセス
このシナリオでは、プログラムで STATIC EXTERNAL 変数を宣言し、アプリケーション内の 1 か所でその変数にアクセスしましたが、プログラムが -defext PL/I コンパイラ オプションでコンパイルされていませんでした。この場合、リンク時にリンカーで再配置情報を生成できないため、変数の記憶域が割り当てられず、アプリケーション内のランダムな位置を指すことになります。この変数を変更しようとすると、静的記憶域のランダムな部分が破損します。