Linux kernel learning 4 -- print process descriptor task_ Fields in struct

Posted by shaunie123 on Sat, 20 Nov 2021 17:02:59 +0100

Let's practice printing process descriptor task_ Fields in struct

The method used here is to insert the kernel module, and the method used is to traverse the process linked list

1, Task_ A preliminary interpretation of struct

First, download your own source code. You can refer to my previous blog https://blog.csdn.net/weixin_45730790/article/details/121294180?spm=1001.2014.3001.5501

have access to bootlin View source code online

Open the header file in the directory of the include file. task_ The struct structure is located in the sched. H header file/ include/linux/sched.h

schde.h shows the full picture of pcb in the kernel. There are many fields involved. Here we only focus on the pcb itself, and some fields that can reflect its structure.

First, look at the first field state, that is, its status information,

Next is its kernel stack * stack

flags is the flag of the process

The ptrace field is used to implement breakpoint debugging

Further down, we can see some priority information

prio is dynamic priority, static_prio is static priority, rt_priority is the real-time priority

Next, you can see the policy field, which is its process scheduling policy

Next, you can see the running information sched of the scheduler statistical process_ Info, which is also a structure

Next is the tasks field, which is a two-way linked list. It is this field that connects all processes together so that we can traverse the process.

Next is all the information of its linear address

active_mm is the last accessed address space pointer

Here is the kinship of the process

Print important information of pcb, such as status information, priority information, kinship, file system information and memory information.

These two information are used to reflect the number of context switches. nvcsw reflects the number of active context switches and nivcsw reflects the number of passive context switches

These two fields are used to record missing page statistics

This array is the name of the corresponding program

These two fields are responsible for the communication between the corresponding processes

Here is very important, its file information. fs stores a pointer to the file system information, and files stores a pointer to the process file descriptor table

Next is its namespace

Further down, we can see that this is its signal descriptor

Further down, we can see that IRQ is its interrupt information

Memory recycling

Record the IO count of the process

There are many fields in the back. You can view the blog in more detail https://blog.csdn.net/gatieme/article/details/51383272

2, Write kernel module print task_struct important fields

Here we print important attribute information of pcb, such as status information, process identifier, priority information, kinship, file system information and memory information.

task_struct.c:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#Include < Linux / sched. H > / / task structure
#include <linux/fdtable.h>      //files
#include <linux/fs_struct.h>   //fs
#include <linux/mm_ Types. H > / / print memory information
#include <linux/init_task.h>   
#include <linux/types.h>
#include <linux/atomic.h>
 
MODULE_LICENSE("GPL");  //licence
 
//Entry function
static int __init print_pcb(void)    //The init macro is supported by the init.h file
{
        struct task_struct *task,*p;
        struct list_head *pos;   //Bidirectional linked list
        int count=0;          //Count the total number of current system processes
 
        printk("begin...\n");
 
        //When traversing the linked list, you want to start with the first one
        task=&init_task;  //Point to process pcb 0
 
        list_for_each(pos,&task->tasks) //The traversal operation uses pos to point, and the passed in parameter task points to the tasks field. The tasks of process 0 are traversed. Tasks connect all processes together.
        {
                p=list_entry(pos,struct task_struct,tasks);    //If you find a node, you can use the tasks field of the node to find the exit address of the structure. The corresponding field tasks
                //At this point, the p pointer already points to task_ The head of the struct structure, which can be operated by the p pointer
                count++;  //Find a process and add it yourself
                printk("\n\n");
                printk("pid: %d; state: %d; prior: %d; static_pri: %d; parent_pid: %d; count: %d; umask: %d",p->pid,p->__state,p->prio,p->static_prio,(p->parent)->pid,atomic_read(&(p->files)->count),(p->fs)->umask);
        //In linux, the mm of the kernel thread is empty. If you want to print it, there will be an error and pointer error
        if((p->mm)!=NULL)
                printk("Total_vm: %ld",(p->mm)->total_vm);      //Total pages in linear area
 
        }
 
        printk("Number of processes:%d\n",count);
 
        return 0;
}
 
static void __exit exit_pcb(void)    //Exit function
{
        printk("Exiting...\n");
}
 
// Specify the entry point and exit point. The entry / exit point is supported by module.h
 
module_init(print_pcb);
module_exit(exit_pcb);

Makefile files are as follows:

#Makefile file note: if the previous. c file is named first.c, then the. o file in the makefile file here
#The module should be named first.o. only the root user can load and unload the module
obj-m:=task_struct.o                          #Generate task_ Object file of struct module
#The object file should be the same as the module name
CURRENT_PATH:=$(shell pwd)             #Current path of the module
LINUX_KERNEL:=$(shell uname -r)        #Current version of linux kernel code
LINUX_KERNEL_PATH:=/home/shupeiyao/linux-5.14.17

all:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules    #Compilation module
#[Tab] the path of the kernel where the current directory is compiled indicates that the kernel module is compiled

clean:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean      #Cleaning module

make compilation

sudo insmod task_struct.ko loading kernel modules

dmesg viewing kernel print information

Some do not print total_vm, indicating that its mm field is empty, which is a kernel thread

There are 361 threads in total

The above is to print tasks in the Linux kernel_ The contents of important fields in struct structure
If it helps you, please like it, pay attention to it or collect it~

Topics: Linux Operation & Maintenance server