簡體   English   中英

在 Linux 中更改進程名稱

[英]Change process name in Linux

我在 Linux 上,我正在從我的 C spawn 應用程序中分叉/執行一個新進程。 是否也可以更改這些新子進程的命名?

我希望能夠識別正在啟動的進程,以防出現問題並且我需要手動終止它。 目前,它們都具有相同的名稱。

我認為這應該有效,以說明原理......

#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 )制作指向可執行文件的軟鏈接,然后在執行時執行鏈接。 該名稱將是鏈接的名稱。

根據此評論prctl(PR_SET_NAME)僅影響線程的“短名稱”。 它與寫入/proc/self/comm效果相同。

要更改“長名稱”( htopps u實際使用的/proc/self/cmdline ),您需要一些丑陋的 hack (該評論中提到了這一點,但鏈接已失效)。 可以在 Chromium 源代碼中找到此類 hack 的示例: https : //source.chromium.org/chromium/chromium/src/+/master : content/ common/ set_process_title_linux.cc

其中一條評論提到了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 : prctl(PR_SET_NAME...)

例子

這是對不同方法的測試(沒有錯誤處理):

// 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 上查看代碼時一定要注意許可證)

也可以看看

另請參閱這些問題和答案:

這是一個非便攜式黑客:

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

下面的代碼示例會將進程的名稱更改為“測試”。

    #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] 包含進程的名稱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM