0

Kill a specific thread in one process from another process.

Below is my code:

ptrace(PTRACE_ATTACH,threadID,NULL,NULL);

stops the complete process, but I want only one specific thread to stop.

Can you please provide me some pointers on how to proceed?

cpp_enthusiast
  • 1,239
  • 10
  • 28
paramikoooo
  • 177
  • 2
  • 16

1 Answers1

2

You can follow the below procedure:

1) Create a pipe and initialize it.

2) Create a signal handler for the specific signal and signal handler should perform minimal operation. In this case, I will write the "signum" into the write end of the pipe.

3) Create a thread will should get blocked on the poll and also it needs to read the data from the read end of the pipe.

4) Then I will ignore the signal that I used above in the other threads.

5) Then continue with the main thread, here I have an infinite loop.

6) Now you can run the program and use the process id to send the signal from the console. For example, let's assume the process id is 24566, then I will send the signal as follows:

kill -n 16 24566

This will kill only the specific thread and not the complete program.

You can find the program that I wrote below:

#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");
}
cpp_enthusiast
  • 1,239
  • 10
  • 28
  • This is a much better solution than trying to hack your way into another process using `ptrace(2)`. – Aaron Digulla Apr 02 '19 at 14:46
  • @Almx1 , I don't get you , 1- You offer to kill thread that must to be read /write from pip , or can I kill/stop any thread that I choose without any conditions? 2) kill -n 16 24566 send signal to process, where do I map to the thread that I want ? – paramikoooo Apr 03 '19 at 06:33
  • @paramikoooo I don't think it is possible to choose the thread to kill unconditionally. You can't map a thread to kill externally, atleast I am not aware of any interface that supports this feature. – cpp_enthusiast Apr 03 '19 at 08:45