IBM Support

PROBEVUE: DETECT FILE DESCRIPTORS LEAK

Technical Blog Post


Abstract

PROBEVUE: DETECT FILE DESCRIPTORS LEAK

Body

This small script will keep a list of file descriptors obtained by calls like 'open()',
accept(), socket() and store them in an associative array. When a given fd is closed
it will be marked 'closed' in the array. Every few seconds (1h by default) the script will output the list
of file descriptors in use by the process. Note that IOCP (IO Completion Port) related
file descriptors are not handled as probevue doesn't have access to those calls.

Some examples of output:

  -- open_files array (pid 11403730) [END PROBE]:
  key                             value
  0                               unused
  6                               notype - closed
  7                               notype - closed
  8                               /home/dalla/sqllib/db2dump/db2diag.log - closed - closed
  9                               /home/dalla/sqllib/db2dump/db2diag.log - closed
  10                              /home/dalla/sqllib/msg/en_US.iso88591/db2diag.mo - closed
  11                              /etc/vfs - closed
  12                              /home/dalla/dalla/NODE0000/SQL00001/SQLDBCONF - closed
  13                              /home/dalla/dalla/NODE0000/SQL00001/SQLOGCTL.GLFH.2 - closed
  14                              /home/dalla/dalla/NODE0000/SQL00001/LOGSTREAM0000/S0000001.LOG - closed
  15                              /home/dalla/dalla/NODE0000/SQL00001/LOGSTREAM0000/S0000002.LOG - closed
  16                              /home/dalla/dalla/NODE0000/SQL00001/SQLOGCTL.GLFH.2 - closed
  17                              /home/dalla/dalla/NODE0000/SQL00001/SQLDBCONF - closed - closed

As can be seen in the list each file descriptor (key) has a name or 'type'
associated with it and a flag indicating whether it's closed or not.

  -- open_files array (pid 58720996):
  key                             value
  0                               unused
  3                               socket()
  4                               accept()

  -- open_files array (pid 58720996) [END PROBE]:
  key                             value
  0                               unused
  3                               socket()
  4                               accept()

In this case, a server with 2 sockets opened. One for listening and the other
dedicated to an incoming connection.
 

The script is here:

/*
 * fdleak1.pb: Track files opened but not closed for a given process.
 *
 * Run as user 'root' using the following command line:
 *
 *     probevue -s 32 -o fdleak1.out fdleak1.pb <pid>
 *
 *
 * dalla
 */


int open(char *);
int close(int);
int socket();
int accept();


__thread int        in_open;
__thread char      *open_path;


int                 target;


@@BEGIN
{
    target = $1;

    if (target == 0) {
        printf("Usage: probevue -s 32 -o fdleak1.out fdleak1.pb <pid>\n");
        exit();
    }

    open_files[0] = "unused";
}


@@syscall:*:open:entry
when (__pid == target)
{
    thread:in_open = 1;

    thread:open_path = __arg1;
}

@@syscall:*:open:exit
when ((thread:in_open == 1) && (__rv >= 0))
{
    __auto String fname[256];

    fname = get_userstring((void *) thread:open_path, -1);

    open_files[__rv] = fname;

    thread:in_open = 0;
}


@@syscall:*:close:entry
when ((__pid == target) && (__arg1 >= 0))
{
    __auto String type[256];

    if (exists(open_files, __arg1)) {
        type = open_files[__arg1];
        open_files[__arg1] = type + " - closed";
    } else {
        open_files[__arg1] = "notype - closed";
    }

}


@@syscall:*:accept:exit
when ((__pid == target) && (__rv >= 0))
{
    open_files[__rv] = "accept()";
}


@@syscall:*:socket:exit
when ((__pid == target) && (__rv >= 0))
{
    open_files[__rv] = "socket()";
}


@@interval:*:clock:3600000
{
    printf("-- open_files array (pid %d):\n", target);
    print(open_files, 0, 0);
    printf("\n");
}


@@END
{
    printf("-- open_files array (pid %d) [END PROBE]:\n", target);
    print(open_files, 0, 0);
    printf("\n");

    exit();
}

 

[{"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

ibm13285837