UFT 프로브 관리자

uft 또는 사용자 함수 추적 프로브 관리자는 프로세스의 XCOFF 기호 표에서 표시할 수 있는 사용자 공간 함수의 점검을 지원합니다. uft 프로브 관리자는 기호 표에 소스가 C 또는 FORTRAN이 아닌 다른 언어로 된 기호가 포함되더라도 소스가 C 또는 FORTRAN 언어 텍스트 파일인 함수의 시작점 및 종료점에서 프로브 위치를 지원합니다.

사용자 관점의 기존 추적 메커니즘과 동일한 방식으로 Java™ 애플리케이션을 추적하며, JVM은 Probevue를 대신하여 대부분의 실제 작업을 수행합니다.

uft 프로브 관리자는 다음 형식으로 된 다섯 개의 튜플 프로브 스펙을 승인합니다.

uft:<processID>:*:<function_name>:<entry|exit>
참고: uft 프로브 관리자는 추적할 프로세스의 프로세스 ID와 프로브가 배치될 진입점 또는 종료점에 있는 함수의 전체 함수 이름을 요구합니다.
PID 또는 프로그램 이름

추적할 프로세스의 프로세스 ID 또는 프로빙할 프로그램 이름(실행 파일의 이름)을 지정합니다. 프로세스 ID 또는 실행 파일의 이름을 큰따옴표("/usr/bin/test") 또는 작은따옴표('/usr/bin/test'')로 입력하거나 파일 경로(/usr/bin/test')로 입력할 수 있습니다. 실행 파일의 절대 경로 또는 상대 경로를 제공할 수 있습니다. 프로그램 name 매개변수에 대한 값으로 실행 파일에 대한 하드 링크 또는 기호 링크를 제공할 수도 있습니다. 다음 예제에서는 두 번째 튜플 프로브 사양을 지정하는 다른 방법을 표시합니다.


@@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  
참고: 사용자는 한 번에 하나의 세션만 사용하여 실행 파일을 추적할 수 있습니다.

세 번째 필드가 *로 설정되면, UFT 프로브 관리자는 기본 실행 파일 및 공유 모듈을 포함하여 프로세스 주소 공간으로 로드되는 모든 모듈에서 함수를 검색합니다. 이는 프로그램에 이 이름을 가진 둘 이상의 C 함수가 있는 경우(예: 다른 오브젝트 모듈에 포함된 정적 클래스가 있는 함수), 프로브는 이러한 함수 모두의 시작점에 적용됩니다.

특정 모듈에 있는 함수 이름을 점검해야 하는 경우, 세 번째 필드에서 모듈 이름을 지정해야 합니다. 다음은 라이브러리 모듈 이름을 제공하는 프로브 스펙 구문에 대해 설명합니다.

# 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	  

네 번째 튜플에 있는 함수 이름은 ERE(Extended Regular Expression)로서 지정될 수 있습니다. ERE는 "/<ERE>/"와 같이 "//" 로 묶어야 합니다.

함수 이름이 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 프로브 관리자는 공유 라이브러리 모듈과 같은 공유 모듈에서 프로브를 지원합니다. 다음 스크립트는 스레드 라이브러리의 뮤텍스 잠금 및 잠금 해제 서브루틴에서 프로브를 사용으로 설정하여 뮤텍스 활동을 추적하는 예제를 표시합니다.

/* 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 플로트(스위치일 경우)
    DOUBLE PRECISION 이중 실선
    COMPLEX 동일한 기본 데이터 유형이 없습니다. 이는 아래 표시된 바와 같이 구조로 맵핑되어야 합니다.
    typedef struct complex {
    float a;
    float b;
    } COMPLEX;
    LOGICAL int(Fortran 표준에서는 논리 변수의 크기가 INTEGER/REAL 변수와 크기가 같아야 함)
    CHARACTER char
    BYTE signed char
  • Fortran은 내부 프로시저의 IN 스칼라 인수를 값으로 전달하고, 다른 인수는 참조로 전달합니다. 참조로 전달된 인수는 copy_userdata()로 액세스해야 합니다. 포트란의 인수 연결에 대한 자세한 내용은 인수 연결 항목에서 확인할 수 있습니다.
  • 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" 옵션에 포함될 수 있습니다.