Jeden z komentářů uvádí prctl
, ale toto si opravdu zaslouží vlastní odpověď, protože nastavení argv[0]
nebude fungovat ve všech případech (v mém systému to nic nedělá).
Existují alespoň dvě volání knihovny pro nastavení názvu vlákna v Linuxu, obě jsou omezena na 15 znaků plus ukončovací NUL
byte:
- specifické pro glibc:
pthread_setname_np(...)
kdenp
znamená "non-portable", ale to může být přítomno na některých jiných OS:https://linux.die.net/man/3/pthread_setname_np - Specifické pro Linux:
prctl(PR_SET_NAME...)
který je také nepřenosný:https://linux.die.net/man/2/prctl
Příklad
Zde je test různých metod (bez zpracování chyb):
// 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;
}
Všimněte si nedostatku výstupu po 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]
V přírodě
Zde je příklad v produkčním kódu (jako vždy si nezapomeňte při prohlížení kódu na GitHubu poznamenat licenci)
Viz také
Viz také tyto otázky a odpovědi:
- https://unix.stackexchange.com/questions/167490/how-can-a-process-appear-to-have-different-name-in-ps-output
- Používáte prctl PR_SET_NAME k nastavení názvu procesu nebo vlákna?
Myslím, že by to mělo fungovat, abychom ilustrovali princip...
#include <stdio.h>
int main(int argc, char *argv[]) {
argv[0][0] = 65;
sleep(10);
}
změní název a místo prvního písmene vloží "A". CtrlZ pozastavte a poté spusťte ps
abyste viděli změnu názvu. Nemám tušení, ale zdá se mi to poněkud nebezpečné, protože některé věci mohou záviset na argv[0]
.
Také jsem se pokusil nahradit samotný ukazatel na jiný řetězec; žádný doutník. Takže to bude fungovat pouze s strcpy
a řetězce kratší nebo stejné než původní název.
Může nebo nemusí existovat lepší způsob. Nevím.
EDIT:nedoslovné řešení:Pokud plácáte, znáte PID dítěte (getpid()
v potomkovi, výsledek fork()
v rodiči). Prostě to vytiskněte někam, kde si to můžete přečíst, a zabijte dítě pomocí PID.
další nedoslovné řešení:vytvořte softwarové odkazy na spustitelný soubor s jiným názvem (ln -s a.out kill_this_a.out
), pak když spustíte, spusťte odkaz. Název bude názvem odkazu.
Toto je nepřenosný 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
}
Podle tohoto komentáře prctl(PR_SET_NAME)
ovlivňuje pouze "krátký název" vlákna. Má to stejný účinek jako zápis do /proc/self/comm
.
Chcete-li změnit "dlouhý název" (/proc/self/cmdline
který ve skutečnosti používá htop
a ps u
) potřebujete nějaký ošklivý hack (který je zmíněn v tom komentáři, ale odkaz je mrtvý). Příklad tohoto druhu hacku lze nalézt ve zdrojovém kódu Chromium:https://source.chromium.org/chromium/chromium/src/+/master:content/common/set_process_title_linux.cc