在Linux中更改进程名称

Fra*_*lea 18 c linux process

我在Linux上,我正在从我的C spawn应用程序中分配/执行一个新进程.是否也可以更改这些新子进程的命名?

我希望能够识别正在启动的进程,以防出现问题并且我需要手动终止它.目前它们都有相同的名称.

Ama*_*dan 13

我认为这应该有效,以说明原则......

#include <stdio.h>

int main(int argc, char *argv[]) {
  argv[0][0] = 65;
  sleep(10);
}
Run Code Online (Sandbox Code Playgroud)

将更改名称,并输入"A"而不是第一个字母.CtrlZ暂停,然后运行ps以查看名称已更改.我不知道,但似乎有点危险,因为有些事情可能依赖argv[0].

另外,我尝试将指针本身替换为另一个字符串; 没有雪茄.所以这只适用于strcpy和字符串短于或等于原始名称.

可能有也可能没有更好的方法.我不知道.

编辑:nonliteral解决方案:如果你正在分叉,你知道孩子的PID(getpid()在孩子,fork()父母的结果).只需将它输出到可以读取的地方,然后通过PID杀死孩子.

另一个非文字解决方案:使用另一个名称(ln -s a.out kill_this_a.out)生成可执行文件的软链接,然后当你执行时,执行链接.名称将是链接的名称.

  • 将重复环境变量用于额外空间是很难看的,例如参见[这里](http://koders.com/c/fidE817FBB097E080657B0A6977E5F4C9612BC1E923.aspx?s=setproctitle.c).使用最新的内核,您也可以执行`prctl(PR_SET_NAME,(unsigned long)"我的进程",0,0,0);` - 但并非所有实用程序都使用该名称作为默认显示名称(顶部,ps不)它的最大长度为16个字符. (7认同)
  • @Frank:这是支持的,如果你观察你的系统,你会发现一些程序可以做到这一点.您受现有参数大小的限制:您可以只覆盖单个字符,而不是调整缓冲区大小或使用不同的缓冲区. (2认同)

nit*_*gen 5

其中一条评论提到prctl,但这确实值得自己回答,因为设置argv[0]并非在所有情况下都有效(它在我的系统上没有任何作用)。

在 Linux 中,至少有两个库调用可以设置线程的名称,两者都限制为 15 个字符加上终止NUL字节:

  1. glibc 特定:pthread_setname_np(...)其中np代表“不可移植”,但这可能存在于其他一些操作系统上: https: //linux.die.net/man/3/pthread_setname_np
  2. Linux 特定:prctl(PR_SET_NAME...)也是不可移植的: https: //linux.die.net/man/2/prctl

例子

这是对不同方法的测试(没有错误处理):

// 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;
}
Run Code Online (Sandbox Code Playgroud)

请注意以下命令之后缺少输出argv[0]

./pstest
Initial ps output:
17169 pts/0    00:00:00 pstest

pthread_setname_np
17169 pts/0    00:00:00 setname

prctl
17169 pts/0    00:00:00 prctl

argv[0]
Run Code Online (Sandbox Code Playgroud)

在野外

这是生产代码中的示例(与往常一样,在 GitHub 上查看代码时请务必记下许可证)

也可以看看

另请参阅这些问题和答案:

  • argv[0] 部分是错误的:您必须直接覆盖内存,而不仅仅是更改指针:`strcpy(argv[0], "argv[0]");`。这就是为什么 Chromium 版本有这个丑陋的 hack,它将 argv 中不同参数的所有空间相加,以允许比程序最初调用的名称更长的名称。它利用了这样一个事实:在 Linux 中,所有 argv 都位于连续内存中(即 argv[1] == argv[0] + strlen(argv[0]) + 1) (2认同)

hex*_*ain 5

根据此评论prctl(PR_SET_NAME)仅影响线程的“短名称”。与写入 的效果相同/proc/self/comm

要更改“长名称”(/proc/self/cmdline实际上由htop和使用ps u),您需要一些丑陋的黑客(该评论中提到了这一点,但链接已失效)。这种黑客攻击的示例可以在 Chromium 源代码中找到: https: //source.chromium.org/chromium/chromium/src/+/master :content/common/set_process_title_linux.cc