mit s0681 lab2 Trace系统调用实现

这篇具有很好参考价值的文章主要介绍了mit s0681 lab2 Trace系统调用实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实验一

实现一个用户级别的程序,功能为,指定系统调用后,跟踪程序的系统调用情况
mit s0681 lab2 Trace系统调用实现,linux,系统架构

分析实验

实验目标为实现一个程序去跟踪指定程序的系统调用。因此目标有两个

  1. 实现一个程序
  2. 跟踪目标程序的系统调用

实现1,就需要在用户这边实现一个trace的相关程序,接收监控的syscall参数,以及启动被监控程序。注意部分代码已被实现user/trace.c
实现2,需要在被监控的程序中当调用到被监控的syscall时,记录或者输出其调用情况

实验目标一
第一步

先看已提供代码
分为三步:

  1. 容错处理
  2. 调用系统调用trace,对argv[1]代表参数进行监控
  3. 调用exec,执行被监控程序
#include "kernel/param.h"
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{
  int i;
  char *nargv[MAXARG];//
/
  if(argc < 3 || (argv[1][0] < '0' || argv[1][0] > '9')){ //容错处理
    fprintf(2, "Usage: %s mask command\n", argv[0]);
    exit(1);
  }

  if (trace(atoi(argv[1])) < 0) { //调用系统调用trace,对argv[1]代表参数进行监控
    fprintf(2, "%s: trace failed\n", argv[0]);
    exit(1);
  }
  
  for(i = 2; i < argc && i < MAXARG; i++){
    nargv[i-2] = argv[i];
  }
  exec(nargv[0], nargv); //调用exec,执行被监控程序
  exit(0);
}

trace还未实现,先看第三步exec执行被监控程序的特点:

exec系统调用使用从文件系统中存储的文件所加载的新内存映像替换调用进程的内存。(百度百科:根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件)该文件必须有特殊的格式,它指定文件的哪部分存放指令,哪部分是数据,以及哪一条指令用于启动等等。xv6使用ELF格式(将会在第三章详细讨论)。当exec执行成功,它不向调用进程返回数据,而是使加载自文件的指令在ELF header中声明的程序入口处开始执行。

也就是说exec所执行的可执行文件在调用进程之中,所以我们监控时只需要监控自身进程即可。

第二步

由于trace该用户进程还没有声明进入编译,因此我们需要Makefile中声明$U/_trace\,使其被编译(注意系统调用未完善,编译会失败)

实验目标二

在实验目标一的基础上,可以发现被监控的程序与原监控程序在同一个进程之中,所以该trace系统调用要做的就是将跟踪的syscall写入该进程之中,将其保存。在后续触发syscall时,判断是否需要为监控的syscall,是则输出其调用记录。因此分为如下几步:

  1. 使用trace系统调用,记录监控的syscall
  2. 检查执行的syscall
第一步

修改kernel/proc.h文件,在其中声明跟踪syscall,这里使用trace_mask做标记。
mit s0681 lab2 Trace系统调用实现,linux,系统架构
修改kernel/proc.c文件,增加trace函数,其中记录跟踪的syscall
mit s0681 lab2 Trace系统调用实现,linux,系统架构
mit s0681 lab2 Trace系统调用实现,linux,系统架构
注意系统调用中fork会重新开辟进程空间,因此fork出来的进程是需要继承父进程的trace_mask的
mit s0681 lab2 Trace系统调用实现,linux,系统架构

第二步

检查系统调用是否为被监控syscall,在kernel/syscall.c中加入监控代码即可。syscall_names是我手动定义的syscall name。用于输出
mit s0681 lab2 Trace系统调用实现,linux,系统架构

代码执行过程

主体代码在上面过程中已经全部实现。后续就是把上面代码连通。
参考xv6的系统调用进入kernel逻辑:

想要调用内核函数的应用程序(例如xv6中的read系统调用)必须过渡到内核。CPU提供一个特殊的指令,将CPU从用户模式切换到管理模式,并在内核指定的入口点进入内核(RISC-V为此提供ecall指令)。一旦CPU切换到管理模式,内核就可以验证系统调用的参数,决定是否允许应用程序执行请求的操作,然后拒绝它或执行它。由内核控制转换到管理模式的入口点是很重要的;如果应用程序可以决定内核入口点, 那么恶意应用程序可以在跳过参数验证的地方进入内核。(原书2.2节)

因此需要在user/usys.pl里面声明trace,使其调用trace时进程能顺利进入内核态。
mit s0681 lab2 Trace系统调用实现,linux,系统架构
注意13行,那里会查询SYS_trace的编号并执行对应函数,因此我们需要定义该调用编号kernel/syscall.h
mit s0681 lab2 Trace系统调用实现,linux,系统架构
声明该编号对应的函数kernel/syscall.c
mit s0681 lab2 Trace系统调用实现,linux,系统架构
至于sys_trace函数的实现,直接让其调用目标二的trace函数即可kernel/sysproc.c
mit s0681 lab2 Trace系统调用实现,linux,系统架构
最后在user/user.h中增加对trace函数的引用mit s0681 lab2 Trace系统调用实现,linux,系统架构

实验结果

mit s0681 lab2 Trace系统调用实现,linux,系统架构文章来源地址https://www.toymoban.com/news/detail-677288.html

到了这里,关于mit s0681 lab2 Trace系统调用实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 临时表、视图与系统函数_Lab2

    理解CTE与视图的知识,掌握临时表、CTE与视图的创建与使用方法,能够根据需要创建CTE、视图,掌握视图应用技术,熟悉常用系统函数的应用方法。 1、 针对指定的表进行全文检索配置,利用全文检索检索记录。 2、 创建视图。 3、 练习常用系统函数使用方法 1、基于派生表

    2024年02月08日
    浏览(28)
  • 《深入理解计算机系统》Lab2-Bomblab

    这篇文章主要记录了我做bomblab的过程,希望能给你一些灵感 本次实验为 熟悉汇编程序 及其 调试方法 的实验。 实验内容包含2个文件:bomb(可执行文件)和bomb.c(c源文件)。 实验主题内容为: 程序运行在linux环境中。程序运行中有6个关卡(6个phase),每个phase需要用户在

    2024年02月04日
    浏览(32)
  • MIT 6.830数据库系统 -- lab two

    原项目使用ant进行项目构建,我已经更改为Maven构建,大家直接拉取我改好后的项目即可: https://gitee.com/DaHuYuXiXi/simple-db-hw-2021 然后就是正常的maven项目配置,启动即可。各个lab的实现,会放在lab/分支下。 lab2必须在lab1提交的代码基础上进行开发,否则无法完成相应的练习。此外

    2024年02月12日
    浏览(28)
  • 操作系统复习 MITS6.1810 lab util 记录

    介绍:主要用来熟悉下环境以及代码结构。 See kernel/sysproc.c for the xv6 kernel code that implements the sleep system call (look for sys_sleep ), user/user.h for the C definition of sleep callable from a user program, and user/usys.S for the assembler code that jumps from user code into the kernel for sleep . 代码: 单个管道一般用于

    2024年02月15日
    浏览(27)
  • 1670_MIT 6.828 xv6中增加系统调用的实现与分析

             全部学习汇总: GreyZhang/g_unix: some basic learning about unix operating system. (github.com)          操作系统的任务调度切换,在xv6中其实是基于中断的方式来进行触发的。          在ttap处理的部分,调用了一个trap处理的C语言接口。          也就是上面的接口。

    2023年04月11日
    浏览(26)
  • lab2 bomblab

    通过下面这个文件可以发现,read_line函数的结果rax放入了rdi寄存器,也就是作为phase_1函数的第一个参数,然后调用了phase_1函数 在phase_1函数中,又将0x402400放入esi寄存器,调用了strings_not_equal函数。 此时rdi寄存器存的是readline函数的结果,esi寄存器存的是一个地址,分别作为

    2024年02月15日
    浏览(25)
  • MIT6824——lab4(实现一个分片kv存储)的一些实现,问题,和思考

    和lab3A一样,shardctler也是一个服务,由客户端调用。这个服务建立在raft集群上, 保证容错。 shardctler也应该保证 线性一致性和重复请求的问题 ,因此也需要记录clientid和messageid。 shardctler保存了当前的分片信息,称为配置 Num:当前配置号 Shards:每一个分片对应的副本组id—

    2024年02月07日
    浏览(27)
  • 操作系统实验 2.3系统调用:linux-0.11-lab “为版本0内核增加一个系统调用getjiffies” 和 “在用户程序中使用新增的系统调用”

    打开 vscode ,在如图所示位置打开 ~/os/linux-0.11-lab/0 文件夹 1.定义getjiffies系统调用 题目中给的提示:进入到 unistd.h 文件中 阅读代码,可以发现上图划线处有个系统调用名为 getpid :返回当前进程号——这与我们期望实现的功能类似:通过系统调用返回jiffies值。 于是此时希望

    2023年04月08日
    浏览(85)
  • CS144 计算机网络 Lab2:TCP Receiver

    Lab1 中我们使用双端队列实现了字节流重组器,可以将无序到达的数据重组为有序的字节流。Lab2 将在此基础上实现 TCP Receiver,在收到报文段之后将数据写入重组器中,并回复发送方。 TCP 接收方除了将收到的数据写入重组器中外,还需要告诉发送发送方: 下一个需要的但是

    2023年04月25日
    浏览(27)
  • 6.s081/6.1810(Fall 2022)Lab2: System calls

    这个lab主要介绍了用户态到内核态的系统调用做了什么,并让我们照猫画虎完成了两个系统调用的实现。 环境搭建 Lab1: Utilities Lab2: System calls Lab3: Page tables Lab4: Traps Lab5: Copy-on-Write Fork for xv6 官网链接 xv6手册链接,这个挺重要的,建议做lab之前最好读一读。 xv6手册中文版,这

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包