3

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?

7
  • 1
    Note that /proc/7610/cmdline contains NULs, which aren't visible in the terminal but very much exist Commented Jan 19, 2021 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. Commented Jan 19, 2021 at 22:17
  • Yes, I have mentioned \u0000, which is \x00 or NUL in other words.
    – 15 Volts
    Commented Jan 20, 2021 at 5:21
  • @CharlesDuffy, an easier way to print the cmdline would be xargs -0 echo < /proc/pid/cmdline.
    – Juergen
    Commented Feb 23 at 22:18
  • @Juergen, that's deeply buggy. Using that practice you can't tell the difference between ./program "one argument" and ./program "one" "argument"; the point of printf %q is that it escapes strings with nonprintable characters unambiguously, so you can tell the difference (f/e) between spaces and tabs, or get output that tells you how to escape a non-breaking space in such a way as to reproduce the command line that was run. Commented Feb 24 at 14:54

1 Answer 1

7

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .