Change process name in Linux Change process name in Linux c c

Change process name in Linux


I think this should work, to illustrate the principle...

#include <stdio.h>int main(int argc, char *argv[]) {  argv[0][0] = 65;  sleep(10);}

will change the name, and put an "A" instead of the first letter. CtrlZ to pause, then run ps to see the name changed. I have no clue, but it seems somewhat dangerous, since some things might depend on argv[0].

Also, I tried replacing the pointer itself to another string; no cigar. So this would only work with strcpy and strings shorter or equal than the original name.

There might or might not be a better way for this. I don't know.

EDIT: nonliteral solution: If you're forking, you know the child's PID (getpid() in the child, result of fork() in the parent). Just output it somewhere where you can read it, and kill the child by PID.

another nonliteral solution: make softlinks to the executable with another name (ln -s a.out kill_this_a.out), then when you exec, exec the link. The name will be the link's name.


According to this comment, prctl(PR_SET_NAME) only affects the "short name" of a thread. It has the same effect as writing into /proc/self/comm.

To change the "long name" (/proc/self/cmdline which is actually used by htop and ps u) you need some ugly hack (which is mentioned in that comment but the link is dead). An example of this kind of hack can be found in Chromium source code: https://source.chromium.org/chromium/chromium/src/+/master:content/common/set_process_title_linux.cc


One of the comments mentions prctl, but this really deserves its own answer, because setting argv[0] will not work in all cases (it does nothing on my system).

There are at least two library calls to set the name of a thread in Linux, both limited to 15 characters plus the terminating NUL byte:

  1. glibc-specific: pthread_setname_np(...) where the np stands for "non-portable", but this might be present on some other OSes: https://linux.die.net/man/3/pthread_setname_np
  2. Linux-specific: prctl(PR_SET_NAME...) which is also non-portable: https://linux.die.net/man/2/prctl

Example

Here's a test of the different methods (with no error handling):

// gcc pstest.c -o pstest -O2 -Wall -Wextra -Werror -Wno-unused -Wno-unused-result -std=gnu99 -pthread -D_GNU_SOURCE #include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <sys/prctl.h>int main(int argc, char *argv[]){    puts("Initial ps output:");    system("ps | grep pstest");    puts("\npthread_setname_np");    pthread_setname_np(pthread_self(), "setname");    system("ps | grep setname");    puts("\nprctl");    prctl(PR_SET_NAME, (unsigned long)"prctl", 0, 0, 0);    system("ps | grep prctl");    puts("\nargv[0]");    argv[0] = "argv0";    system("ps | grep argv0");    return 0;}

Notice the lack of output after argv[0]:

./pstestInitial ps output:17169 pts/0    00:00:00 pstestpthread_setname_np17169 pts/0    00:00:00 setnameprctl17169 pts/0    00:00:00 prctlargv[0]

In the wild

Here's an example in production code (as always, be sure to take note of the license when looking at code on GitHub)

See also

See also these questions and answers: