在Linux中更改进程名称

时间:2011-05-21 13:58:51

标签: c linux process

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

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

5 个答案:

答案 0 :(得分:13)

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

#include <stdio.h>

int main(int argc, char *argv[]) {
  argv[0][0] = 65;
  sleep(10);
}

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

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

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

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

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

答案 1 :(得分:0)

其中一条评论提到了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;
}

注意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]

在野外

Here's an example in production code(一如既往,在GitHub上查看代码时,请务必注意许可证)

另请参见

另请参阅以下问题和答案:

答案 2 :(得分:0)

根据this commentprctl(PR_SET_NAME)仅影响线程的“短名称”。它的作用与写入/proc/self/comm的作用相同。

要更改“长名”(/proc/self/cmdlinehtop实际使用的“长名”),您需要进行一些丑陋的修改(该注释中已提及,但链接已失效) )。可在Chromium源代码中找到这种黑客的示例:https://cs.chromium.org/chromium/src/services/service_manager/embedder/set_process_title_linux.cc?sq=package:chromium&g=0

答案 3 :(得分:0)

这是不可移植的骇客:

/*
 * Sets process title, truncating if there is not enough space, 
 * rather than causing memory corruption.
 */
void set_title_np(int argc, char **argv, const char *title) {
    // calculate available size
    size_t space = 0;
    for (int i = 0; i < argc; i++) {
        size_t length = strlen(argv[i]);
        space += length + 1; // because of terminating zero 
    }
    memset(argv[0], '\0', space); // wipe existing args
    strncpy(argv[0], title, space - 1); // -1: leave null termination, if title bigger than space
} 

答案 4 :(得分:-1)

以下代码示例会将进程名称更改为“Testing”。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    int main (int argc, char *argv[]) {
    char* temp = (char*) malloc (20);
    strcpy(temp, "Testing");
    temp[7] = 0;
    printf("Argv[0] --> %s\n", argv[0]);
    argv[0] = temp;
    printf("Argv[0] --> %s\n", argv[0]);    
    return 0;
    }

以上程序的输出是:

./ a.out的

Argv [0] - &gt; ./a.out

Argv [0] - &gt;测试

argv [0]包含进程的名称。