Linux - системный вызов для перебора дочерних потоков

Я создаю системный вызов для возврата некоторой информации о процессе и его дочерних потоках. Я тестирую это в Ubuntu 14.04. Вот код, который я написал:

#include <linux/list.h>
#include <linux/linkage.h>
#include <linux/sched.h>
#include <linux/uaccess.h>

#define NUM_THREADS 5

struct thread_info_prj {
    int pid;
    int nthreads;
    int tid[NUM_THREADS];
};

asmlinkage void sys_threadinfo_prj(void *ptr)
{
    struct task_struct *task;
    struct thread_info_prj t_info;
    struct list_head *list;
    int num_threads = 0;

    t_info.pid = current->pid;

    list_for_each(list, &current->children) {
        //task = list_entry(&p_task->children, struct task_struct, sibling);
        task = list_entry(list, struct task_struct, sibling);
        t_info.tid[num_threads] = task->pid;
        num_threads++;
    }

    t_info.nthreads = num_threads;

    copy_to_user(ptr, &t_info, sizeof(struct thread_info_prj));
}

Этот код встроен в ядро ​​как системный вызов и протестирован с помощью следующей программы.

#include <pthread.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <errno.h>

#define NUM_THREADS 5

struct thread_info_prj {
    int pid;
    int nthreads;
    int tid[NUM_THREADS];
};

void * thread_fn(void *ptr) {
    printf("Im a thread!\n");
    sleep(4);
    pthread_exit(NULL);
}

int main() {
    pthread_t threads[NUM_THREADS];
    pthread_attr_t attr;
    int i;
    struct thread_info_prj t_info;
    void *status;

    pthread_attr_init(&attr);
    //pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    for (i = 0; i < NUM_THREADS; i++)
        pthread_create(&(threads[i]), &attr, thread_fn, NULL);

    sleep(1);

    syscall(352, &t_info);

    //for (i = 0; i < NUM_THREADS; i++)
    //  pthread_join(threads[i], &status);
    printf("PID: %d\n", t_info.pid);
    printf("Num Threads: %d\n", t_info.nthreads);

    for (i = 0; i < t_info.nthreads; i++) {
        printf("Thread ID: %d\n", t_info.tid[i]);
    }

    printf("%s\n",strerror(errno));

    return 0;
}

К сожалению, единственный выход - правильный родительский pid. В противном случае он возвращает отсутствие потоков и не печатает никаких дополнительных идентификаторов PID. Добавив printk внутри цикла for, я обнаружил, что он даже не входит в цикл for. Какие-либо предложения?

Спасибо.

0 ответов

Другие вопросы по тегам