XL Fortran コンパイラーには、さまざまなメモリー割り当て機能に使用できる 2 つのライブラリーが含まれます。これらのライブラリーには、以下のものが含まれます。
Fortran ユーザーに最も関係するライブラリーは libhmd.a です。詳細については、libhmd.a ライブラリーを参照してください。これらのライブラリーが組み込まれたアプリケーションを、XL Fortran がインストールされていない環境にインストールする場合、ライブラリー libhu.a も組み込む必要がある場合があります。これは、libhmd.a および libhm.a 内のルーチンには libhu.a 内のルーチンに依存するものがあるためです。
libhm.a は、malloc、calloc、realloc、free、strdup、 mallopt および mallinfo などの libc.a プロシージャーに、高速な置換ルーチンを提供します。これらのルーチンへのインターフェースは、標準システムのルーチンへのインターフェースと同じであるため、システム・ライブラリーを使用する前に libhm.a でリンクすること以外は必要ありません。
さらに、libhm.a で提供される以下のライブラリー・ルーチン (_heapchk と _heapset) は、 Fortran ユーザーも使用できます。これらのルーチンによって、製品レベルのサービスが行えるようになるため、一貫性がある正しいヒープ・ストレージの保守が容易になります。
これらの機能を使用するプログラムでの -qextname コンパイラー・オプションは使用できないことに注意してください。つまり、これらのライブラリー・ルーチンは「システム寄り」のルーチンであって Fortran 特有のルーチンではないため、このライブラリーでは 「_」 バージョンのルーチンを提供しません。
次の表では、libhm.a から使用できる追加のルーチンを説明しています。
C 関数プロトタイプ | Fortran の使用例 | 説明 |
---|---|---|
int _heapchk(void); |
integer(4) _heapchk, retc retc = _heapchk() | ヒープ上のすべての割り振りオブジェクトおよび解放済みオブジェクトに対して整合性検査を実行します。
戻り値:
|
int _heapset (unsigned int fill); |
integer(4) _heapset, retc integer(4) fill /1/ retc = _heapset(%val(fill)) | _heapset は、ヒープの整合性について検査します (_heapchk と類似)。それから、予約されていない解放済みストレージがあれば、それらの各バイト を fill の値に設定します。
fill の値は、0 から 255 の範囲の整数にする必要があります。
_heapset を使用すると、プログラムがオブジェクトへの解放済みポインターを継続して使用する場所での問題を見つけやすくなります。
戻り値:
|
例 1: ヒープ・エラーをテストするための _heapchk の使用 program tstheapchk pointer (p,pbased),(q,qbased) integer pbased,qbased integer(4) _heapchk,retcode p = malloc(%val(4)) pbased = 10 ! Decrement the pointer and store into ! memory we do not own. q = p-4; qbased = 10 retcode = _heapchk() if (retcode .ne. 0) call abort() ! Expected return code is: 2. Program will be aborted. call free(%val(p)) end
例 2: _heapset の使用 program tstheapset pointer (p,based) integer*1 based(1000) integer _heapset,retcode p = malloc(%val(1000)) based = 1 print *,based(450:500) call free(%val(p)) retcode = _heapset(%val(2)) print *,based(450:500) end Output: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
例 3: ヒープ・エラーをテストするための ALLOCATE と DEALLOCATE を指定した _heapchk の使用 program tstheapchk integer, allocatable :: a(:) integer(4) :: retcode integer(4), external :: _heapchk allocate(a(1:5)) ! Store outside the bounds of allocated memory. a(-5:10) = 17 retcode = _heapchk() if (retcode /= 0) call abort() print *, retcode deallocate(a) end program tstheapchk
例 4: ALLOCATE と DEALLOCATE によって管理されているメモリーでの _heapset の使用 program tstheapset integer(1), pointer :: p1(:), p2(:) integer(4) :: retcode integer(4), external :: _heapset allocate(p1(1:10)) p2 => p1(6:10) p1 = 1 print *, p2 deallocate(p1) retcode = _heapset(%val(2)) print *, p2 end program tstheapset Output: 1 1 1 1 1 2 2 2 2 2
libhmd.a では、以下の機能が提供されています。
システム・ライブラリーの前に libhmd.a ライブラリーにリンクすると、この機能へアクセスできるようになります。 malloc、realloc、および free へは明示的に参照できます。または、ALLOCATE および DEALLOCATE ステートメントによって割り振られたメモリーおよび割り振り解除されたメモリーに対するヒープ・デバッグを実行できます。デバッグ・ライブラリーが生成する出力内のソース行番号情報を取得するには、 -g コンパイラー・オプションを使用してコンパイルする必要があります。
これらの機能を使用するプログラムでは -qextname コンパイラー・オプションを指定できないことに注意してください。
次に、外部インターフェースおよび提供されているプロシージャーの説明を示します。外部インターフェースと malloc、free、calloc、
realloc、および strdup の機能は変更されていないので、この表では示されていないことに注意してください。
C 関数プロトタイプ | Fortran の使用例 | 説明 |
---|---|---|
void _dump_allocated (int size); |
integer(4) :: size=4 call _dump_allocated & (%val(size)) | このルーチンは、デバッグ・メモリー管理ルーチンを使用して現在割り振られている、または割り振られていた各メモリー・ブロックについての情報を stderr に出力します。
size は、各メモリー・ブロックで出力されるバイト数を以下のように示します。
|
void _dump_allocated_delta (int size); |
integer(4) :: size=4 call _dump_allocated_delta & (%val(size)) | このルーチンは、_dump_allocated または _dump_allocated_delta への最新の呼び出し以降にデバッグ・メモリー管理ルーチンを使用して現在割り振られている、または割り振られていたそれぞれのメモリー・ブロックについての情報を stderr に出力します。
size は、各メモリー・ブロックで出力されるバイト数を以下のように示します。
|
void heap_check(void); |
call _heap_check() | このルーチンは、デバッグ・メモリー管理ルーチンを使用して、割り振られているメモリー・ブロックの整合性を検査します。これにより、解放されたストレージまたは割り振られたブロックの境界外のメモリーを、ユーザーのプログラムが上書きしていないことが検査されます。
デバッグ・メモリー割り振りルーチン (malloc などのデバッグ・バージョン) はすべて、heap_check を自動的に起動します。さらに、メモリー問題が存在すると思われるコードの領域内で、明示的に呼び出すこともできます。
heap_check を頻繁に呼び出すと、メモリー要件を増やしてプログラムのパフォーマンスに影響を与える可能性があります。デバッグ・メモリー・プロシージャーがヒープを検査する頻度を制御するために、この HD_SKIP 環境変数を使用できます。
プログラム内でエラーが生じた時点ではなく、heap_check ルーチンが呼び出された時点でエラーが検出されることに注意してください。 |
デバッグ・ライブラリーは、以下の環境変数をサポートします。
たとえば、次のようになります。
export HD_SKIP=10 ! Every 10th debug memory function calls heap_check. export HD_SKIP=100,10 ! After 100 calls to debug memory functions, every 10th call ! will result in a call to heap_check.
例 1: メモリー・リークの検出 pointer (p,a),(p2,b),(p3,c) ! 1 character a(4) ! 2 integer b,c ! 3 ! 4 p = malloc(%val(4)) ! 5 a(1) = 'a' ! 6 a(2) = 'b' ! 7 a(3) = 'c' ! 8 a(4) = 'd' ! 9 ! 10 p2 = malloc(%val(4)) ! 11 b = 1 ! 12 ! 13 call _dump_allocated(%val(4)) ! 14 ! 15 p3 = malloc(%val(4)) ! 16 c = 2 ! 17 ! 18 call _dump_allocated_delta(%val(4)) ! 19 end ! 20
Output: 1546-515 ----------------------------------------------------------------- 1546-516 START OF DUMP OF ALLOCATED MEMORY BLOCKS 1546-515 ----------------------------------------------------------------- 1546-518 Address: 0x20000DE0 Size: 0x00000004 (4) _int_debug_umalloc + 32C _debug_umalloc + 44 _dbg_umalloc + 18 _umalloc_init + 30 malloc + 24 _main + 24 [x.f:5] 1000022C 1546-520 Memory contents: 61626364 [abcd 1546-515 ----------------------------------------------------------------- 1546-518 Address: 0x2000DE10 Size: 0x00000004 (4) _int_debug_umalloc + 32C _debug_umalloc + 44 _dbg_umalloc + 18 malloc + 24 _main + 64 [x.f:11] 1000022C 1546-520 Memory contents: 00000001 [.... 1546-515 ----------------------------------------------------------------- 1546-517 END OF DUMP OF ALLOCATED MEMORY BLOCKS 1546-515 ----------------------------------------------------------------- 1546-515 ----------------------------------------------------------------- 1546-516 START OF DELTA DUMP OF ALLOCATED MEMORY BLOCKS 1546-515 ----------------------------------------------------------------- 1546-518 Address: 0x2000DE30 Size: 0x00000004 (4) _int_debug_umalloc + 32C _debug_umalloc + 44 _dbg_umalloc + 18 malloc + 24 _main + 8C [x.f:16] 1000022C 1546-520 Memory contents: 00000002 [.... 1546-515 ----------------------------------------------------------------- 1546-517 END OF DELTA DUMP OF ALLOCATED MEMORY BLOCKS 1546-515 -----------------------------------------------------------------
例 2: 無効な書き込み pointer (p,a) ! 1 integer a ! 2 ! 3 p = malloc(%val(4)) ! 4 a = 1 ! 5 p = p + 4 ! 6 a = 2 ! 7 ! 8 call _heap_check() ! 9 ! 10 end ! 11 Output: 1546-503 End of allocated object 0x20000BD0 was overwritten at 0x20000BD4. 1546-514 The first eight bytes of the object (in hex) are: 0000000100000002. _int_debug_umalloc + 32C _debug_umalloc + 44 _dbg_umalloc + 18 _umalloc_init + 30 malloc + 24 _main + 24 [x.f:4] 1000022C 1546-522 Traceback: 0xD09D1C94 = _uheap_check_init + 0x24 0xD09D18C0 = heap_check + 0x28 0x100002C8 = _main + 0x5C IOT/Abort trap(coredump)