Salah satu komentar menyebutkan prctl
, tetapi ini benar-benar layak mendapatkan jawabannya sendiri, karena menyetel argv[0]
tidak akan berfungsi di semua kasus (tidak melakukan apa pun di sistem saya).
Setidaknya ada dua panggilan pustaka untuk menyetel nama utas di Linux, keduanya dibatasi hingga 15 karakter ditambah NUL
terminasi byte:
- khusus glibc:
pthread_setname_np(...)
di mananp
singkatan dari "non-portable", tetapi ini mungkin ada di beberapa OS lain:https://linux.die.net/man/3/pthread_setname_np - Khusus Linux:
prctl(PR_SET_NAME...)
yang juga non-portabel:https://linux.die.net/man/2/prctl
Contoh
Berikut adalah pengujian berbagai metode (tanpa penanganan kesalahan):
// 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;
}
Perhatikan kurangnya output setelah 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]
Di alam liar
Berikut adalah contoh dalam kode produksi (seperti biasa, pastikan untuk mencatat lisensi saat melihat kode di GitHub)
Lihat juga
Lihat juga pertanyaan dan jawaban ini:
- https://unix.stackexchange.com/questions/167490/how-can-a-process-appear-to-have-different-name-in-ps-output
- Menggunakan prctl PR_SET_NAME untuk menyetel nama proses atau utas?
Saya pikir ini harus berhasil, untuk mengilustrasikan prinsipnya...
#include <stdio.h>
int main(int argc, char *argv[]) {
argv[0][0] = 65;
sleep(10);
}
akan mengganti nama, dan meletakkan "A" sebagai pengganti huruf pertama. CtrlZ untuk menjeda, lalu jalankan ps
untuk melihat nama diubah. Saya tidak tahu, tapi sepertinya agak berbahaya, karena beberapa hal mungkin bergantung pada argv[0]
.
Juga, saya mencoba mengganti pointer itu sendiri ke string lain; tidak ada cerutu. Jadi ini hanya akan berfungsi dengan strcpy
dan string lebih pendek atau sama dengan nama aslinya.
Mungkin ada atau mungkin tidak ada cara yang lebih baik untuk ini. Saya tidak tahu.
EDIT:solusi nonliteral:Jika Anda bercabang, Anda tahu PID anak (getpid()
pada anak, hasil dari fork()
pada orang tua). Keluarkan saja di suatu tempat di mana Anda dapat membacanya, dan bunuh anak itu dengan PID.
solusi nonliteral lainnya:buat softlink ke executable dengan nama lain (ln -s a.out kill_this_a.out
), lalu saat Anda menjalankan, jalankan tautannya. Nama tersebut akan menjadi nama tautan.
Ini adalah peretasan non-portabel:
/*
* 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
}
Menurut komentar ini, prctl(PR_SET_NAME)
hanya mempengaruhi "nama pendek" dari sebuah utas. Ini memiliki efek yang sama seperti menulis ke /proc/self/comm
.
Untuk mengubah "nama panjang" (/proc/self/cmdline
yang sebenarnya digunakan oleh htop
dan ps u
) Anda memerlukan peretasan yang jelek (yang disebutkan dalam komentar itu tetapi tautannya mati). Contoh peretasan semacam ini dapat ditemukan di kode sumber Chromium:https://source.chromium.org/chromium/chromium/src/+/master:content/common/set_process_title_linux.cc