MIT操作系统课程CS6.828实验(2) —— 实验工具指导
2016-08-13 18:47
411 查看
熟悉开发环境,对开发和调试非常关键,本节对JOS环境进行一个简单的概述,以及对GDB和QEMU的有用命令进行介绍。除了这些之外,还需要阅读GDB和QEMU手册。这些都是非常强大的工具,非常有必要去熟悉如何使用它们
GDB是一个非常好的工具,在JOS实验中,使用qemu-gdb目标(或者qemu-gdb-nox变体)让QEMU等待GDB工具连接。参考GDB中下面介绍的一些命令来调试内核。
如果出现了不期望的中断,异常,或者其他错误。可以使用-d参数让QEMU产生一些更加详细的关于错误中断的Log
但调试虚拟地址问题时,可以尝试使用QEMU监视命令 info mem(对于高级别的概述)或者info pg(对于更多的细节),注意,这些命令只显示当前的页表。
(Lab 4+)为了调试多CPU场景,可以使用GDB的线程相关的命令,像thread和info threads
1.2 用户环境(Lab 3+)
GDB也可以用于调试用户环境程序,但是需要注意一些事情,因为GDB本身不知道多个用户环境之间或用户和内核之间的差别。
通过使用make run-name(或直接编辑kern/init.c)对一特定的用户环境启动JOS。为了让QEMU等待GDB连接,使用run-name-gdb变体。
可以通过符号表来调试用户代码,就是调试内核代码一样,但是需要GDB使用symbol-file命令告诉GDB用的是哪个符号表,由于一次只能使用一个符号表, 默认提供的.gdbinit加载的是内核符号表 obj/kern/kernel。用户环境的符号表在ELF二进制文件中,因此可以使用symbol-file obj/user/name来加载对应的符号表。 不要从.o文件中加载符号,因为.o文件并没有被链接器(链接到JOS用户二进制的静态库,因此这些符号都已经包含在各个用户库中)进行重定位处理。确保获得了正确的用户库;库函数在不同二进制文件中被链接到不同的EIPs,所以GDB不知道。
(Lab 4+)因为GDB整个的连接到虚拟机,可以看到时钟中断作为另一个控制转移。这样基本上不可能逐步调试用户代码,由于一个时钟中断确保让VM再一次运行的时刻, stepi命令起作用,由于其禁止了中断,但是它只能逐步调试汇编指令。断点通过是起作用的,但是需要注意,可能在不同的环境下(不同的二进制)命中相同的EIP。
以下命令构建所有,并启动QEMU(包括在新窗口中启动VGA终端和当前终端中启动串口终端)。退出的话,要么通过关闭VGA窗口或者在串口中断中通过按Ctrl-c或者Ctrl-a x退出。
以下命令类似make qemu,但只在串口终端中启动Qemu,退出的话,按Ctrl-a x。这对于ssh方式登录非常有用,因为VGA窗口会消耗很大的带宽
以下命令类似make qemu,但是并不是在任何时间被动地接受GDB连接,该命令停止在第一条机器命令,然后等待GDB连接。
以下结合qemu-nox和qemu-gdb目标
(Lab 3+)运行用户程序name,例如,make run-hello运行user/hello.c
(Lab 3+)run-name的变体,用来响应qemu目标的变体。
makefile也可以接收一些有用的变量,例如:
以下命令V=1表示verbose模式,打印出每条命令的执行,包括参数。
以下命令表示当任何评分测试fail的时候即停止,然后把Qemu输出到jos.out中用于检查
指定额外的参数,传递给QEMU
bootloader,kernel,和用户程序的汇编代码
kernel和user程序的符号表
kernel和user程序的ELF镜像,这些包含的符号信息可以被GDB使用
停止当前机器,以及在GDB当前的指令处中断,若QEMU有很多虚拟CPU,将终止它们。
继续执行直到下一个断点或者Ctrl-c
执行一条机器指令
在给定的函数或者行设置断点
在EIP地址设置断点
确保数组和结构体的完美的打印
打印通用目的寄存器,eip,eflags和段选择子,对于更多的关于机器寄存器状态输出,参见QEMU info registers命令。
显示从虚拟地址addr开始的N个words的16进制输出,若N忽略,缺省为1,addr可以是任何的表达式。
显示从addr地址开始的N个汇编指令,使用$eip作为addr将显示当前指令指针的指令。
(Lab 3+)切换符号文件file,当GDB连接到Qemu,在虚拟机中没有进程边界的概念,所以需要告诉它使用哪个符号,缺省情况下,配置GDB使用内核符号表,obj/kern/kernel,若机器正在运行用户代码,比如hello.c,可以使用symbol-file obj/user/hello,切换到hello符号文件中。
Qemu中各个虚拟的CPU在GDB中作为一个线程,所以可以使用所有的GDB的线程相关的命令来观察和管理Qemu的虚拟CPUs。
GDB一次只关注一个线程(e.g. CPUs),该命令切换到线程n,线程编号从0开始
列出所有的线程(例如,CPUs),包括它们的状态(活动的还是终止的),以及它们处在哪个函数中。
对于完整的monitor命令,可以参考Qemu手册,以下是一些常用的比较有用的命令:
显示从物理地址paddr开始的N个words的十六进制输出。若N忽略,缺省值为1,这个是物理内存,可对比与GDB的x命令
显示机器内部寄存器状态的所有输出,尤其包括对于段选择子的隐藏段状态,以及局部的,全局的和中断描述符表, 外加task寄存器,这些隐藏的状态是虚拟CPU当加载段选择子时从GDT/LDT从读取的信息。但运行Lab1中的Jos内核,如下是寄存器CS的各个域的意思
1. 调试技巧
1.1 内核GDB是一个非常好的工具,在JOS实验中,使用qemu-gdb目标(或者qemu-gdb-nox变体)让QEMU等待GDB工具连接。参考GDB中下面介绍的一些命令来调试内核。
如果出现了不期望的中断,异常,或者其他错误。可以使用-d参数让QEMU产生一些更加详细的关于错误中断的Log
但调试虚拟地址问题时,可以尝试使用QEMU监视命令 info mem(对于高级别的概述)或者info pg(对于更多的细节),注意,这些命令只显示当前的页表。
(Lab 4+)为了调试多CPU场景,可以使用GDB的线程相关的命令,像thread和info threads
1.2 用户环境(Lab 3+)
GDB也可以用于调试用户环境程序,但是需要注意一些事情,因为GDB本身不知道多个用户环境之间或用户和内核之间的差别。
通过使用make run-name(或直接编辑kern/init.c)对一特定的用户环境启动JOS。为了让QEMU等待GDB连接,使用run-name-gdb变体。
可以通过符号表来调试用户代码,就是调试内核代码一样,但是需要GDB使用symbol-file命令告诉GDB用的是哪个符号表,由于一次只能使用一个符号表, 默认提供的.gdbinit加载的是内核符号表 obj/kern/kernel。用户环境的符号表在ELF二进制文件中,因此可以使用symbol-file obj/user/name来加载对应的符号表。 不要从.o文件中加载符号,因为.o文件并没有被链接器(链接到JOS用户二进制的静态库,因此这些符号都已经包含在各个用户库中)进行重定位处理。确保获得了正确的用户库;库函数在不同二进制文件中被链接到不同的EIPs,所以GDB不知道。
(Lab 4+)因为GDB整个的连接到虚拟机,可以看到时钟中断作为另一个控制转移。这样基本上不可能逐步调试用户代码,由于一个时钟中断确保让VM再一次运行的时刻, stepi命令起作用,由于其禁止了中断,但是它只能逐步调试汇编指令。断点通过是起作用的,但是需要注意,可能在不同的环境下(不同的二进制)命中相同的EIP。
2. JOS makfile介绍
JOS GNUmakefile文件包含很多的伪目标(Phony Target),用以不同的方式运行JOS。 所有的这些目标配置QEMU来监听GDB连接(*-gdb目标也是等到GDB连接),一旦启动了QEMU,只要在当前的lab目录下运行gdb即可。在代码中提供了.gdbinit文件自动在QEMU中指向GDB,加载内核符号表,以及在16-bit和32-bit模式之间切换,退出GDB将关闭QEMU。以下命令构建所有,并启动QEMU(包括在新窗口中启动VGA终端和当前终端中启动串口终端)。退出的话,要么通过关闭VGA窗口或者在串口中断中通过按Ctrl-c或者Ctrl-a x退出。
$ make qemu
以下命令类似make qemu,但只在串口终端中启动Qemu,退出的话,按Ctrl-a x。这对于ssh方式登录非常有用,因为VGA窗口会消耗很大的带宽
$ make qemu-nox
以下命令类似make qemu,但是并不是在任何时间被动地接受GDB连接,该命令停止在第一条机器命令,然后等待GDB连接。
$ make qemu-gdb
以下结合qemu-nox和qemu-gdb目标
$ make qemu-nox-gdb
(Lab 3+)运行用户程序name,例如,make run-hello运行user/hello.c
$ make run-name
(Lab 3+)run-name的变体,用来响应qemu目标的变体。
$ make run-name-nox, run-name-gdb, run-name-gdb-nox
makefile也可以接收一些有用的变量,例如:
以下命令V=1表示verbose模式,打印出每条命令的执行,包括参数。
$ make V=1 ...
以下命令表示当任何评分测试fail的时候即停止,然后把Qemu输出到jos.out中用于检查
$ make V=1 grade
指定额外的参数,传递给QEMU
$ make QEMUEXTRA='args' ...
3. JOS生成文件
当构建JOS,makefile同时会产生一些额外的输出文件,在进行代码调试时非常的有用。obj/boot/boot.asm, obj/kern/kernel.asm, obj/user/hello.asm, 等等 |
obj/kern/kernel.sym, obj/user/hello.sym,等等 |
obj/boot/boot.out, obj/kern/kernel, obj/user/hello等等 |
4. GDB常用命令介绍
更多的关于GDB的详细用法,可以参考GDB手册。以下只介绍6.828课程中用到的一些特定的GDB命令。其中的一些GDB命令在OS开发完很少使用。Ctrl-c
停止当前机器,以及在GDB当前的指令处中断,若QEMU有很多虚拟CPU,将终止它们。
c(或者continue)
继续执行直到下一个断点或者Ctrl-c
si(或者 stepi)
执行一条机器指令
b function或b file:line(或breakpoint)
在给定的函数或者行设置断点
b *addr(或breakpoint)
在EIP地址设置断点
set print pretty
确保数组和结构体的完美的打印
info registers
打印通用目的寄存器,eip,eflags和段选择子,对于更多的关于机器寄存器状态输出,参见QEMU info registers命令。
x/Nx addr
显示从虚拟地址addr开始的N个words的16进制输出,若N忽略,缺省为1,addr可以是任何的表达式。
x/Ni addr
显示从addr地址开始的N个汇编指令,使用$eip作为addr将显示当前指令指针的指令。
symbol-file file
(Lab 3+)切换符号文件file,当GDB连接到Qemu,在虚拟机中没有进程边界的概念,所以需要告诉它使用哪个符号,缺省情况下,配置GDB使用内核符号表,obj/kern/kernel,若机器正在运行用户代码,比如hello.c,可以使用symbol-file obj/user/hello,切换到hello符号文件中。
Qemu中各个虚拟的CPU在GDB中作为一个线程,所以可以使用所有的GDB的线程相关的命令来观察和管理Qemu的虚拟CPUs。
thread n
GDB一次只关注一个线程(e.g. CPUs),该命令切换到线程n,线程编号从0开始
info threads
列出所有的线程(例如,CPUs),包括它们的状态(活动的还是终止的),以及它们处在哪个函数中。
5. QEMU常用命令介绍
Qemu包含一个内置的监视器用来观察和修改机器状态,进入monitor模式后,在终端中按下Ctrl-a c运行Qemu, 再次按下Ctrl-a c切换到串口控制台。对于完整的monitor命令,可以参考Qemu手册,以下是一些常用的比较有用的命令:
xp/Nx paddr
显示从物理地址paddr开始的N个words的十六进制输出。若N忽略,缺省值为1,这个是物理内存,可对比与GDB的x命令
info registers
显示机器内部寄存器状态的所有输出,尤其包括对于段选择子的隐藏段状态,以及局部的,全局的和中断描述符表, 外加task寄存器,这些隐藏的状态是虚拟CPU当加载段选择子时从GDT/LDT从读取的信息。但运行Lab1中的Jos内核,如下是寄存器CS的各个域的意思
CS =0008 10000000 ffffffff 10cf9a00 DPL=0 CS32 [-R-] |
info mem
info pg
make QEMUEXTRA='-d int' ...
6. 参考
1. 6.828 lab tools guide相关文章推荐
- MIT操作系统课程CS6.828实验(1) —— 工具链安装
- MIT操作系统课程CS6.828实验(3) —— 启动PC(Lab1)
- 关于学习MIT6.828操作系统课程lab1记录
- 关于学习MIT6.828操作系统课程的记录
- MIT 操作系统实践课程
- 操作系统课程设计指导书
- CSAPP深入理解操作系统 课程实验 bomb 反向编译 汇编(3)
- MIT 操作系统实验 MIT JOS lab4
- 电子科技大学---操作系统课程实验(一)
- MIT 操作系统实验 MIT JOS lab2
- Linux内核分析实验二:mykernel实验指导(操作系统是如何工作的)
- 操作系统课程实验报告(四)
- MIT操作系统实验1-3
- MIT 6.828 学习笔记6 Lab4实验报告
- 操作系统进程实验课程设计
- 操作系统课程设计和实验
- 操作系统课程实验二 死锁的避免―银行家算法
- FZU操作系统课程实验 实验一
- MIT 操作系统实验 MIT JOS lab3