UFT probe manager
The uft or the user function tracing probe manager supports probing user space functions that are visible in the XCOFF symbol table of a process. The uft probe manager supports probe points that are at entry and exit points of functions whose source is a C or FORTRAN language text file even though the symbol table can contain symbols whose sources are from a language other than C or FORTRAN.
The tracing of Java™ applications in a way identical to the existing tracing mechanism from the users point of view and the JVM is one that performs most of the real tasks on behalf of Probevue.
The uft probe manager accepts a 5-tuple probe specification in the following format:
uft:<processID>:*:<function_name>:<entry|exit>
- PID or program name
-
Specifies process ID of the process to be traced or the name of the program (name of the executable file) to be probed. You can provide the process ID or the name of the executable file in double quotes ("/usr/bin/test") or in single quotes('/usr/bin/test') or as a file path (/usr/bin/test) . You can provide the absolute path or the relative path of the executable file. You can also provide the hard link or the symbolic link to the executable file as a value to the program name parameter. The following examples show different ways to specify the second tuple probe specification.
Examples@@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
If /usr/bin/test is the executable file and /testln is the soft link to the /usr/bin/test file (/testln ->/usr/bin/test), run the following command to probe all processes that were started by running the /usr/bin/test executable file or the /testln soft link for that user.@@uft:/testln:*:foo:entry
When the third field is set to *, the UFT probe manager searches the function in all of the modules loaded into the process address space including the main executable and shared modules. This implies that if a program contains more than one C function with this name (for example, functions with static class that are contained in different object modules), then probes will be applied to the entry point of every one of these functions.
If a function name in a specific module needs to be probed, the module name needs to be specified in the third field. The probe specification syntax to provide the library module name is illustrated below:
# 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
The function name in the fourth tuple can be specified as an Extended Regular Expression (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
In the entry probes, where a function name is specified as a regular expression, individual arguments cannot be accessed. However, probevue function print_args can be used to print the function name and its arguments. The argument values is printed based on the argument type information available in the traceback table of the function.
In the exit probes, where a function name is specified as a regular expression, return value cannot be accessed.
Probevue supports enabling probes in more than one process at the same time. However, you will need privileges even for probing processes that belong to you.
Probevue enforces a restriction that prevents processes with user-space probes from being debugged using the ptrace or procfs based APIs.
As indicated above, the uft probe manager supports probes in shared modules like shared library modules. The following script shows an example that traces mutex activity by enabling probes in the thread library's mutex lock and unlock subroutines.
/* 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);
}
- User has to map the Fortran data types to ProbeVue
data types and use the same in the script. The mapping of Fortran basic data types to ProbeVue data types is listed in the below table.
Table 1. Fortran to ProveVue data types mapping Fortran data-type ProbeVue data-type INTEGER * 2 short INTEGER * 4 int/long INTEGER * 8 long long REAL float DOUBLE PRECISION double COMPLEX No equivalent basic data type. This needs to be mapped to a structure as shown below: typedef struct complex { float a; float b; } COMPLEX;
LOGICAL int (The Fortran standard requires logical variables to be the same size as INTEGER/REAL variables) CHARACTER char BYTE signed char - Fortran passes IN scalar arguments of internal procedures by value, and other arguments by reference. Arguments passed by reference should be accessed with copy_userdata(). More information on argument association in fortran can be found in the Argument association topic.
- Routine names in a Fortran program is case in-sensitive. But, while specifying them in a ProbeVue script, they should be in lower-case . The following sample script illustrates how to map Fortran data types to ProbeVue data types:
/* 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 stores arrays in column-major form, whereas ProbeVue stores in row-major form and the below script shows
how users can retrieve the array elements.
/* 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
- Intrinsic or built-in functions cannot be probed with ProbeVue . All FORTRAN routines as listed in the XCOFF symbol
table of the executable/linked libraries can be probed. ProbeVue uses the XCOFF symbol table to
identify the location of these routines. However, the prototype for the routine has to be provided
by the user and ProbeVue tries to access the arguments
according to the prototype provided. For routines where the compiler mangles the routine names, the
mangled name should be provided. Since Vue is a C-style language, user should ensure that the
FORTRAN function/subroutine prototype is appropriately mapped to C language style function
prototype. Please refer to the linkage conventions for argument passing and function return values
in the Passing data from one language to another topic. The below example illustrates
this:
/* 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 won’t support direct inclusion of Fortran header files in the script. However, a mapping of Fortran data types to ProbeVue data types can be provided in a ProbeVue header file and included with the “-I’’ option.