Micro Focus 製品を使用してメモリを割り当てるときは、割り当てられたメモリ ブロックの前後にガード バイトと呼ばれる追加のバイトが割り当てられます。意図しない上書きを検出できるように、これらのガード バイトには既知の値が設定されています。
CBL_MEM_VALIDATE API (または同一の API PLI_MEM_VALIDATE) を呼び出すことで、ヒープ メモリの破損をチェックできます。現在割り当てられているメモリとフリー チェーン (該当する場合) の両方がチェックされ、上書きされているガード バイトがないかどうかが確認されます。
オプションで、次の COBOL ランタイム チューナーを使用できます。
さらに、Open PL/I では各メモリ割り当てにタイプが割り当てられます。割り当てられたタイプを使用して、どのタイプのメモリが破損しているかを判断できます。Open PL/I ランタイム システムによって割り当てられるメモリのタイプは 65350 から 65399 までです。最も一般的なタイプは 65398 です(65350 から 65397 までは使用されません)。
ヒープ破損が発生すると、次のように報告されます。
Memory Strategy: 00000001 Corruption at: 0E2A776C Flags:0000000F Type: 0 Size: 0
このメッセージは、破損したメモリがアドレス 0E2A776C (32 ビット プログラム) にあり、メモリに割り当てられたタイプが 0 であること、つまり破損したメモリは PL/I によって割り当てられたものでないことを示しています。Flags の値は、検出されたメモリ破損のタイプ (割り当てられたタイプではなく) や検出元などを示します。詳細については、「CBL_MEM_VALIDATE」を参照してください。
CTF トレースでは、メモリ破損は COBOL RTS 249 および 252 イベントとして報告されます。この情報は、破損のアドレス、タイプ、サイズなどを示す PLIDUMP で表示される内容と似ています。次に、CTF トレースの RTS 249 イベントの例を示します。
21:59:33.009 5892 MF.RTS 249 3 : 0X14025F10 65398 1 0X140362A2
このメッセージには、いくつかの役立つ情報が含まれています。
| 65398 | 破損したメモリは PL/I によって割り当てられたものです。原因として、CONTROLLED 変数または BASED 変数、あるいは中間結果を処理するために PL/I によって作成された一時変数が考えられます。 |
| 1 | 問題はユーザー データの不足です。割り当てられたブロックの終わりを超えて書き込みが行われたことを示しています。 |
| 0X140362A2 | 書き込まれたチェック バイトのアドレスです。 |
%ProgramFiles(x86)%\Micro Focus\Enterprise Developer\etc\mftrace\annotations(Windows) または /etc/mftrace/annotations(UNIX) ディレクトリにある mf.rts.xml で、249 イベントに関する次の追加情報が提供されます。
<Event Id="249" Description="Memory Stomp">
<Arguments>
<Argument Index="0" Description="Data Address" />
<Argument Index="1" Description="Memory Type" />
<Argument Index="2" Description="">
<ArgumentCase Index="2" Value="0" Description="Run-In (Header)"/>
<ArgumentCase Index="2" Value="1" Description="Run-Out (User Data)"/>
<ArgumentCase Index="2" Value="2" Description="Bad Header"/>
<ArgumentCase Index="2" Value="3" Description="Freed Overwrite"/>
<ArgumentCase Index="2" Value="4" Description="Bad Header User"/>
<ArgumentCase Index="2" Value="5" Description="Failed OS Check"/>
<ArgumentCase Index="2" Value="6" Description="Run-In (User Data)"/>
<ArgumentCase Index="2" Value="7" Description="Bad Track Data"/>
<ArgumentCase Index="2" Value="8" Description="Bad Link"/>
</Argument>
<Argument Index="3" Description="">
<ArgumentCase Index="2" Value="0" Description="Check Bytes Address"/>
<ArgumentCase Index="2" Value="1" Description="Check Bytes Address"/>
<ArgumentCase Index="2" Value="2" Description="Header Address"/>
<ArgumentCase Index="2" Value="3" Description="Overwrite Address"/>
<ArgumentCase Index="2" Value="6" Description="Check Bytes Address"/>
<ArgumentCase Index="2" Value="7" Description="Track Data Address"/>
<ArgumentCase Index="2" Value="8" Description="Header Address"/>
</Argument>
</Arguments>
</Event>