XL Fortran for AIX V8.1.1

ユーザーズ・ガイド


XL Fortran プログラムのサンプル dbx セッション

dbx と互換性のあるシンボリック・デバッガーを使用して XL Fortran プログラムをデバッグすることができます。 dbx に関する背景情報を得るには、「AIX General Concepts and Procedures 」を参照してください。 dbx サブコマンドの情報については、「AIX コマンド・リファレンス 」を参照してください。

以下の例は、dbx で解決できる場合のある一般的な XL Fortran の問題を示しています。これは、dbx 機能の小さなサブセットだけを示したもので、Fortran 90 または Fortran 95 割り振り可能配列では使用されなくなったメモリー割り振り手法を使用していますが、このデバッガーを使用したことがない方には、入門書としての役割を果たします。

動的メモリー割り振りの問題

以下のプログラムは、AIX システム・サブルーチン malloc を使用して実行時に配列を割り振ろうとします。以下のコマンドを使用してプログラムをコンパイルしてからそのプログラムを実行すると、プログラムはメモリー・ダンプを生成します。

   xlf95 -qddim testprog.f -o testprog

この時点で、C の malloc ルーチンが正しく機能しているかどうか、あるいは、実行時まで次元がわからない場合に、この方法がメインプログラム内の配列を割り振る方法として正しいかどうか疑問に思うかもしれません。

          program main
 
	  pointer(p, array(nvar,nrec))
	  real*8 array
 
	  nvar = 2
	  nrec = 3
	  p = malloc(nvar*nrec*8)
 
	  call test_sub(array, nvar, nrec)
 
	  end
 
	  subroutine test_sub(array, nvar, nrec)
 
	  dimension array(nvar, nrec)
 
	  array(1,1) = 1.
	  array(2,1) = 2.
	  array(1,2) = 3.
	  array(2,2) = 4.
	  array(1,3) = 5.
	  array(2,3) = 6.
 
	  write(*, 100) array(1,1), array(2,1), array(1,2),
     1          array(2,2), array(1,3), array(2,3)
  100     format(//t2,f4.1/t2,f4.1/t2,f4.1/t2,f4.1/
     1          t2,f4.1/t2,f4.1)
 
	  return
	  end

デバッグ・プロセスは次のように行います。

  1. -g オプションを指定してプログラムをコンパイルし、dbx 下でのデバッグを許可します。


     -> xlf95  -qddim -g testprog.f -o testprog
    ** main   === End of Compilation 1 ===
    ** test_sub   === End of Compilation 2 ===
    1501-510  Compilation successful for file testprog.f.
    
  2. プログラムを実行して問題を確認し、メモリー・ダンプを作成します。


     -> testprog
    Segmentation fault(coredump)
     ->
    
  3. メモリー・ダンプが発生するプログラム内の場所を見つけます。


     -> dbx testprog core
    dbx version 3.1 for AIX.
    Type 'help' for help.
    reading symbolic information ...
    [using memory image in core]
     
    segmentation violation in test_sub at line 21 in file "testprog.f"
       21             array(1,1) = 1.
    (dbx)
    
  4. この where コマンドを使用して、プログラム内で見つけた点の呼び出しからトレースバックを取得します。


    (dbx) where
    test_sub(array = (...), nvar = warning: Unable to access address 0x200aee94
     from core
    -1, nrec = warning: Unable to access address 0x200aee98 from core
    -1), line 21 in "testprog.f"
    main(), line 12 in "testprog.f"
    (dbx)
    

    main は 12 行目の test_sub を呼び出します。この警告は、この呼び出しに対して引き数を評価しているときに問題が発生することを示しています。

  5. 配列の最初の引き数の値を見ます。


    (dbx) print array(1,1)
    reference through nil pointer
    (dbx)
    

    array に値が割り当てられていないことを示唆しています。その可能性を確かめるには、配列内のエレメントのアドレスを見てください。


    (dbx) p &array(1,1)
    (nil)
    (dbx)
    

    XL Fortran は配列のためのスペースを割り振っていないようです。それを確認するには、その配列を指し示しているポインターの値を印刷します。


    (dbx) print p
    warning: Unable to access address 0x200aee90 from core
    0xffffffff
    
  6. 実行中に p に何が起こっているかを調べるために、プログラムを再始動して、p の使用をトレースします。


    (dbx) stop in main
    [1] stop in main
    (dbx) run
    [1] stopped in main at line 7 in file "testprog.f"
        7             nvar = 2
    (dbx) trace p
    [3] trace p
    (dbx) cont
    initially (at line 8 in "testprog.f"):  p = nil
     
    segmentation violation in test_sub at line 21 in file "testprog.f"
       21             array(1,1) = 1.
    (dbx) p p
    nil
    (dbx)
    

    p は有効な値に設定されないので、配列にスペースを割り振っている行に何か誤りがあります。


         9            p = malloc(nvar*nrec*8)
    
  7. 次のステップは、malloc への呼び出しが機能しない理由を調べるのが目的です。 malloc は C 関数なので、基礎知識および明確な指針を得るために、第 10 章, 言語間呼び出しを参照してください。

    この項を読むと、C 関数への呼び出しには参照によってではなく値によって引き数を渡す必要があることがわかります。このサンプル・プログラム内の問題を修正するには、

    p = malloc(nvar*nrec*8)
    

    行を次の行に置き換えます。

    p = malloc(%val(nvar*nrec*8))
    
  8. 修正したプログラム (solution.f) を再コンパイルして実行すると、正しい結果が生成されます。


     -> xlf95  -qddim -g solution.f -o solution
    ** main   === End of Compilation 1 ===
    ** test_sub   === End of Compilation 2 ===
    1501-510  Compilation successful for file solution.f.
     -> solution
     
     
      1.0
      2.0
      3.0
      4.0
      5.0
      6.0
    
  9. 修正されたプログラムをトレースすることは有益です。


     -> dbx solution
    dbx version 3.1 for AIX.
    Type 'help' for help.
    Core file program (testprog) does not match current program (core ignored)
    reading symbolic information ...
    (dbx) trace p
    [1] trace p
    (dbx) run
    initially (at line 7 in "solution.f"):  p = nil
    after line 9 in "solution.f":   p = 0x200af100
     
     
      1.0
      2.0
      3.0
      4.0
      5.0
      6.0
     
    execution completed
    (dbx)
    

parray の値が適切かどうかをチェックするには、トレースをオフにします。


(dbx) status
[1] trace p
(dbx) delete all
(dbx) status
(dbx)

次に、新しいブレークポイントを設定して、再びプログラムを最初から終わりまで実行します。予想どおり、array(1,1) のアドレスが p(0x200af100) の内容と同じであることに注目してください。


(dbx) stop at 9
[11] stop at "solution.f":9
(dbx) run
[11] stopped in main at line 9 in file "solution.f"
    9             p = malloc(%val(nvar*nrec*8))
(dbx) p p
nil
(dbx) next
stopped in main at line 12 in file "solution.f"
   12             call test_sub(array, nvar, nrec)
(dbx) p p
0x200af100     <-------------
(dbx)
(dbx) step      /* Notice we use step to step into subroutine test_sub. */
stopped in test_sub at line 21 in file "solution.f"
   21             array(1,1) = 1.
(dbx) p &array(1,1)
0x200af100     <---------------
(dbx) next
stopped in test_sub at line 22 in file "solution.f"
   22             array(2,1) = 2.
(dbx) p array(1,1)
1.0
(dbx)


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