Изменить имя процесса в Linux
Я нахожусь в Linux, и я форкирую/выполняю новый процесс из своего приложения C spawn. Можно ли также изменить именование этих новых дочерних процессов?
Я хочу иметь возможность идентифицировать начавшийся процесс в случае, если что-то пойдет не так, и мне нужно его убить вручную. В настоящее время все они имеют одинаковое имя.
Ответы
Ответ 1
Я думаю, что это должно сработать, чтобы проиллюстрировать принцип...
#include <stdio.h>
int main(int argc, char *argv[]) {
argv[0][0] = 65;
sleep(10);
}
изменит имя и поместит вместо буквы "А" вместо первой буквы. CtrlZ для приостановки, затем запустите ps
, чтобы увидеть, как изменилось имя. У меня нет подсказки, но это кажется несколько опасным, поскольку некоторые вещи могут зависеть от argv[0]
.
Кроме того, я попытался заменить сам указатель на другую строку; нет сигары. Таким образом, это будет работать только с strcpy
и строками короче или равными исходному имени.
Там может быть и не лучше. Я не знаю.
EDIT: нелитеративное решение: если вы используете forking, вы знаете дочерний PID (getpid()
у ребенка, результат fork()
в родительском). Просто выведите его где-нибудь, где вы можете его прочитать, и убить ребенка с помощью PID.
другое нелитеративное решение: сделайте программные ссылки для исполняемого файла с другим именем (ln -s a.out kill_this_a.out
), затем, когда вы выполните exec, выполните ссылку. Имя будет именем ссылки.
Ответ 2
В одном из комментариев упоминается prctl
, но это действительно заслуживает отдельного ответа, потому что установка argv[0]
не будет работать во всех случаях (она ничего не делает в моей системе).
Существует как минимум два библиотечных вызова для установки имени потока в Linux, оба ограничены 15 символами плюс завершающий байт NUL
:
- специфично для glibc:
pthread_setname_np(...)
где np
означает "непереносимый", но это может присутствовать в некоторых других ОС: https://linux.die.net/man/3/pthread_setname_np - Для Linux:
prctl(PR_SET_NAME...)
который также является prctl(PR_SET_NAME...)
: https://linux.die.net/man/2/prctl
пример
Вот тест различных методов (без обработки ошибок):
// 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)
Смотрите также
Смотрите также эти вопросы и ответы:
Ответ 3
Согласно этому комментарию, prctl(PR_SET_NAME)
влияет только на "короткое имя" потока. Это имеет тот же эффект, что и запись в /proc/self/comm
.
Чтобы изменить "длинное имя" (/proc/self/cmdline
, которое на самом деле используется htop
и ps u
), вам нужен некрасивый хак (который упоминается в этом комментарии, но ссылка мертва). Пример такого взлома можно найти в исходном коде Chromium: https://cs.chromium.org/chromium/src/services/service_manager/embedder/set_process_title_linux.cc?sq=package:chromium&g=0
Ответ 4
Нижеприведенный пример кода изменит имя процесса на "Тестирование".
#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] → Тестирование
Аргус [0] содержит имя процесса.