IBM Support

PROBEVUE: EXECVE(), WAITPID(), _EXIT() [TRACK CHILDREN]

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);
}

[{"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SSEPGG","label":"Db2 for Linux, UNIX and Windows"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB10","label":"Data and AI"}}]

UID

ibm13286263