【安卓源码】简单分析smaps节点
smap节点,位于/proc/{pid}/smaps。
通过这个节点可以看到一个进程映射的内存信息,不会包括设备使用的内存,比如gpumem。
smaps节点内核定义
kernel/msm-4.19/fs/proc/base.c#ifdef CONFIG_PROC_PAGE_MONITORREG("clear_refs", S_IWUSR, proc_clear_refs_operations),REG("smaps", S_IRUGO, proc_pid_smaps_operations),REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),REG("pagemap", S_IRUSR, proc_pagemap_operations),
#endif
kernel/msm-4.19/fs/proc/task_mmu.cconst struct file_operations proc_pid_smaps_operations = {.open = pid_smaps_open,.read = seq_read,.llseek = seq_lseek,.release = proc_map_release,
};
open系统调用分析
对smaps节点的open系统调用,我觉得应该类似binder_open,打开这个节点做一些初始化工作
调用堆栈如下:
kernel/msm-4.19/fs/proc/task_mmu.c pid_smaps_open()--->kernel/msm-4.19/fs/proc/task_mmu.c do_maps_open()--->kernel/msm-4.19/fs/proc/task_mmu.c proc_maps_open()
重点看一下阿proc_maps_open函数调用了__seq_open_private方法,这一番操作实际上是把smaps文件与proc_pid_smaps_op关联上。
实际上就是在seq_file结构体的seq_operations指针上放了proc_pid_smaps_op,之后对smaps进行cat操作就会执行到show_smap()方法。
具体的细节可以按照
kernel/msm-4.19/fs/proc/task_mmu.c static int proc_maps_open(struct inode *inode, struct file *file,const struct seq_operations *ops, int psize)
{//在这里初始化,关联了seq_file的proc_pid_smaps_opstruct proc_maps_private *priv = __seq_open_private(file, ops, psize);
priv->inode = inode;priv->mm = proc_mem_open(inode, PTRACE_MODE_READ);if (IS_ERR(priv->mm)) {int err = PTR_ERR(priv->mm);
seq_release_private(inode, file);return err;}
return 0;
}
kernel/msm-4.19/include/linux/seq_file.hstruct seq_file {char *buf;size_t size;size_t from;size_t count;size_t pad_until;loff_t index;loff_t read_pos;u64 version;struct mutex lock;const struct seq_operations *op;int poll_event;const struct file *file;void *private;
};
show方法分析
在执行cat /proc/{pid}/smaps之后,会执行下面的调用栈。
在调用栈(2)的smap_gather_stats()函数中,会初始化一个mm_walk结构体,并设置smaps_pte_range()函数作为回调,
所以在smap_gather_stats()函数最后执行walk_page_vma()后,遍历页表时会回调smaps_pte_range()函数。
然后在smaps_account方法中把VMA的所有子项与结构体mem_size_stats关联起来。
最后在show_smap方法里就可以通过打印mem_size_stats中的数据,将一个进程的一块VMA信息打印出来了。
分析到这里,可以知道smaps节点的信息都是从mm_struct中的vma中获得的。
调用栈:
1. kernel/msm-4.19/fs/proc/task_mmu.c show_smap()
2. --->kernel/msm-4.19/fs/proc/task_mmu.c smap_gather_stats()
3. --->kernel/msm-4.19/mm/pagewalk.c walk_page_vma()
4. --->kernel/msm-4.19/mm/pagewalk.c __walk_page_range()
5. --->kernel/msm-4.19/mm/pagewalk.c walk_pgd_range()
6. --->kernel/msm-4.19/mm/pagewalk.c walk_p4d_range()
7. --->kernel/msm-4.19/mm/pagewalk.c walk_pud_range()
8. --->kernel/msm-4.19/mm/pagewalk.c walk_pmd_range()
9. --->kernel/msm-4.19/fs/proc/task_mmu.c smaps_pte_range()
10. --->kernel/msm-4.19/fs/proc/task_mmu.c smaps_pte_entry()
11. --->kernel/msm-4.19/fs/proc/task_mmu.c smaps_account()
每执行一次,会打印smaps节点的一块VMA信息,如下:
kernel/msm-4.19/fs/proc/task_mmu.cstatic const struct seq_operations proc_pid_smaps_op = {.start = m_start,.next = m_next,.stop = m_stop,.show = show_smap
};
static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,struct mm_walk *walk)
{struct vm_area_struct *vma = walk->vma;pte_t *pte;spinlock_t *ptl;
ptl = pmd_trans_huge_lock(pmd, vma);.../** The mmap_sem held all the way back in m_start() is what* keeps khugepaged out of here and from collapsing things* in here.*/pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);for (; addr != end; pte++, addr += PAGE_SIZE)//在这里遍历此vma的每一个页表项smaps_pte_entry(pte, addr, walk);pte_unmap_unlock(pte - 1, ptl);
return 0;
}
\
【安卓源码】简单分析smaps节点相关推荐
- poco源码简单分析
自动化工具poco源码简单分析 Airtest简介 Airtest是网易游戏开源的一款UI自动化测试项目,目前处于公开测试阶段,该项目分为AirtestIDE.Airtest.Poco.Testlab ...
- Hessian 源码简单分析
Hessian 源码简单分析 Hessian 是一个rpc框架, 我们需要先写一个服务端, 然后在客户端远程的调用它即可. 服务端: 服务端通常和spring 做集成. 首先写一个接口: public ...
- FFmpeg的HEVC解码器源码简单分析:概述
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- FFmpeg的HEVC解码器源码简单分析:解码器主干部分
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- JSP 编译和运行过程与JSP源码简单分析
JSP 编译和运行过程与JSP转移源码简单分析 Web容器处理JSP文件请求的执行过程主要包括以下4个部分: 1. 客户端发出Request请求 2. JSP Container 将JSP转译成Ser ...
- 线程的3种实现方式并深入源码简单分析实现原理
前言 本文介绍下线程的3种实现方式并深入源码简单的阐述下原理 三种实现方式 Thread Runnable Callable&Future 深入源码简单刨析 Thread Thread类实现了 ...
- reentrantlock失效了?_ReentrantLock 源码简单分析
JAVA中锁的实现最常见的方式有两种,一种是 synchronized关键字,一种是Lock.实际的开发过程中,要对这两种方式进行取舍. synchronized是基于JVM层面实现的, Lock却是 ...
- Linux·内核源码简单分析
目录 系统总体流程: 各个目录的阅读总结: (一) boot (二)内核初始化init (三)kernel: (四)mm内存管理 (五)文件系统模块fs: 系统总体流程: 系统从boot开始动作,把内 ...
- ChaLearn Gesture Challenge_3:Approximated gradients源码简单分析
前言 上一篇博文ChaLearn Gesture Challenge_2:examples体验 中简单介绍了CGC官网提供的丰富的sample,本节来简单分下其中的一个sample源码,该sample ...
- Enemy源码简单分析
这是这个项目的网页链接,以下是关于enemy源代码的粗略分析. https://github.com/freakanonymous/enemy 弗兰克,是一个全职的恶意代码工程师,会不定期更新enem ...
最新文章
- C#使用ping命令
- 第九十二期:多少程序员注意到了「中台」的背面?
- 在上级对自己做绩效评估之前
- 关于常用的git命令列表
- 区块链教程Fabric1.0源代码分析flogging(Fabric日志系统)
- Python 语言简介与入门(1)
- 基于NXP iMX8测试Secure Boot功能部署
- c语言国二题库选择填空题,国二c语言笔试题库(含答案),选择填空.doc
- java版b2b2c社交电商spring cloud分布式微服务 (三) 服务消费者(Feign)
- Python API+Postman+jmeter
- CF 1696 E. Placing Jinas 组合数 2000
- 梆梆加固的病毒分析-破解篇
- 成为黑客需要学习什么技能?
- Mac下Smb的使用
- 新版标准日本语初级_第三十课
- Android:国家气象局提供的天气预报接口(完整Json接口)
- 【 CF1186D,E,F】Vus the Cossack and Numbers/Vus the Cossack and a Field/Vus the Cossack and a Graph
- 华科提出首个用于伪装实例分割的一阶段框架OSFormer
- Ansible Role详解
- 重庆北大青鸟python培训
热门文章
- 微信小程序分享小程序码的生成,多参数以及参数的获取
- 计算机显示器分辨率,电脑显示器分辨率调多少合适
- 目标检测标签分配之 OTA 和 SimOTA 细节学习
- 【百战GAN】StyleGAN原理详解与人脸图像生成代码实战
- BIMC电子商务外包服务独特之处
- Fedora 9在用VMware 5.5、6.5虚拟机安装和硬盘安装中遇见的几点问题
- 基于ASP.NET开发的固定资产管理系统源码 企业固定资产管理系统源码
- flutter上分之路1-新手教学(配置安装)
- 查看oracle的SID
- java开发购物系统菜单_Java控制台购物系统