Technical Blog Post
Abstract
PROBEVUE: EXECVE(), WAITPID(), _EXIT() [TRACK CHILDREN]
Body
This small script will show you how you can track a process' children activity. It tracks all
children that use 'exec()' for a given executable. Then for each one of those children it will
print the 'exit()' code and for the parent it will track the 'waitpid()' status after a child is gone.
This script can be used for example to track the activity from TSA related to db2 on
a purescale system. It will show all the monitor commands executed by TSA to monitor
the purescale system.
The script should be executed like this as root:
probevue -t 10 -e 75 -s 64 -o children1.out children1.pb
The output will look like this:
[ IBM.GblResRMd - 33816740 - 17563680 - 6751193 ] execve( [ExecCCommand] [5] [17] [70320] [/db2/db2ins1/sqllib/adm/db2rocme 1 CF db2ins1 128 MONITOR] [7] [] [] )
0xd08ded04
0xd4a9b224
0xd4a992e4
0xd7a2c908
...
[ ExecCCommand - 33816740 - 17563680 - 6751193 ] execve( [-ksh] [-c] [/db2/db2ins1/sqllib/adm/db2rocme 1 CF db2ins1 128 MONITOR] ) [Aug/09/17 10:13:14]
0x100001b8
0x10003e9c
0xd03b0e90
0x00003938
...
[ db2rocme - 33816740 - 17563680 - 6751193 ] _exit(1)
0x1000002f8
0x100003608
0x900000000056fe4
0x00003938
...
[ IBM.GblResRMd - 5701810 - 33816740 - 52297827 ] waitpid(17563680) = 17563680 [status 256 errno 0]
0xd08ded04
0xd4a9b224
0xd4a992e4
0xd7a2c908
...
The script is like this:
/*
* children1.pb: Follow children of 'IBM.GblResRMd'.
*
* Run as user 'root' using the following command line:
*
* probevue -t 10 -e 75 -s 64 -o children1.out children1.pb
*
* dalla
*/
/*
* Function prototypes (at least what we need).
*/
int _exit(int);
int execve(char *, char *, char *);
int waitpid(int *, int);
int kill(int, int);
/*
* Remember start time.
*/
__thread probev_timestamp_t in_waitpid;
__thread int waitpid_pid;
__thread int *waitpid_status;
__thread probev_timestamp_t waitpid_start;
__thread int in_kill;
__thread int kill_sig;
__thread int kill_pid;
__thread int monitor_me;
/*
* execve(): There is no 'loop' (while, for) possible in probevue so
* this has to be done one by one... Currently reads up to
* 8 arguments.
*/
@@syscall:*:execve:entry
when ((__pname == "IBM.GblResRMd") || (__pname == "ExecCCommand"))
{
__auto String buf[256];
__auto long long *addr[8];
__auto long long *ptr;
thread:monitor_me = 1;
copy_userdata(__arg2, addr);
/*
* Print the call.
*/
printf("[ %s - %ld - %ld - %ld ] execve(",
__pname, __ppid, __pid, __tid);
/*
* Now deal with 'av[]' array.
*/
ptr = (long long *) addr[0];
if (ptr) { /* av[0] */
buf = get_userstring(ptr, 256);
printf(" [%s]", buf);
ptr = (long long *) addr[1];
if (ptr) { /* av[1] */
buf = get_userstring(ptr, 256);
printf(" [%s]", buf);
ptr = (long long *) addr[2];
if (ptr) { /* av[2] */
buf = get_userstring(ptr, 256);
printf(" [%s]", buf);
ptr = (long long *) addr[3];
if (ptr) { /* av[3] */
buf = get_userstring(ptr, 256);
printf(" [%s]", buf);
ptr = (long long *) addr[4];
if (ptr) { /* av[4] */
buf = get_userstring(ptr, 256);
printf(" [%s]", buf);
ptr = (long long *) addr[5];
if (ptr) { /* av[5] */
buf = get_userstring(ptr, 256);
printf(" [%s]", buf);
ptr = (long long *) addr[6];
if (ptr) { /* av[6] */
buf = get_userstring(ptr, 256);
printf(" [%s]", buf);
ptr = (long long *) addr[7];
if (ptr) { /* av[7] */
buf = get_userstring(ptr, 256);
printf(" [%s]", buf);
}
}
}
}
}
}
}
}
printf(" )\n");
stktrace(GET_USER_TRACE, 20);
}
@@syscall:*:execve:exit
when ((__pname == "IBM.GblResRMd") || (__pname == "ExecCCommand"))
{
printf("[ %s - %ld - %ld - %ld ] execve() = %d\n",
__pname, __ppid, __pid, __tid, __rv);
}
@@syscall:*:waitpid:entry
when (__pname == "IBM.GblResRMd")
{
thread:in_waitpid = 1;
thread:waitpid_status = __arg1;
thread:waitpid_pid = __arg2;
thread:waitpid_start = timestamp();
}
@@syscall:*:waitpid:exit
when ((thread:in_waitpid == 1) && (__errno != 4))
{
__auto int status;
thread:in_waitpid = 0;
copy_userdata(thread:waitpid_status, status);
printf("[ %s - %ld - %ld - %ld ] waitpid(%d) = %d [status %d errno %d]\n",
__pname, __ppid, __pid, __tid, thread:waitpid_pid,
__rv, status, __errno);
stktrace(GET_USER_TRACE, 20);
}
@@syscallx:*:_exit:entry
when ((thread:monitor_me == 1) || (__pname == "ExecCCommand") ||
(__pname == "IBM.GblResRMd"))
{
printf("[ %s - %ld - %ld - %ld ] _exit(%d)\n",
__pname, __ppid, __pid, __tid, (int) __mst->r3);
stktrace(GET_USER_TRACE, 20);
}
@@syscall:*:kill:entry
when (__pname == "IBM.GblResRMd")
{
thread:in_kill = 1;
thread:kill_pid = __arg1;
thread:kill_sig = __arg2;
}
@@syscall:*:kill:exit
when (thread:in_kill == 1)
{
thread:in_kill = 0;
printf("[ %s - %ld - %ld - %ld ] kill(%d, %d) = %d [errno %d]\n",
__pname, __ppid, __pid, __tid, thread:kill_pid,
thread:kill_sig, __rv, __errno);
stktrace(GET_USER_TRACE, 20);
}
UID
ibm13286263