The ending flag to traversing ancestors in the ker

2019-09-10 14:20发布

问题:

I am trying to traverse all the ancestors of a process to store their info in a static array passed by the user, and I am using the NULL pointer end flag to end traversing. However, this does not seem to work, and will continue looping until the size number (the capacity of the array) passed by the user space matches num_filed number (the number of elements in the array) in all cases, even if I have very little number of processes running. So, what seem to be the ending flag for traversing ancestors? Here is my traversing loop code:

current_process = current;
int i = 0;
while (current_process != NULL && current_num_filled < size) {
    temp_info_array[i] = get_process_info(current_process);
    ++current_num_filled;
    ++i;
    current_process = current_process->parent;
}

回答1:

You can see the INIT_TASK() macro used to initialize the struct task_struct for the init process in /include/linux/init_task.h. In particular:

    #define INIT_TASK(tsk)  \
    {                                              \
            .state          = 0,                   \
            .stack          = &init_thread_info,   \
                                                   \
            /* ... */                              \
                                                   \
            .real_parent    = &tsk,                \
            .parent         = &tsk,                \
                                                   \
            /* ... */                              \
    }

So as you can see - the parent member of init's struct task_struct is set point to itself, not the null pointer.



回答2:

It depends on the way your OS encodes the concept of "root process". "NULL" is not the only way to do it. Another common solution in similar cases is to set "parent" field to "current_process" itself. I guess your OS behaves this way. This explains why your loop doesn't end until the buffer space is exhausted.



回答3:

You can walk the list as follows...

 struct task_struct *task = current;
 do {
    task = task->parent;
    printk(KERN_INFO "process=%s, pid=%d", task->comm, task->pid);
  } while (task->pid != 0);

Don't do this in interrupt context.