Остановить или уничтожить поток с помощью ptrace? - PullRequest
0 голосов
/ 02 апреля 2019

Убить определенный поток в одном процессе из другого процесса.

Ниже мой код:

ptrace(PTRACE_ATTACH,threadID,NULL,NULL);

останавливает полный процесс, но я хочу только одинконкретная тема для остановки.

Не могли бы вы дать мне несколько советов о том, как действовать?

1 Ответ

2 голосов
/ 02 апреля 2019

Вы можете выполнить следующую процедуру:

1) Создайте канал и инициализируйте его.

2) Создайте обработчик сигнала для конкретного сигнала, и обработчик сигнала должен выполнять минимальные операции. В этом случае я запишу "signum" в конец записи канала.

3) Создание потока должно блокироваться при опросе, а также для чтения данных с конца чтения канала.

4) Тогда я буду игнорировать сигнал, который я использовал выше в других темах.

5) Затем перейдите к основному потоку, здесь у меня есть бесконечный цикл.

6) Теперь вы можете запустить программу и использовать идентификатор процесса для отправки сигнала с консоли. Например, предположим, что идентификатор процесса равен 24566, тогда я отправлю сигнал следующим образом:

kill -n 16 24566

Это убьет только определенный поток, а не всю программу.

Вы можете найти программу, которую я написал ниже:

#include <pthread.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/poll.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#define ERR -1

int                pipefd[2] = {0, 0};

void signal_handler(int signum)
{
    printf("signal handler");
    if (ERR == write(pipefd[1], &signum, sizeof(signum)))
        printf("errno: %d", errno);
}

void initializePipeAndAddSignalHandler()
{
    if (ERR == pipe(pipefd))
    {
        printf("pipe2 returned an error: %s", strerror(errno));
        exit(EXIT_FAILURE);
    }
    else
    {
        if (SIG_ERR == signal(SIGUSR1, signal_handler))
        {
            printf("Enabling signal Handling to SIGUSR1 failed: %s", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }
}

void *threadfunc(void *arg)
{
    int sig = -1;
    const int NO_FDS = 1;
    struct pollfd fds[NO_FDS];
    nfds_t nfds = NO_FDS;

    const int PIPE_FD = 0;

    fds[PIPE_FD].events = POLLIN | POLLHUP;
    fds[PIPE_FD].fd = pipefd[0];

    printf("in threadfunc");
    while(1)
    {
        int ret = poll(fds, nfds, -1);
        printf("Poll called");
        if (ret != ERR)
        {
            if (POLLIN == (fds[PIPE_FD].revents & POLLIN))  
            {
                if (-1 != read(fds[PIPE_FD].fd, &sig, sizeof(sig)))
                {
                    switch (sig)
                    {
                        case SIGUSR1:
                        {
                            printf("received sigusr1");
                            return NULL;
                        }
                        default:
                        {
                            printf("UnKnown Signal received = %d", sig);
                            break;
                        }
                    }
                }
            }
        }
    }
}

int main()
{


    int sig_return;
    sigset_t set;

    initializePipeAndAddSignalHandler();

    pthread_t tid;
    if(pthread_create(&tid, NULL, &threadfunc, NULL)) 
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
   }


    sigemptyset(&set);
    sigaddset(&set, SIGUSR1);
    sig_return = pthread_sigmask(SIG_BLOCK, &set, NULL);
    if (sig_return != 0)
        printf("Setting sigmask failed");

    while (1)
    {
        printf("\nmain thread running\n");
        sleep (1);
    }

    printf("killed");
}
...