linux ptrace 内核源码分析,linux 3.5.4 ptrace源码分析分析(系列一)
ptrace是linux系统中为了调试专门设立的一种系统调用。要想调试调试一个进程,有两种方式:
PTRACE_TRACEME和PTRACE_ATTACH。这两种方式的主要区别可以概括为:
PTRACE_TRACEME是子进程主动申请被TRACE。而PTRACE_ATTACH是父进程自己要attach到子进程,相当于子进程是被动的trace。
PTRACE_TRACEME程序设置的框架大概为:
if(pid==0)//child
{
ptrace(PTACE_TRACEME,0,NULL,NULL);
exec(...);
}
else//parent
{
wait(&status);
if(WIFSTOPPED(status))
fprintf(stderr,"%s\n",WSTOPSIG(status);//打印出子进程当前的状态。
}看似简单的代码,其实内核做了大量的工作,我们在此进行详细分析。
当程序执行ptrace系统调用,传入PTRACE_TRACEME函数时,内核执行下面的代码段:
static int ptrace_traceme(void)
{
int ret = -EPERM;
write_lock_irq(&tasklist_lock);
/* Are we already being traced? */
if (!current->ptrace) {
ret = security_ptrace_traceme(current->parent);
/*
* Check PF_EXITING to ensure ->real_parent has not passed
* exit_ptrace(). Otherwise we don't report the error but
* pretend ->real_parent untraces us right after return.
*/
if (!ret && !(current->real_parent->flags & PF_EXITING)) {
current->ptrace = PT_PTRACED;
__ptrace_link(current, current->real_parent);
}
}
write_unlock_irq(&tasklist_lock);
return ret;
}从上面的源码我们可以看出:PTRACE_TRACEME并没有使子进程停止,而是将进行一系列判断之后(父进程是否能对子进程进行跟踪的合法性检查),将子进程链接到父进程的ptrace链表中。
真正导致子进程停止的是exec系统调用,该系统调用成功之后,内核会判断该进程是否被ptrace跟踪,如果被跟踪的话,内核将向该进程发送SIGTRAP信号。该信号将导致当前进程停止。具体的代码如下:
static inline void ptrace_event(int event, unsigned long message)
{
if (unlikely(ptrace_event_enabled(current, event))) {
current->ptrace_message = message;
ptrace_notify((event << 8) | SIGTRAP);
} else if (event == PTRACE_EVENT_EXEC) {
/* legacy EXEC report via SIGTRAP */
if ((current->ptrace & (PT_PTRACED|PT_SEIZED)) == PT_PTRACED)
send_sig(SIGTRAP, current, 0);
}
}我们都知道:SIGTRAP信号是专门为debug设计的,当内核踩中断点的时候(断点就是int 3,相应的回调函数就是do_trap),就会发送这个信号:
asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
{
siginfo_t info;
memset(&info, 0, sizeof(info));
info.si_signo = SIGTRAP;
info.si_code = TRAP_TRACE;
info.si_addr = (void *)address;
force_sig_info(SIGTRAP, &info, current);
regs->pc += 4;
}
从这里我们可以看出,进程被trace之后,对于子进程的许多操作(尤其是父进程感兴趣的操作)都改变了,目的是为了让父进程感知到这些事件,exec就是一个例子。
此时,父进程的wait操作将被唤醒。我们知道wait操作就是父进程用来检测子进程的退出情况,wait操作返回有三种情况:
1、子进程正常退出
int status;
wait(&status);//status保存了子进程当前的状态
WIFEXITED(status)://如果子进程确实正常退出,则为真
WEXITSTATUS(status)://打印出进程的退出码
2、子进程因为收到信号而退出
int status;
wait(&status);
WIFSIGNALED(status)://如果子进程确实正常退出,则为真
WTERMSIG(status)://打印出进程的退出码
3、子进程因为收到信号而暂停
int status;
wait(&status);
WIFSTOPPED(status)://如果子进程确实正常退出,则为真
WSTOPSIG(status)://打印出进程的退出码 显然,PTRACE_TRACEME对应的就是第三种情况。如果想要输出信号对应的描述性字符串,可以这样操作:
sprintf(stderr,"%s\n",WSTOPSIG(status));
linux ptrace 内核源码分析,linux 3.5.4 ptrace源码分析分析(系列一)相关推荐
- linux纯内核直接用吗,Linux:为啥内核有的变量没有初始化就敢直接使用?
一.问题 为啥内核有的变量没有初始化就敢直接使用? 二.分析 看上图,其中的5747行的变量nid的确没有定义,就直接使用了,这么做没有问题吗? 其实大家仔细看一下,5765行是一个宏, 到内核源码去 ...
- linux降内核版本_查看linux版本内核 Linux内核版本的变化
1.major:表示主版本号,有结构性变化时才变更. 2.minor:表示次版本号,新增功能时才发生变化;一般奇数表示测试版,偶数表示生产版. 3.patch:表示对次版本的修订次数或补丁包数. 4. ...
- mint linux更新内核,如何在Ubuntu/Linux Mint中安装最新Linux 5.2.5内核
原标题:如何在Ubuntu/Linux Mint中安装最新Linux 5.2.5内核 Linux 5.2的Ubuntu主线内核包最终可以在32位和64位操作系统中下载和安装. 由于构建失败,Linux ...
- linux cifsutils 内核,Veeam Agent for Linux 4.0 安装部署
官方说明: 硬件要求: CPU:x86-64处理器(i386或更高版本). 内存:1 GB RAM或更大.内存消耗量因备份类型和备份的数据. 磁盘空间:用于产品安装的100 MB可用磁盘空间. 网络: ...
- linux编译内核实验,实验六 Linux内核编译实验.doc
实验六 Linux内核编译 讲师:杨行 [实验目的] 1.掌握Linux内核编译 2.了解Linux内核Makefile 3.了解Linux内核Kbuild系统 [实验原理] 网站可以下载标准内核文件 ...
- linux驱动内核哪个文件夹,linux设备驱动归纳总结(一):内核的相关基础概念...
linux设备驱动归纳总结(一):内核的相关基础概念 1. 内核与 linux 设备驱动的作用与关系 内核:用于管理软硬件资源,并提供运行环境.如分配 4G 虚拟空间等. linux 设备驱动:是连接 ...
- linux裁剪内核和移植,嵌入式Linux内核裁剪及移植的研究与实现
摘要: 嵌入式操作系统是嵌入式系统的软件核心,它管理系统中所有的软件和硬件资源,并且满足嵌入式系统的专用性和可裁剪性.嵌入式Linux以其开源,可裁剪以及模块化设计等特点,吸引了国内外众多研发人员的青 ...
- linux中内核4c,一台Linux服务器(4C8G配置)可以负载百万个连接?
首先我们来看如何标识一个TCP连接?系统是通过一个四元组来识别,(src_ip,src_port,dst_ip,dst_port)即源IP.源端口.目标IP.目标端口.比如我们有一台服务192.168 ...
- linux 调整 内核空间占用cpu,[Linux性能优化]3.CPU使用率100%,怎么办?
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? CPU使用率是单位时间内CPU使用情况的统计,以百分比的方式展示. CPU时间是Linux通过事先定义的节拍率(内核中表 ...
- linux 替换内核 img,查看更改linux内核initrd.img-Go语言中文社区
2.6以前的版本采用的是ext2格式的initrd,2.6及以后是cpio包形式,具体来看下吧 2.6及以后版本内核 解包 查看ubuntu的grub.cfg文件 红框是root文件系统,挂载在根目录 ...
最新文章
- 【ios开发/Xcode】使用UITableView完成学生信息及成绩的显示
- 4一20ma电流有源与无源区别_4-20 mA电流环的工作原理是怎么样的
- C/Cpp / Cpp 中 struct 和 class 区别
- 带参数的URLconf
- 《当程序员的那些狗日日子》(三十六)无名的配角
- LeetCode 349. 两个数组的交集(哈希)
- 详细讲解Spring中的@Bean注解
- 【信息系统项目管理师】第4章-项目整体管理 知识点详细整理
- WinForm模拟单击按钮两种方法
- python速学_【Python杂货铺】速学python基础
- cdh安装hadoop组件后一些常用设置
- GIS开发实习地图符号图式制作
- Adobe系列软件-快捷键(PS-Photoshop、PR-Premiere Pro、AE-After Effects)
- 堆排序算法知识点总结
- 龙芯 Linux usb,使用debirf制作龙芯2F的LiveUSB
- cdoj1633 去年春恨却来时,落花人独立,微雨燕双飞
- T470 Win10下触摸板手势
- 45本程序员圣经级别书籍,包邮送到家
- 吴松计算机学院,IT|“创青春”创业大赛计算机学院选拔赛成功举行!
- Unity热更新机制
热门文章
- 完全编译安装boost
- mysql datetime 间隔,MySQL datetime默认时间间隔
- mysql group by 重复_mysql – 使用GROUP BY删除重复项的查询
- 网站添加页面热力图--百度统计
- java对两个表进行排序_Excel工作簿中多个worksheet工作表,如何对工作表进行排序?...
- java map与set的区别_java 集合(list,set,map)三者之间的关系和区别
- 盘点和程序员相关的那些事,让你不再被割韭菜,薅羊毛!
- 高内聚,低耦合——8大核心中间件,微服务基础技术栈技术图谱
- 在HTML中嵌入PHP代码,有以下几种方法,其中错误的是( )
- linux cpu负载巡检,linux服务器巡检报告.doc