Изменить имя процесса в Linux - PullRequest
18 голосов
/ 21 мая 2011

Я нахожусь в Linux, и я создаю новый процесс из моего приложения C spawn.Можно ли также изменить наименование этих новых дочерних процессов?

Я хочу иметь возможность определить, какой процесс запускается, если что-то идет не так, и мне нужно убить его вручную.В настоящее время все они имеют одинаковые имена.

Ответы [ 3 ]

13 голосов
/ 21 мая 2011

Я думаю, что это должно сработать, чтобы проиллюстрировать принцип ...

#include <stdio.h>

int main(int argc, char *argv[]) {
  argv[0][0] = 65;
  sleep(10);
}

изменит имя и поставит букву «А» вместо первой буквы.CtrlZ для паузы, затем наберите ps, чтобы увидеть, как изменилось имя.Я понятия не имею, но это кажется несколько опасным, поскольку некоторые вещи могут зависеть от argv[0].

Также я попытался заменить сам указатель на другую строку;без сигарыТак что это будет работать только с strcpy и строками, которые короче или равны оригинальному имени.

Может быть или не быть лучшего способа для этого.Я не знаю.

РЕДАКТИРОВАТЬ: нелитеральное решение: Если вы разветвляетесь, вы знаете PID ребенка (getpid() у ребенка, результат fork() у родителя).Просто выведите его куда-нибудь, где вы сможете прочитать его, и убейте дочерний элемент с помощью PID.

другое нелитеральное решение: создайте программные ссылки на исполняемый файл с другим именем (ln -s a.out kill_this_a.out), затем при выполнении exec выполните ссылку.Имя будет именем ссылки.

0 голосов
/ 09 апреля 2019

В одном из комментариев упоминается prctl, но это действительно заслуживает отдельного ответа, потому что настройка argv[0] не будет работать во всех случаях (она ничего не делает в моей системе).

Существует не менее двух библиотечных вызовов для установки имени потока в Linux, оба ограничены 15 символами плюс завершающий NUL байт:

  1. специфично для glibc: pthread_setname_np(...), где np означает «непереносимый», но это может присутствовать в некоторых других ОС: https://linux.die.net/man/3/pthread_setname_np
  2. Для Linux: 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)

Смотри также

См. Также эти вопросы и ответы:

0 голосов
/ 12 июня 2017

Приведенный ниже пример кода изменит название процесса на «Тестирование».

    #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] содержит имя процесса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...