UFT プローブ・マネージャー
uft (ユーザー関数トレース) プローブ・マネージャーは、プロセスの XCOFF シンボル・テーブルに表示されるユーザー・スペース関数をプローブすることをサポートしています。 uft プローブ・マネージャーは、ソースが C または FORTRAN 言語のテキスト・ファイルである関数の入り口点および出口点であるプローブ・ポイントをサポートします。ただし、シンボル・テーブルには、 C または FORTRAN以外の言語からのソースを持つシンボルが含まれている場合があります。
Java™ アプリケーションのトレースは、ユーザーの観点からは既存のトレース・メカニズムと同じ方法で行われます。JVM は、Probevue の代わりに実タスクのほとんどを実行するものです。
UFT プローブ・マネージャーは、次のフォーマットの 5 組のプローブ指定を受け入れます。
uft:<processID>:*:<function_name>:<entry|exit>
- PID またはプログラム名
トレースするプロセスのプロセス ID、または厳密に調べるプログラムの名前 (実行可能ファイルの名前)。 プロセス ID または実行可能ファイルの名前は、二重引用符 ("/usr/bin/test") または単一引用符 ('/usr/bin/test') で囲んで指定するか、ファイル・パス (/usr/bin/test) として指定することができます。 実行可能ファイルの絶対パスまたは相対パスを指定できます。 また、実行可能ファイルへのハード・リンクまたはシンボリック・リンクを、値としてプログラム名パラメーターに指定することもできます。 以下の例は、2 番目のタプル・プローブ仕様を指定するための、さまざまな方法を示しています。
例@@uft:123450 :*: foo :entry @@uft : /usr/bin/test:* :foo:entry @@uft:./test:*:foo:entry @@uftxlc++:/usr/bin/test:*:foo:exit @@uftxlc++:"/usr/bin/testxxx":*:foo:exit @@uft :"/usr/bin/xxx":* :foo:entry @@uft:'/home/xxx/test':*:func1:entry/usr/bin/test が実行可能ファイルで、/testln が /usr/bin/test ファイルへのソフト・リンク (/testln ->/usr/bin/test) であれば、そのユーザーの /usr/bin/test 実行可能ファイルまたは /testln ソフト・リンクの実行によって開始されたプロセスのすべてを厳密に調べるには、次のコマンドを実行してください。@@uft:/testln:*:foo:entry
3 番目のフィールドを * に設定すると、UFT プローブ・マネージャーは、プロセスのアドレス・スペースにロードされるすべてのモジュール (メインの実行可能モジュールと共有モジュールを含む) で関数を検索します。 これは、1 つのプログラムにこの名前の C 関数が複数含まれている場合、(例えば、複数の異なるオブジェクト・モジュールに静的クラスをもつ関数が含まれている場合)、プローブがこれらのすべての関数のエントリー・ポイントに適用されることを意味します。
特定のモジュール内の関数名をプローブする必要がある場合、そのモジュール名を 3 番目のフィールドに指定する必要があります。 ライブラリー・モジュール名を指定するプローブ指定構文を以下に示します。
# Function foo in any module
@@uft:<pid>:*:foo:entry
# Function foo in any module in any archive named libc.a
@@uft:<pid>:libc.a:foo:entry
# Function foo in the shr.o module in any archive named libc.a
@@uft:<pid>:libc.a(shr.o):foo:entry
4 番目の組の関数名を拡張正規表現 (ERE) として指定できます。 The ERE should be enclosed between "/ and /" like "/<ERE>/".
/* Probe entry of all libc.a functions starting with “malloc” word */
@@uft:$__CPID:libc.a: “/^malloc.*/”:entry
/* Probe exit of all functions in the executable a.out */
@@uft:$__CPID:a.out:”/.*/”:exit
関数名が正規表現として指定されるエントリー・プローブでは、個別の引数にはアクセスできません。 ただし、Probevue 関数の print_args は、関数名とその引数を表示するために使用できます。 引数値は、関数のトレースバック・テーブルにある引数タイプ情報に基づいて表示されます。
関数名が正規表現として指定される終了プローブでは、戻り値にはアクセスできません。
Probevue では、同時に複数のプロセスでプローブを使用可能にすることができます。 ただし、ユーザーのプロセスをプローブする場合でも特権が必要です。
Probevue は、ptrace または procfs ベースの API を使用してユーザー・スペース・プローブのプロセスがデバッグされないように制限を課します。
前述のとおり、UFT プローブ・マネージャーは、共有ライブラリー・モジュールのような共有モジュールのプローブをサポートしています。 次のスクリプトは、スレッド・ライブラリーの mutex ロックおよびアンロック・サブルーチンのプローブを使用可能にして、mutex アクティビティーをトレースする例を示しています。
/* pthreadlocks.e */
/* Trace pthread mutex activity for a given multithreaded process */
/* The following defines are from /usr/include/sys/types.h */
typedef long long pid_t;
typedef long long thread_t;
typedef struct {
int __pt_mutexattr_status;
int __pt_mutexattr_pshared;
int __pt_mutexattr_type;
} pthread_mutexattr_t;
typedef struct __thrq_elt thrq_elt_t;
struct __thrq_elt {
thrq_elt_t *__thrq_next;
thrq_elt_t *__thrq_prev;
};
typedef volatile unsigned char _simplelock_t;
typedef struct __lwp_mutex {
char __wanted;
_simplelock_t __lock;
} lwp_mutex_t;
typedef struct {
lwp_mutex_t __m_lmutex;
lwp_mutex_t __m_sync_lock;
int __m_type;
thrq_elt_t __m_sleepq;
int __filler[2];
} mutex_t;
typedef struct {
mutex_t __pt_mutex_mutex;
pid_t __pt_mutex_pid;
thread_t __pt_mutex_owner;
int __pt_mutex_depth;
pthread_mutexattr_t __pt_mutex_attr;
} pthread_mutex_t;
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
@@uft:$__CPID:*:pthread_mutex_lock:entry
{
printf("thread %d: mutex 0x%08x locked\n", __tid, __arg1);
}
@@uft:$__CPID:*:pthread_mutex_unlock:entry
{
printf("thread %d: mutex 0x%08x unlocked\n", __tid, __arg1);
}
- ユーザーは、 Fortran データ型を ProbeVue データ型にマップし、スクリプトで同じデータ型を使用する必要があります。 Fortran 基本データ型から ProbeVue データ型へのマッピングを以下の表に示します。
表 1. Fortran データ型と ProveVue データ型のマッピング Fortran データ型 ProbeVue データ型 INTEGER * 2 簡略 INTEGER * 4 int/long INTEGER * 8 long long REAL float DOUBLE PRECISION double COMPLEX 同等の基本データ型はありません。 これは、次に示すように構造体にマップする必要があります。 typedef struct complex { float a; float b; } COMPLEX;LOGICAL int (Fortran の規格では、論理変数が INTEGER/REAL 変数と同じサイズであることが求められます) CHARACTER char BYTE signed char - Fortran は、内部プロシージャーの IN スカラー引数を値によって渡し、他の引数を参照によって渡します。 参照によって渡される引数には、 copy_userdata()でアクセスする必要があります。 fortran の引数の関連付けに関する詳細情報は、 引数の関連付け トピックに記載されています。
- Fortran プログラムのルーチン名では大文字小文字が区別されません。 ただし、 ProbeVue スクリプトで指定する場合は、小文字にする必要があります。以下のサンプル・スクリプトは、 Fortran データ型を ProbeVue データ型にマップする方法を示しています。
/* cmp_calc.e */ /* Trace fortran routines cmp_calc(COMPLEX, INTEGER) and cmplxd(void) */ typedef struct complex{ float a; float b; } COMPLEX; typedef int INTEGER; /* arguments are indicated to be of pointer type as they are passed by reference */ void cmp_calc(COMPLEX *, INTEGER *); void cmplxd(); @@uft:$__CPID:*:cmplxd:entry { printf("In cmplxd entry \n"); } @@uft:$__CPID:*:cmp_calc:entry { COMPLEX c; int i; copy_userdata(__arg1, c); copy_userdata(__arg2, i); printf("%10.7f+j%9.7f %d \n", c.a,c.b,i); } - Fortran は配列をカラム・メジャー形式で保管しますが、 ProbeVue は行メジャー形式で保管します。以下のスクリプトは、ユーザーが配列エレメントを検索する方法を示しています。
/* array.e*/ /* ProbeVue script to probe fortran program array.f */ void displayarray(int **, int, int); @@uft:$__CPID:*:displayarray:entry { int a[5][4]; /* row and column sizes are interchanged */ copy_userdata(__arg1, a); /* to print the first row */ printf("%d %d %d \n”, a[0][0], a[1][0], a[2][0]); /* to print the second row */ printf(“%d %d %d\n", a[0][1], a[1][1], a[2][1]); } /* Fortran program array.f */ PROGRAM ARRAY_PGM IMPLICIT NONE INTEGER, DIMENSION(1:4,1:5) :: Array INTEGER :: RowSize, ColumnSize CALL ReadArray(Array, RowSize, ColumnSize) CALL DisplayArray(Array, RowSize, ColumnSize) CONTAINS SUBROUTINE ReadArray(Array, Rows, Columns) IMPLICIT NONE INTEGER, DIMENSION(1:,1:), INTENT(OUT) :: Array INTEGER, INTENT(OUT) :: Rows, Columns INTEGER :: i, j READ(*,*) Rows, Columns DO i = 1, Rows READ(*,*) (Array(i,j), j=1, Columns) END DO END SUBROUTINE ReadArray SUBROUTINE DisplayArray(Array, Rows, Columns) IMPLICIT NONE INTEGER, DIMENSION(1:,1:), INTENT(IN) :: Array INTEGER, INTENT(IN) :: Rows, Columns INTEGER :: i, j DO i = 1, Rows WRITE(*,*) (Array(i,j), j=1, Columns ) END DO END SUBROUTINE DisplayArray END PROGRAM ARRAY_PGM - 組み込み関数または組み込み関数は、 ProbeVue ではプローブできません。 プローブできるのは、実行可能/リンクされたライブラリーの XCOFF シンボル・テーブルにリストされているすべての FORTRAN ルーチンです。 ProbeVue は XCOFF シンボル・テーブルを使用して、これらのルーチンの場所を識別します。 ただし、ルーチンのプロトタイプはユーザーが提供する必要があり、 ProbeVue は提供されたプロトタイプに従って引数にアクセスしようとします。 コンパイラーがルーチン名をマングルするルーチンでは、マングルされた名前を指定する必要があります。 Vue は C スタイルの言語であるため、ユーザーは FORTRAN 関数/サブルーチンのプロトタイプが、C 言語スタイルの関数プロトタイプに適切にマップされていることを確認する必要があります。 「ある言語から別の言語へのデータの引き渡し」 トピックで、引数の引き渡しと関数の戻り値に関するリンケージ規約を参照してください。 次の例にこれを示します。
/* Fortran program ext_op.f */ /* Operator “*” is extended for rational multiplication */ MODULE rational_arithmetic IMPLICIT NONE TYPE RATNUM INTEGER :: num, den END TYPE RATNUM INTERFACE OPERATOR (*) MODULE PROCEDURE rat_rat, int_rat, rat_int END INTERFACE CONTAINS FUNCTION rat_rat(l,r) ! rat * rat TYPE(RATNUM), INTENT(IN) :: l,r TYPE(RATNUM) :: val,rat_rat val.num=l.num*r.num val.den=l.den*r.den rat_rat=val END FUNCTION rat_rat FUNCTION int_rat(l,r) ! int * rat INTEGER, INTENT(IN) :: l TYPE(RATNUM), INTENT(IN) :: r TYPE(RATNUM) :: val,int_rat val.num=l*r.num val.den=r.den int_rat=val END FUNCTION int_rat FUNCTION rat_int(l,r) ! rat * int TYPE(RATNUM), INTENT(IN) :: l INTEGER, INTENT(IN) :: r TYPE(RATNUM) :: val,rat_int val.num=l.num*r val.den=l.den rat_int=val END FUNCTION rat_int END MODULE rational_arithmetic PROGRAM Main1 Use rational_arithmetic IMPLICIT NONE TYPE(RATNUM) :: l,r,l1 l.num=10 l.den=11 r.num=3 r.den=4 L1=l*r END PROGRAM Main1 /* ext_op.e */ /* ProbeVue script to probe routine that gets called when “*” is used to multiply rational numbers in ext_op.f */ struct rat { int num; int den; }; struct rat rat; void __rational_arithmetic_NMOD_rat_rat(struct rat*, struct rat*,struct rat*); /* Note that the mangled function name is provided. */ /* Also, the structure to be returned is sent in the buffer whose address is provided as the first argument. */ /* The first explicit parameter is in the second argument. */ @@BEGIN { struct rat* rat3; } @@uft:$__CPID:*:__rational_arithmetic_NMOD_rat_rat:entry { struct rat rat1,rat2; copy_userdata((struct rat *)__arg2,rat1); copy_userdata((struct rat *)__arg3,rat2); rat3=__arg1; /* The address of the buffer where the returned structure will be stored is saved at the function entry */ printf("Argument Passed rat_rat = %d:%d,%d:%d\n",rat1.num,rat1.den,rat2.num,rat2.den); } @@uft:$__CPID:*:__rational_arithmetic_NMOD_rat_rat:exit { struct rat rrat; copy_userdata((struct rat *)rat3,rrat); /* The saved buffer address is used to fetch the returned structure */ printf("Return from rat_rat = %d:%d\n",rrat.num,rrat.den); exit(); } - ProbeVue は、スクリプトに Fortran ヘッダー・ファイルを直接組み込むことをサポートしません。 ただし、 Fortran データ型から ProbeVue データ型へのマッピングは、 ProbeVue ヘッダー・ファイルで提供でき、「-I」オプションを使用して組み込むことができます。