实验目的:掌握linux进程调度的工作原理和实现方式,提高内核调度技术。
实验内容:编一个程序在3个进程中分别循环输出字母A/B/C,每输出一个字母就主动放弃CPU;然后通过对内核的调度,画出3个进程运行的详细时序图和概要时序图,时序图的时间范围涵盖上述字母至少2个(可以相同),要求在详细的时序图中标注下列控制点信息:
调度的开始及原因和结束、进程切换的开始;
中断处理的开始和结束、软中断处理的开始和结束;
系统调用的开始及系统调用号和结束;
缺页等异常的开始和结束
增加和删除CFS运行队列中的节点的时刻
更新当前进程的vruntime的时刻
准备由核心态进入用户态的时刻
设置需要剥夺当前进程而重新调度标志TIF_NEED_RESCHED的时刻
系统处于用户态的区间
系统处于哪个进程的上下文
实验步骤:
1、编写一个普通的应用程序
提示:
创建子进程可以使用系统调用fork
输出字符A可以使用系统调用write:write(2,“A”,1)
主动放弃CPU可以使用系统调用sched_yield
父进程应等待子进程结束以后才退出,可以使用系统调用waitpid
2、在Ubuntu中编译测试上述应用程序; 待成功后,重新编译生成带调试信息的32位可执行文件
3、将生成的可执行文件放入实验用的qume虚拟机
4、运行qume虚拟机,在虚拟机的命令解释器中运行和测试应用程序,确保其正确输出期望的字符序列
5、调试分析内核,绘制时序图,步骤如下
a)启动调试,设置所需要的内核断点,可执行文件的执行(do_execve,只需要跟踪普通进程对此函数的调用),调度的开始和结束(函数_schedule的进入和退出),进程切换的开始(_switch_to),参数next_p指向新进程的进程控制块,中断处理的开始(smp_apic_timer_interrupt时钟中断,do_IRQ其他中断部分),中断和异常的结束(从ret_from_intr/ret_from_exception开始准备结束;真正结束是在restore_all,但这里也有可能是系统调用的结束),软中断处理的开始和结束(函数_do_softirq的进入和退出),缺页异常的开始(do_page_fault),设备不存在异常的开始(do_device_not_available),系统调用的开始和结束(函数do_fast_syscall_32的进入和退出,在此函数的参数regs->orig_ax中记录了系统调用号;有时系统调用的结束位置是在restore_all。系统调用返回前,一般会执行函数prepare_exit_to_usermode),增加和删除CFS运行队列中的节点(enqueue_task_fair和dequeue_task_fair,函数参数p指向被操作进程的进程控制块),更新当前进程的vruntime(update_curr,此函数结束时vruntime已经更新),准备山上核心态进入用户态(prepare_exit_to_usermode),设置需要当前进程而重新调度标志(set_tsk_need_resched)
b)关闭除do_execve之外的的所有其他断点,使用disable命令
c)在应用程序abc的main函数入口处设置断点,步骤如下:1在内核源码目录下,创建指向abc.c所在目录的符号链接,ln -s <abc.c所在目录> abc,2查看可执行文件abc的".text"节(Section)的起始虚拟地址(VMA),在可执行文件abc所在目录运行:objdump -dlx abc | less,然后查看".test"节的起始虚拟地址,3在gdb导入应用程序符号信息:dir abc,add-symbol-file abc/abc <可执行文件abc的".text"节的起始虚拟地址>,4设置断点:b abc.c:main
d)跟踪到应用程序abc的main函数入口处
e)打开所有断点,使用enable命令
f)继续运行,分析操作系统的运行轨迹,画出进程运行的时序图,直到输出至少两个字母(可以相同)
常见问题
1、如何查看当前进程的“需要剥夺当前进程而重新调度”标志(TIF_NEED_RESCHED)?
p/x $lx_thread_info($lx_current()).flags
在该flags的第3位(位置计数从低位开始、从0开始)
2、进程调度的原因有哪些
在CONFIG_PREEMPT没有定义(实验环境的默认配置)的情况下,只有两种情况可能引发调度:a)当前进程主动放弃cpu,直接引发调度;b)从内核态返回用户态之前,如果“TIF_NEED_RESCHED”标志被设置,则剥夺当前进程,引发调度
3、如何查看当前进程的vruntime(虚拟运行时间)
p $lx_current().se.vruntime
4、系统何时处于核心态,何时处于用户态
系统调用执行期间和中断、异常处理期间处于核心态;其他时间处于用户态
5、如何知道系统处于哪个进程的上下文
查看当前进程的pid即可
6、如何查询系统调用号对应的系统调用函数名
在文件Syscalls_32.h(arch\x86\include\generated\asm)中有记录
7、如何查看当前cpu的运行队列中有进程
8、查看CFS运行队列中最小的进程vruntime
9、查看当前cpu的CFS运行队列中各进程信息
10、在每次调度停止时显示某表达式的值
11、在每次某断点被捕获而停止时都执行一组命令
12、在某函数结束处设置断点
13、在gdb启动时运行调试脚本
14、为什么会观察到一些孤立的异常返回事件(ret_from_exception)?
因为只在缺页异常处理程序的入口设置了断点,没有截获其他类型的异常
15、如何在某绝对地址处设置断点
原文地址:https://www.cnblogs.com/ppbb/p/12524335.html