XL Fortran for AIX V8.1.1

ユーザーズ・ガイド


XL Fortran のデバッグ・メモリー・ルーチンの使用

XL Fortran コンパイラーには、さまざまなメモリー割り当て機能に使用できる 2 つのライブラリーが含まれます。これらのライブラリーには、以下のものが含まれます。

libhmd.a
メモリー管理ルーチンのデバッグ・バージョンを提供するライブラリー。

libhm.a
mallocfree などの置換ルーチンを提供する非デバッグ・ライブラリー。これらのルーチンは、通常の AIX バージョンよりも高速です。さらに、2、3 の新しいライブラリー・ルーチンが追加されており、メモリー管理および製品レベルのヒープ・エラー・チェックのための追加機能が提供されます。

Fortran ユーザーに最も関係するライブラリーは libhmd.a です。詳細については、libhmd.a ライブラリーを参照してください。これらのライブラリーが組み込まれたアプリケーションを、XL Fortran がインストールされていない環境にインストールする場合、ライブラリー libhu.a も組み込む必要がある場合があります。これは、libhmd.a および libhm.a 内のルーチンには libhu.a 内のルーチンに依存するものがあるためです。

libhm.a ライブラリー

libhm.a は、malloccallocreallocfreestrdupmallopt および 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()
ヒープ上のすべての割り振りオブジェクトおよび解放済みオブジェクトに対して整合性検査を実行します。

戻り値:

0
ヒープに一貫性がある。

1
予約済み。

2
ヒープ・エラーが発生した。
int _heapset
  (unsigned int fill);
integer(4) _heapset,
  retc
integer(4) fill /1/
 
retc = 
  _heapset(%val(fill))
_heapset は、ヒープの整合性について検査します (_heapchk と類似)。それから、予約されていない解放済みストレージがあれば、それらの各バイトfill の値に設定します。 fill の値は、0 から 255 の範囲の整数にする必要があります。

_heapset を使用すると、プログラムがオブジェクトへの解放済みポインターを継続して使用する場所での問題を見つけやすくなります。

戻り値:

0
ヒープに一貫性がある。

1
予約済み。

2
ヒープ・エラーが発生した。

例:

例 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 では、以下の機能が提供されています。

システム・ライブラリーの前に libhmd.a ライブラリーにリンクすると、この機能へアクセスできるようになります。 mallocrealloc、および free へは明示的に参照できます。または、ALLOCATE および DEALLOCATE ステートメントによって割り振られたメモリーおよび割り振り解除されたメモリーに対するヒープ・デバッグを実行できます。デバッグ・ライブラリーが生成する出力内のソース行番号情報を取得するには、 -g コンパイラー・オプションを使用してコンパイルする必要があります。

これらの機能を使用するプログラムでは -qextname コンパイラー・オプションを指定できないことに注意してください。

次に、外部インターフェースおよび提供されているプロシージャーの説明を示します。外部インターフェースと mallocfreecallocrealloc、および strdup の機能は変更されていないので、この表では示されていないことに注意してください。

C 関数プロトタイプ Fortran の使用例 説明
void _dump_allocated
  (int size);
integer(4) :: size=4
call _dump_allocated &
   (%val(size))
このルーチンは、デバッグ・メモリー管理ルーチンを使用して現在割り振られている、または割り振られていた各メモリー・ブロックについての情報を stderr に出力します。 size は、各メモリー・ブロックで出力されるバイト数を以下のように示します。

負のサイズ
すべてのバイトが表示される。

0 のサイズ
バイトは表示されない。

正のサイズ
指定したバイト数が表示される。
void _dump_allocated_delta
    (int size);
integer(4) :: size=4
call _dump_allocated_delta &
   (%val(size))
このルーチンは、_dump_allocated または _dump_allocated_delta への最新の呼び出し以降にデバッグ・メモリー管理ルーチンを使用して現在割り振られている、または割り振られていたそれぞれのメモリー・ブロックについての情報を stderr に出力します。 size は、各メモリー・ブロックで出力されるバイト数を以下のように示します。

負のサイズ
すべてのバイトが表示される。

0 のサイズ
バイトは表示されない。

正のサイズ
指定したバイト数が表示される。
void heap_check(void);
call _heap_check()
このルーチンは、デバッグ・メモリー管理ルーチンを使用して、割り振られているメモリー・ブロックの整合性を検査します。これにより、解放されたストレージまたは割り振られたブロックの境界外のメモリーを、ユーザーのプログラムが上書きしていないことが検査されます。

デバッグ・メモリー割り振りルーチン (malloc などのデバッグ・バージョン) はすべて、heap_check を自動的に起動します。さらに、メモリー問題が存在すると思われるコードの領域内で、明示的に呼び出すこともできます。

heap_check を頻繁に呼び出すと、メモリー要件を増やしてプログラムのパフォーマンスに影響を与える可能性があります。デバッグ・メモリー・プロシージャーがヒープを検査する頻度を制御するために、この HD_SKIP 環境変数を使用できます。

プログラム内でエラーが生じた時点ではなく、heap_check ルーチンが呼び出された時点でエラーが検出されることに注意してください。

環境変数

デバッグ・ライブラリーは、以下の環境変数をサポートします。

HD_SKIP=increment [,start]
デバッグ・バージョンのメモリー管理ルーチンから heap_check が呼び出される頻度を制御します。 increment は、デバッグ関数にヒープを検査させる頻度を示します。 start では、デバッグ・メモリー・ルーチンを特定の回数呼び出した後に、ヒープ検査のスキップを開始しなければならないことを示します。 incrementstart のデフォルト値は、それぞれ 1 と 0 です。

HD_FILL
この環境変数をエクスポートすると、デバッグ・バージョンの mallocrealloc は、0xAA のバイト・パターンに割り振られているメモリーを設定します。

HD_STACK=n
n には、デバッグ・メモリー・ルーチンによって作成された呼び出しのチェーンに現れるプロシージャー数を指定します。デフォルトは 10 ですが、10 を下回る場合には、呼び出しのチェーン内のルーチンの数になります。

たとえば、次のようになります。

        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)
 


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]