Einer der Kommentare erwähnt prctl
, aber das verdient wirklich eine eigene Antwort, weil das Setzen von argv[0]
wird nicht in allen Fällen funktionieren (es tut nichts auf meinem System).
Es gibt mindestens zwei Bibliotheksaufrufe, um den Namen eines Threads in Linux festzulegen, beide auf 15 Zeichen plus den abschließenden NUL
beschränkt byte:
- glibc-spezifisch:
pthread_setname_np(...)
wo dienp
steht für "non-portable", aber dies könnte auf einigen anderen Betriebssystemen vorhanden sein:https://linux.die.net/man/3/pthread_setname_np - Linux-spezifisch:
prctl(PR_SET_NAME...)
die auch nicht portierbar ist:https://linux.die.net/man/2/prctl
Beispiel
Hier ist ein Test der verschiedenen Methoden (ohne Fehlerbehandlung):
// 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;
}
Beachten Sie die fehlende Ausgabe nach 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 freier Wildbahn
Hier ist ein Beispiel im Produktionscode (achten Sie wie immer darauf, die Lizenz zu beachten, wenn Sie sich Code auf GitHub ansehen)
Siehe auch
Siehe auch diese Fragen und Antworten:
- https://unix.stackexchange.com/questions/167490/how-can-a-process-appear-to-have-different-name-in-ps-output
- Mit prctl PR_SET_NAME Namen für Prozess oder Thread setzen?
Ich denke, das sollte funktionieren, um das Prinzip zu veranschaulichen ...
#include <stdio.h>
int main(int argc, char *argv[]) {
argv[0][0] = 65;
sleep(10);
}
wird den Namen ändern und anstelle des Anfangsbuchstabens ein "A" setzen. StrgZ zum Anhalten, dann ps
ausführen um den geänderten Namen zu sehen. Ich habe keine Ahnung, aber es scheint etwas gefährlich zu sein, da einige Dinge von argv[0]
abhängen könnten .
Außerdem habe ich versucht, den Zeiger selbst durch eine andere Zeichenfolge zu ersetzen. Keine Zigarre. Das würde also nur mit strcpy
funktionieren und Zeichenfolgen, die kürzer oder gleich dem ursprünglichen Namen sind.
Es könnte einen besseren Weg dafür geben oder auch nicht. Ich weiß es nicht.
BEARBEITEN:nicht wörtliche Lösung:Wenn Sie forken, kennen Sie die PID des Kindes (getpid()
im Kind Ergebnis von fork()
im Elternteil). Geben Sie es einfach irgendwo aus, wo Sie es lesen können, und töten Sie das Kind per PID.
eine andere nicht wörtliche Lösung:Erstellen Sie Softlinks zu der ausführbaren Datei mit einem anderen Namen (ln -s a.out kill_this_a.out
), dann führen Sie den Link aus, wenn Sie ihn ausführen. Der Name ist der Name des Links.
Dies ist ein nicht-portabler 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
}
Laut diesem Kommentar prctl(PR_SET_NAME)
wirkt sich nur auf den "Kurznamen" eines Threads aus. Es hat den gleichen Effekt wie das Schreiben in /proc/self/comm
.
Um den "langen Namen" (/proc/self/cmdline
die tatsächlich von htop
verwendet wird und ps u
) brauchen Sie einen hässlichen Hack (der in diesem Kommentar erwähnt wird, aber der Link ist tot). Ein Beispiel für diese Art von Hack finden Sie im Chromium-Quellcode:https://source.chromium.org/chromium/chromium/src/+/master:content/common/set_process_title_linux.cc