LINUX 3.5.4 PTRACE(系列三)
来源:互联网 发布:nginx 算是中间件吗 编辑:程序博客网 时间:2024/05/30 02:52
本系列文章将对ptrace系统调用的强大功能进行详细分析和验证,通过本系列文章,可以深入理解ptrace的实现原理和使用方法,之后编写自己的编译器就不在话下了。
我们首先以一个简单的例子作为入门。‘CTRL+C’这个快捷键我们再熟悉不过了。在正常情况下,我们向一个正常的进行发送‘CTRL+C’ 即SIGINT信号,程序就会停止运行。但是,如果我们在程序中加入ptrace系统调用之后,‘CTRL+C’这个信号就不能让进程终止(terminated),而是让进程暂停(stopped)。
程序一:
child1:
#include "ptrace.h"void main(){ ptrace(PTRACE_TRACEME,NULL,0,0); while (1);}
本系列所有的头文件我们都在“ptrace.h”中定义
#include <sys/ptrace.h>#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <sys/user.h> /* For struct user_regs_sturct */#include <sys/syscall.h> /* For SYS_write etc */#include <sys/reg.h> /* For constants ORI_EAX etc */编译程序并运行
#gcc list1.c -o list1.o
#./list1.o
从上面的程序中我们可以看到,这个程序其实啥也没做,就是一个死循环,此时我们输入'CTRL+C'。然后查看进程的状态
#ps -ax
在linux中,进程的常用状态包括:
D 无法中断的休眠状态(通常 IO 的进程);
R 正在运行,在可中断队列中;
S 处于休眠状态,静止状态;
T 停止或被追踪,暂停执行;
W 进入内存交换(从内核2.6开始无效);
X 死掉的进程;
Z 僵尸进程不存在但暂时无法消除
如果程序中没有ptrace系统调用,则进程的状态为彻底结束,从而使用ps命令也看不出来。
我们都知道SIGINT信号的含义:程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。
那么为什么同样是‘SIGINT’,进程的处理方式却不同了呢?
为了清除的了解究竟发生了什么,我们可以对进程停止的状态进行扑捉
list1.c
#include "ptrace.h"void main(){ pid_t child; int status; child=fork(); if(child==0){//child // ptrace(PTRACE_TRACEME,0,NULL,NULL); usleep(50); //while(1) printf("hello!\n"); } else{ //int status; //printf("parent!,%d\n\n\n\n",child); usleep(10); kill(child,SIGINT);//send SIGINT to child wait(&status); if(WIFSTOPPED(status)){ printf("%d",WSTOPSIG(status)); fprintf(stderr,"%s",strsignal(WSTOPSIG(status))); printf("\nstopped!\n"); } else if(WIFEXITED(status)){ printf("%d",WEXITSTATUS(status)); fprintf(stderr,"%s",strsignal(WEXITSTATUS(status))); printf("\eixted!\n"); } else if(WIFSIGNALED(status)){ printf("%d",status); fprintf(stderr,"%s",strsignal(WTERMSIG(status))); printf("\nterminated!\n"); } else printf("error!\n"); ptrace(PTRACE_CONT,child,0,0); }}编译并运行结果如下所示:
而interrupt后面紧跟的数字“2”正好对应的是SIGINT信号。而WIFSIPPED我们以前也解释过了,只有当进程被ptrace调用监控的时候被信号停止/暂停才会为真。
通过上面的分析我们可以看到:由于子进程使用了ptrace调用使得子进程对SIGINT信号的处理不同了。
为了充分验证这一点,我们接下来再分析一下没有ptrace调用的效果。此时,只要child1中的ptrace系统调用注释掉就行了,在运行list1,看看结果:
从这里我们可以看到子进程同样是收到了SIGINT信号,然而子进程的处理方式却不同。显然此时是WIFSIGNALED(status)判断条件为真。说明子进程是因为收到SIGINT信号而退出了。
未完待续!
- LINUX 3.5.4 PTRACE(系列三)
- LINUX 3.5.4 PTRACE(系列五)
- linux 3.5.4 ptrace源码分析分析(系列一)
- linux 3.5.4 PTRACE(系列六)
- LINUX 3.5.4 PTRACE (系列七)
- linux 3.5.4 PTRACE(系列八)
- linux 3.5.4 PTRACE(系列九)
- [Ptrace]Linux内存替换(三)运行控制
- linux 分析 ptrace()
- linux 分析 ptrace()
- linux 分析 ptrace()
- linux 分析 ptrace()
- linux 分析 ptrace()
- linux ptrace
- linux ptrace
- linux ioctl与ptrace(转载+整理)
- ptrace应用系列-基础知识
- ptrace应用系列-基础知识
- android 滑动菜单SlidingMenu实现
- Android获取手机地址(Mac、ip和imei)
- sk_buff详解2
- OpenAFS
- Hibernate get和load区别
- LINUX 3.5.4 PTRACE(系列三)
- Android照相小功能
- 为什么选择她他网络?客户们这样问?
- cache高速缓冲存储器映射主存储器
- GMT、UTC、PDT 时间是什么?Linux下如何调整时区
- PS中消除图片边缘的锯齿
- ThreadPoolExecutor使用介绍
- 练习:创建一个按钮,点击一次,则创建一个<input type="text"><input> 点击三次按钮,应该有三个输入框被创建出来。需要每一个input tag都有一个id
- Oracle 包操作