次の例で示す手法は、これまでに紹介した方法を使用してもメモリ破損の原因となっている場所を簡単に特定できない場合に特に役立ちます。
プログラム例 foo.pli:
/* Example PL/I Program demonstrating a memory corruption
and the use of a macro to run down the point of failure.
To compile:
mfplx -macro -incafter checkstomp.inc foo.pli
*/
foo: proc() options(main);
dcl stompee1 char(10) based(stompptr);
dcl stompee2 char(14) based(stompptr);
dcl stompptr ptr;
on error
begin;
call PLIDUMP('FBCAT', 'Demo Memory Corruption');
end;
alloc stompee1; /* 10 bytes */
stompee1 = '0123456789'; /* assign 10 bytes - happy happy */
/* memory should be clean */
$CHECKSTOMP();
/* Create memory stomp and try again */
stompee2 = 'ABCDEFGHIJKLMN'; /* pump in 14 and corrupt guard bytes */
/* should be stomped! */
$CHECKSTOMP();
end foo;
このプログラム例では、$CHECKSTOMP(); を使用して、ヒープベースのメモリのメモリ ストンプを意図的に作成しています。コメント テキストで示してあるコマンド ラインを使用してコンパイルすると、破損が発生した文を分離するマクロ コードが生成されます。これには、SYSPRINT または CTF トレース (あるいはその両方) にメッセージを送るコードが含まれています。また、呼び出しスタックや変数の値などを示す PLIDUMP を生成する ERROR 条件も設定しています。
このプログラム例をコンパイルしてマクロ コードを生成するための推奨される手順を次に示します。
mfplx -macro -incafter checkstomp.inc -pp foo.pp foo.pli
foo.pp は、マクロで生成されたコードを格納する中間出力ファイルです。
マクロによる処理の内容をしっかりと理解できるまで、マクロで生成されたコードを確認することを強くお勧めします。内容が理解できたら、この手法を独自の PL/I プログラムに適用して破損が発生した文を特定できます。
mfplx -macro -incafter checkstomp.inc -pp prog-name.pp prog-name.pli
サンプル セッション:
c:\work\emergency\jan13 ED>mfplx -macro -incafter checkstomp.inc -pp foo.pp foo.pli c:\work\emergency\jan13 ED>foo Memory Clean: FOO Line #(22) Memory Corruption detected: FOO Line #(28)