メモリ破損

PL/I アプリケーションでメモリ破損を引き起こす可能性のある一般的な問題について説明します。

メモリ破損はアプリケーションで追跡するのが最も難しい問題の 1 つであり、論理的かつ系統的に問題を特定するには専門的な専任のプログラマーが必要になります。「メインフレームで動作した」としても、Open PL/I では同じように動作しない可能性があります。ここでは、メインフレームと Windows/Linux/UNIX ベースのコンピューティングの違いについて説明し、それらの違いの非常に簡単な例を示します。

スタック方向
z/OS では、スタックが増加する方向がほとんどの分散プラットフォーム (特に Intel ベースのプラットフォーム) と異なります。ポインター算術を行うアプリケーションで計算に誤りがあった場合、z/OS では未使用のスタック スペースができるだけですが、Intel ベースのプラットフォームでは項目が簡単に破損する可能性があります。
スタック サイズ
Windows では、プロセスを開始するために使用される実行可能ファイルにスタック サイズの最大値とコミット サイズが埋め込まれています。これは、使用可能なスタック サイズをランタイム システム オプションまたは JCL パラメーター (あるいはその両方) で動的に制御できる z/OS ベースのアプリケーションとは異なります。

Linux/UNIX では、使用可能なスタック サイズは 2 つの異なる方法で制御されます。ulimit 設定と COBMAINSTACK 環境変数です。

非常に大規模な自動変数を使用している場合、CALL 文の実行時または関数の呼び出し時にプログラムが予期せずに終了するときは、まずはそこから調べる必要があります。-map オプションを使用してコンパイラ リストを作成すると、想定よりも大きい AUTOMATIC 変数を特定するのに非常に便利です。

CTF トレースを有効にしたり、診断コードを導入したりすると、障害が発生する時点が変わったり、障害がまったく再現されなくなったりすることがあるため、メモリ破損の診断がさらに複雑になる可能性があります。通常、CTF トレースや診断コードによって問題が再現されなくなるのは、初期化されていない AUTOMATIC 変数が原因です。CTF トレースの追加ロジックにより、プログラムが最初に失敗したときとは異なる方法で未初期化のスタック領域が上書きされる可能性があるためです。このような問題が発生した場合は、障害を確実に再現できる時点まで戻ってから、次のステップについて考える必要があります。

以降のトピックで、破損についてタイプ別に説明します。それらを調査するためのツールとプロセス/手順についても説明しています。