2

The executable name is linux can be read in various ways.

  1. By reading /proc/[pid]/comm, which contains a string that's truncated after reaching 16 characters or TASK_COMM_LEN.
  2. By reading /proc/[pid]/cmdline which contains the command line used with arguments.

There are other ways like reading /proc/[pid]/stat, or /proc/[pid]/status, but they are similar to 1.

In case of Point 1, the proc(5) man page says:

The filename of the executable, in parentheses. Strings longer than TASK_COMM_LEN (16) characters (including the terminating null byte) are silently truncated. This is visible whether or not the executable is swapped out.


I have 3 processes that I see mismatch and highlight them (on my system right now):

  1. PID 7610
  2. PID 38193
  3. PID 37030

Consider these cases:

  1. PID 7610:
  • The content of /proc/7610/comm is Web Content
  • But the content of /proc/7610/cmdline is /opt/firefox-developer-edition/firefox-bin-contentproc-childID17-isForBrowser-prefsLen7837-prefMapSize238232-parentBuildID20201215185920-appdir/opt/firefox-developer-edition/browser4080truetab
  1. PID 38193:
  • The content of /proc/38193/comm is zyxwvutsrqponml
  • But the content of /proc/38193/cmdline is /ramdisk/abcdefghijklmnopqrstuvwxyz./zyxwvutsrqponmlkjihgfedcba

There's a \u0000 between ramdisk/abcdefghijklmnopqrstuvwxyz and ./zyxwvutsrqponmlkjihgfedcba that I can see programmatically, which I replace with \s.

  1. PID 37030
  • The content of /proc/37030/comm is kworker/3:1-xfs-reclaim/sda2
  • The content of /proc/37030/cmdline is empty.

  • In case 1, we see that the cmdline and comm are totally different.
  • In case 2, we see that the cmdline shows the whole command, but comm is truncated to 15 characters.
  • In case 3, we see that the cmdline is empty, but comm isn't truncated as it's supposed to be.

How does the file comm contains "kworker/3:1-xfs-reclaim/sda2" without getting truncated to 15 places (+ \n to be 16)?

How do I know if it's actually truncated or not, like in the case of point 2?

3
  • 1
    Note that /proc/7610/cmdline contains NULs, which aren't visible in the terminal but very much exist – Charles Duffy Jan 19 at 22:17
  • ...consider cmdline=( ); while IFS= read -r -d '' piece; do cmdline+=( "$piece" ); done </proc/7610/cmdline; printf '%q ' "${cmdline[@]}"; printf '\n' if you want to write a command-line list out to the terminal for human consumption (or written elsewhere for a shell-compatible parser to read) unambiguously. – Charles Duffy Jan 19 at 22:17
  • Yes, I have mentioned \u0000, which is \x00 or NUL in other words. – S.Goswami Jan 20 at 5:21
6

The only reliable way is via /proc/PID/exe, which will work even if the executable has been removed, or it never existed in the first place (as when executing a file created with memfd_create() via fexecve() or execveat(AT_EMPTY_PATH).

Both /proc/PID/comm and /proc/PID/cmdline can be easily faked by the process itself (the former via prctl(PR_SET_NAME), the latter just by overwriting the argv[] strings).

How does the file comm contains kworker/3:1-xfs-reclaim/sda2 without getting truncated to 15 places (+ \n to be 16)?

That's a kernel thread, not a userland process, and different rules apply ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.