[英]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
效果相同。
要更改“長名稱”( htop
和ps 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
字節:
pthread_setname_np(...)
其中np
代表“不可移植”,但這可能存在於其他一些操作系統上: https : //linux.die.net/man/3/pthread_setname_npprctl(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.