Name

psleaks — Reports process attributes associated with resource leaks.

Synopsis

psleaks [ -p TEXT | --pids TEXT ] [ --pgrep TEXT ] [ -r [true]|false | --recurse [true]|false ] [ --format TEXT ] [ -s TEXT | --sort TEXT ] [ --reverse [true]|false ] [ --no-headers [true]|false ] [ --version [true]|false ] [ -h [true]|false | --help [true]|false ]

Description

The psleaks command is typically used during software development when testing for resource leaks. This command reports information for one or more processes in a table format as shown below.

[root@probe ~]# psleaks --pids "28353 21249, 27367" --pgrep sshd;

Name                 PID Thrd File Net  %CPU %Mem RSS     VSZ      Elapsed     
---------------- ------- ---- ---- ---- ---- ---- ------- -------- ------------
sshd                1117    1    5    2  0.0  0.0    7692    99972   6-05:59:18
sshd                9492    1    8    1  0.0  0.0    9668   163632     18:02:01
sshd                9533    1   12    0  0.0  0.0    5052   163632     18:01:53
sshd               13465    1    8    1  0.0  0.0    9632   163632     17:20:19
sshd               13467    1   15    2  0.0  0.0    5044   163632     17:20:19
chrome             21249   16   52    0  0.0  0.7  123260  1303832   1-00:36:19
mate-terminal      27367    4   14    0  0.0  0.3   51760   749648   2-23:15:30
java               28353   38   40    0  0.5  1.1  184996  8238608   1-15:36:41
---------------- ------- ---- ---- ---- ---- ---- ------- -------- ------------
Counts/Sums            8   63  154    6  0.5  2.1  397104 11046588            7

The output table contains the following columns.

Name (Process Name)

The first 16 characters of the process name from the base name of the "command" column in the ps output.

PID (Process ID)

The unique integer process ID associated with the process.

PPID (Parent Process ID)

The unique integer process ID of the parent process that this process belongs to. NOTE: This column is omitted in the standard "compact" format. This value comes from the "ppid" column in the ps output.

User (user account)

The user account associated with the process. NOTE: This column is omitted in the standard "compact" format. This value comes from the "user" column in the ps output.

Thrd (Thread Count)

The number of threads associated with the process from the "nlwp" column in the ps output. If you see this count continue to increase over time, it may indicate that the process has a "thread leak".

File (File Count)

The number of open file descriptors associated with the process. This comes from counting the number of entries under the /proc/PID/fd directory. If you see this count continue to increase over time, it may indicate that the process has a "file descriptor" leak. It should be noted that network connections also appear in this count. If you see -1 in this column, it indicates that we didn't have the necessary permissions to retrieve the information (try running as root with sudo).

Net (TCP/UDP Count)

The number of TCP or UDP network connections that are associated with the process. This comes from looking for the PID value in the last column of the "netstat -tunap" output. If you see this count continue to increase over time, it may indicate that the process is opening network connection, but failing to close them and has a "network connection" leak. If you see -1 in this column, it indicates that we didn't have the necessary permissions to retrieve the information (try running as root with sudo).

%CPU

This column displays the CPU utilization of the process and is computed by dividing the total amount of CPU time used by the process by the time that the process has been running. This value comes from the "%cpu" column in the ps output. If you see this count continue to increase over time, it may indicate that the process has a "CPU leak" (the complexity of the problems it solves grows as it continues to process information). It is possible for this value to exceed 100.0% if the threads within a process are consuming more resources than a single core can provide.

%Mem (Resident/Physical Memory Usage)

The ratio of the resident memory consumed by the process to the total physical memory available on the machine. This value comes from the "%mem" column in the ps output. If you see this count continue to increase over time, it may indicate that the process has a "memory leak".

RSS (Resident Memory Usage)

This column shows the resident non-swapped physical memory of the process in kiloBytes. This value comes from the "rss" column in the ps output. If you see this count continue to increase over time, it may indicate that the process has a "memory leak". However, for some processes, it is normal for this value to fluctuate over time or to grow to a stable point, you may need to take several samples after the process has run for a long time before becoming too worried.

VSZ (Virtual Memory Size)

This column shows the virtual memory size of the process in KiB. This value comes from the "vsz" column in the ps output. If you see this count continue to increase over time, it may indicate that the process has a "memory leak". However, for some processes, it is normal for this value to fluctuate over time or to grow to a stable point, you may need to take several samples after the process has run for a long time before becoming too worried. It is possible to see this value continue to increase without seeing the RSS value continue to increase. For example, if a process forgets to release memory that it no longer references the memory will swap out of the RSS space, but still consume VSZ space.

Elapsed (How long since started)

This column contains how long the process has been running. This value comes from the "etime" column in the ps output. If you have noticed the process leaking one or two resources, but you see that this duration is a very large value (like 180 days) it may indicate that it is a low priority leak to run down in your code.

There are several things to consider when using psleaks:

  • You can always get information for the processes that you own.

  • You can get partial information for processes that you don't own. The File and Net count columns will show -1 if you request information for processes that you don't own. You can run as the root user via sudo if you need this information.

  • It is legal to include both the "--pids PIDLIST" and "--pgrep PATTERN" command line options to display a table of all of the resulting PIDs.

  • It is legal to omit both the "--pids PIDLIST" and "--pgrep PATTERN" command line options to display just the table header.

The "--pids PIDLIST" option can be used in a variety of ways. You don't need to explicitly list integer values. You can use other commands to generate the pid list for you. For example, the following reports on the init process (1) and all of the processes owned by the "jdoe" user:

[root@probe ~]# psleaks --pids "1 $(pgrep -u nstwui;)";

Name                 PID Thrd File Net  %CPU %Mem RSS     VSZ      Elapsed     
---------------- ------- ---- ---- ---- ---- ---- ------- -------- ------------
systemd                1    1  116    6  0.0  0.0    9160   221300   6-06:00:28
httpd               1187   22   12    0  0.0  0.2   34364   892900   6-06:00:23
httpd               1192    6   12    0  0.0  0.2   32664   696056   6-06:00:23
httpd               1216    6   13    0  0.0  0.3   53988   835056   6-06:00:23
httpd               1222    6   13    0  0.0  0.3   53864   835032   6-06:00:23
httpd               2785    6   12    0  0.0  0.1   32216   695984   6-05:58:43
httpd               3047    6   12    0  0.0  0.1   27892   695568   6-05:58:30
httpd               3048    6   12    0  0.0  0.1   31848   695836   6-05:58:30
httpd               3054    6   12    0  0.0  0.1   27960   695568   6-05:58:30
httpd               3060    6   12    0  0.0  0.1   28980   696072   6-05:58:30
httpd              12774    6   12    0  0.0  0.1   28568   695664   1-03:07:22
---------------- ------- ---- ---- ---- ---- ---- ------- -------- ------------
Counts/Sums           11   77  238    6  0.0  1.6  361504  7655036            5

Counts/Summary

Unless you specify the "--no-headers" option, the ASCII tables will include column headings and footer summary information. For the most part, the value below each column will be the sum of the values in the column. However, there are some things to be aware of.

  • The value below the PID, PPID, User and Elapsed columns will be the count of unique values in the corresponding column.

  • For columns where a summation or count does not make sense (like Elapsed), you will see "na" indicating that a summary value is not applicable to this column.

  • Sums are provided for the "%CPU" and "%Mem" columns. However, this information may not be that useful or accurate - especially in the case where there is a lot of variation in the "Elapsed" time column.

Recursive Search For PIDs

You can use the "--recurse" option to recursively search for all children, the children of the children and so on for the list of processes specified. This is the easiest way to track down all of the related processes for applications that spawn multiple processes. The following example demonstrates using this method to track down all of the processes started by the Google Chrome browser.

[root@probe ~]# psleaks --pgrep chrome --recurse;

Name                 PID Thrd File  Net  %CPU %Mem     RSS      VSZ      Elapsed
---------------- ------- ---- ---- ---- ----- ---- ------- -------- ------------
chrome              2492   48  343   24   2.9  1.8  304104  1662160     10:06:15
cat                 2528    1    3    0   0.0  0.0     652   114776     10:06:15
cat                 2529    1    3    0   0.0  0.0     800   114776     10:06:15
chrome              2532    1   16    0   0.0  0.3   53868   536932     10:06:15
nacl_helper         2533    1    7    0   0.0  0.0    8264   116876     10:06:15
chrome              2536    1   17    0   0.0  0.0   12296   536932     10:06:15
chrome              2599    8  135    0   1.0  1.9  315188   880440     10:06:14
chrome              2609    1   18    0   0.0  0.0   14532   560544     10:06:14
chrome              2634   18   60    0   0.6  2.3  386416  1598896     10:06:14
chrome              2674   15   36    0   0.0  0.4   75236  1242880     10:06:14
chrome              2714   15   36    0   0.0  0.4   71772  1221368     10:06:14
chrome              2731   15   44    0   0.5  0.7  121048  1300136     10:06:14
chrome              2786   22   73    0   3.3  1.4  238812  1549012     10:06:14
chrome              2865   16   48    0   0.0  0.5   94412  1275308     10:06:11
chrome              5215   18   59    0   0.4  1.1  188204  1411840     09:31:25
chrome              5566   20   51    0   0.4  0.8  143480  1359644     09:25:47
chrome              7226   16   52    0   0.3  0.7  123376  1348748     08:57:01
chrome             12393   16   51    0   0.1  0.8  137980  1347704     04:44:49
chrome             12647   16   48    0   0.3  0.7  118656  1294140     04:42:35
chrome             15353   16   47    0   0.0  0.6  104184  1297084     03:56:52
chrome             23966   16   40    0   0.3  0.7  114584  1306576        12:52
chrome             24033   16   47    0   0.4  0.7  118024  1306812        12:29
chrome             24208   37   70    0   8.4  1.2  208880  1528204        11:17
chrome             24249   17   56    0   0.5  0.8  144280  1347572        11:11
---------------- ------- ---- ---- ---- ----- ---- ------- -------- ------------
Counts/Sums           24  351 1360   24  19.4 17.8 3099048 26259360           13

The above output shows that running Google Chrome consumes a large number of resources. This output also demonstrates a case where the the summary %CPU value looks pretty high at 19.4%. There is a bit of uncertainty in this value as process 24208 makes up 8.4% but has only been active for 11 minutes and 17 seconds compared to many of the other processes that have been running longer.

This example demonstrates using the "--recurse" option to track down all Apache Web Server processes using the "wide" format.

[root@probe ~]# psleaks --pgrep httpd --recurse --format wide;

Name                 PID    PPID User         Thrd File  Net   %CPU %Mem       RSS        VSZ      Elapsed
---------------- ------- ------- ------------ ---- ---- ---- ------ ---- --------- ---------- ------------
httpd             378086       1 root            1   12    2    0.0  0.4     17504      44244     08:09:02
httpd             378090  378086 nstwui          1   12    0    0.0  0.2      8916      54300     08:09:02
httpd             378091  378086 nstwui         65   17    0    0.0  1.1     46596    2307868     08:09:02
httpd             378092  378086 nstwui         81   17    0    0.0  0.6     28004    2557232     08:09:02
httpd             378093  378086 nstwui         65   23    4    0.0  1.0     41332    2373148     08:09:02
httpd             378305  378086 nstwui         65   18    1    0.0  1.1     47132    2373404     08:09:01
---------------- ------- ------- ------------ ---- ---- ---- ------ ---- --------- ---------- ------------
Counts/Sums            6       2 2             278   99    7    0.0  4.4    189484    9710196            2

Since getting a "recursive" list of process IDs can be useful for other tasks (pgrep does not seem to support this). You can use the "pids" format if you want to reduce the output to just the process IDs found.

[root@probe ~]# psleaks --pgrep chrome --recurse --format pids;

2492 2532 2536 2599 2609 2634 2674 2714 2731 2786 2865 26048 27226 27250 28139 28169 28217 28683 2528 2529 2533

Options

The following command line options are available:

[-p TEXT] | [--pids TEXT]

Use this option to specify a list of 1 or more process IDs (PIDs). For example, "2122 2414" and "3333,3124,3990" are both valid PID lists. Each process ID must be an integer value of an active process that can be found using the ps command. You can use commas and or spaces to separate each PID in the list.

[--pgrep TEXT]

Use this option to specify a pattern for the pgrep command. The resulting PIDs of the pgrep output will be included in the table. This option can be used in combination with or instead of the "--pids PIDLIST" option.

[-r [true]|false] | [--recurse [true]|false]

Use this option to recursively search for and include all descendents of the processes specified by the "--pids PIDLIST" and "--pgrep PATTERN". For example, specifying "--pgrep chrome --recurse" could be used to report on all processes started by the Google Chrome browser.

[--format TEXT]

Use this option to specify a the output format. There are currently four output formats available. The "compact" format (the default) produces a table that will fit in a 80 column terminal session. The "wide" format adds more information and makes several of the columns wider. The "json" format dumps the output in a non-human readable JSON format that may be easier to use in some situations when you want to write another program to make use of the resulting table. The "pids" format just list the process IDs (similar to the pgrep). The "pids" format is typically not used unless you are also using the "--recurse" option (recursion is about the only thing that psleaks can do that pgrep can not do).

[-s TEXT] | [--sort TEXT]

Use this option to indicate the column that data should be sorted on. Legal column choices include: "none", "name", "pid", "ppid", "threads", "files", "network", "cpuPct", "memPct", "rss", "vsz", "elapsed", "user". If this option is omitted sorting will be done using the column "pid" (this is the default). You can specify "none" if you don't need the output sorted (to save a few CPU cycles). Sorting by "pid" will be done with an ascending sort (lower PID values towards the top of the table). Sorting by any other column will result in a descending sort (higher values like memory usage will float to the top of the table).

[--reverse [true]|false]

Use this option to reverse the normal sort order of the column. For example, if you are sorting by "pid" then the largest PID would appear at the top of the table. If you were sorting by "rss" the the smallest memory usage would appear at the top of the table.

[--no-headers [true]|false]

Use this option to disable any headers and footers in the ASCII output. This can be useful when post-processing the ASCII output.

[--version [true]|false]

Use this option to see the version of the psleaks software that is being run.

[-h [true]|false] | [--help [true]|false]

Use this option to display a short synopsis showing the command line options recognized by the psleaks command.

See Also

netstat(8), ps(1), Network Security Toolkit