更改Linux中的进程名称

发布于 2024-11-08 20:32:39 字数 113 浏览 0 评论 0 原文

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

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

I'm on Linux and I am forking/execing a new process out of my C spawn application. Is it possible to also change the naming of these new child processes?

I want to be able to identify the process being started in case something goes wrong and I need to kill it manually. Currently they all have the same name.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

蓦然回首 2024-11-15 20:32:39

我认为这应该可行,为了说明原理......

#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)创建到可执行文件的软链接,然后当您执行时,执行该链接。该名称将是链接的名称。

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.

奶气 2024-11-15 20:32:39

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

在野外

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

请参阅另

请参阅以下问题和解答:

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]:

./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]

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:

筑梦 2024-11-15 20:32:39

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

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

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

写给空气的情书 2024-11-15 20:32:39

这是一个不可移植的黑客:

/*
 * 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
} 

This is a non-portable hack:

/*
 * 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
} 
街道布景 2024-11-15 20:32:39

下面的代码示例会将进程的名称更改为“测试”。

    #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] --> ./a.out

Argv[0] -->测试

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

The below code sample would change the name of the process to "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;
    }

The output of above program is:

./a.out

Argv[0] --> ./a.out

Argv[0] --> Testing

The argv[0] contains the name of the process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文