Chinaunix首页 | 论坛 | 博客
  • 博客访问: 894732
  • 博文数量: 119
  • 博客积分: 2493
  • 博客等级: 大尉
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-03 14:00
文章分类

全部博文(119)

文章存档

2013年(19)

2012年(100)

分类: LINUX

2012-07-20 11:15:18

      
       本文将通过内核模块打印出指定进程的虚存区,而且使用两种方
式,因为进程的虚拟区有多种组织方式。一种是单链表,一种是红黑树。
红黑树是基于树的查找,效率很高,主要用来快速定位进程的某个虚存区。
红黑树也属于二叉树的范畴,故这儿就使用二叉树的先序的递归形式遍历。
--------------------------------------------------------------------------------
一,使用单链表形式。
    
  1,首先根据进程的pid(模块传参)定位到进程的PCB。
       通过如下两个函数实现。

     
  1.  k = find_vpid(pid);
  2.  p = pid_task(k,PIDTYPE_PID);
2,根据进程task_struct可以找到单链表的头,故接下来就是遍历一个单链表了。

  1. static void printvm_list(void)
  2. {
  3.     struct task_struct *p;
  4.     struct pid *k;
  5.     struct vm_area_struct *tmp;
  6.     
  7.     k = find_vpid(pid);
  8.     p = pid_task(k,PIDTYPE_PID);
  9.     tmp = p->mm->mmap;
  10.     
  11.     printk("process:%s,pid:%d\n",p->comm,p->pid);

  12.     while (tmp != NULL) {
  13.         printk("0x%lx - 0x%lx\t",tmp->vm_start,tmp->vm_end);
  14.         if (tmp->vm_flags & VM_READ)
  15.             printk("r");
  16.         else
  17.             printk("-");

  18.         if (tmp->vm_flags & VM_WRITE)
  19.             printk("w");
  20.         else
  21.             printk("-");
  22.     
  23.         if (tmp->vm_flags & VM_EXEC)
  24.             printk("x");
  25.         else
  26.             printk("-");
  27.         
  28.         if (tmp->vm_flags & VM_SHARED)
  29.             printk("s\n");
  30.         else
  31.             printk("p\n");

  32.         tmp = tmp->vm_next;    
  33.     }
  34. }
-------------------------------------------------------------------------------------
二,遍历二叉树的形式。
1,同样是通过进程的pid找到进程的task_struct。

2,通过task_struct找到树的根,然后就是先树遍历二叉树了。


  1. static void visit(struct rb_node *root)
  2. {
  3.     struct vm_area_struct *tmp;
  4.     tmp = container_of(root,struct vm_area_struct,vm_rb);
  5.     printk("0x%lx - 0x%lx\t",tmp->vm_start,tmp->vm_end);
  6.     if (tmp->vm_flags & VM_READ)
  7.         printk("r");
  8.     else
  9.         printk("-");

  10.     if (tmp->vm_flags & VM_WRITE)
  11.         printk("w");
  12.     else
  13.         printk("-");
  14.     
  15.     if (tmp->vm_flags & VM_EXEC)
  16.         printk("x");
  17.     else
  18.         printk("-");
  19.         
  20.     if (tmp->vm_flags & VM_SHARED)
  21.         printk("s\n");
  22.     else
  23.         printk("p\n");
  24. }

  25. static void print_rb_tree(struct rb_node *root)
  26. {
  27.     if (root != NULL) {
  28.         visit(root);
  29.         print_rb_tree(root->rb_left);
  30.         print_rb_tree(root->rb_right);
  31.     }
  32. }

  33. static void printvm_tree(void)
  34. {
  35.           struct task_struct *p;
  36.     struct pid *k;
  37.     struct rb_node *root = NULL;

  38.     k = find_vpid(pid);
  39.     p = pid_task(k,PIDTYPE_PID);
  40.     root = p->mm->mm_rb.rb_node;
  41.     print_rb_tree(root);
  42.     return ;
  43. }
---------------------------------------------------------------------------

模块完整代码:
 print_vm.rar  
---------------------------------------------------------------------------

阅读(2081) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~