中斷、異常和系統調用(2-1,2-2,2-3)

2-1 課堂練習2.1:外部中斷

本實訓分析 Linux 0.11 對外部中斷的響應和處理過程。在每條指令執行的末尾,如果沒有關中斷,CPU 會檢查是否收到了外部中斷信號,如果有信號,則 CPU 就切換到核心態去執行對應的中斷處理程序,在處理完畢后,會執行 iret 這個中斷返回指令,回到原狀態(一般是用戶態),繼續執行原程序。

第1關時鐘中斷的發生

任務描述

?本關任務:通過實際操作回答在輸出第一行 0/1 字符的過程中(如下圖所示),共發生了幾次時鐘中斷?

相關知識

為了完成本關任務,你需要掌握: 1.設置版本 1 內核為分析對象; 2.開始用 gdb 調試內核; 3.跟蹤分析時鐘中斷。

設置版本1內核為分析對象

首先解壓版本1內核源碼。使用cp命令將/data/workspace/myshixun/exp1中的1.tgz復制到~/os/目錄下;

切換到~/os/linux-0.11-lab目錄下,將1.tgz解壓到當前目錄下;

然后調整cur的指向。先使用rm -rf curcur刪除,再使用ln命令創建符號鏈接。

現在可以編譯和測試版本 1 內核。首先進入1/linux目錄下編譯內核;

確認內核映像文件Image已經生成;

然后回到目錄~/os/linux-0.11-lab,并使用./run啟動虛擬機檢測內核是否正常;

如果正常虛擬機在加載完畢之后將會出現如下畫面。

第2關第一次時鐘中斷

?任務描述

分析版本1內核,找到第一次時鐘中斷的恢復點地址。

相關知識

為了完成本關任務,你需要掌握: 1.用 gdb 調試內核; 2.跟蹤分析時鐘中斷; 3.中斷/異常的恢復點分析。

準備階段

本關卡的分析對象是版本1內核,可以基于前一關卡環境進行后續實驗,如果重置實驗環境則需要重新將版本1內核設置為分析對象,詳見第一關的相關知識。

使用 gdb 調試內核

啟動兩個終端,在一個終端里切換到目錄~/os/linux-0.11-lab,然后運行腳本 rungdb,以啟動 bochs 虛擬機并等待 gdb 連接;

在另一個終端里切換到目錄~/os/linux-0.11-lab,然后執行腳本./mygdb,以啟動 gdb 并讀入符號信息,跟蹤到 main 函數入口。

跟蹤分析時鐘中斷

在函數 do_timer(由時鐘中斷的處理函數 timer_interrupt 調用)處設置斷點; 跟蹤到該斷點第 1 次出現;

中斷/異常的恢復點分析

當一個中斷/異常被 gdb 捕獲時,通常正在運行中斷處理程序,這時可以繼續跟蹤,直至回到恢復點指令。以時鐘中斷為例,為了從函數 do_timer 跟蹤到恢復點,可以如下操作:

由上圖可見時鐘中斷處理程序的入口是 timer_interrupt 函數。 跟蹤到當前函數(do_timer)執行完畢返回到 timer_interrupt 函數;

跟蹤到 timer_interrupt 函數(用匯編語言寫的)末尾的 iret 指令;

通過單步執行命令 si 來執行該 iret 指令,返回到恢復點;

再通過反匯編命令:disas ,分析恢復點指令的地址。

關閉 gdb 調試: 在評測通關之后為了保證環境的正常,不影響下一關的操作,需要先輸入 kill 指令關閉虛擬機,然后輸入 quit 退出 gdb 調試。

答案

第3關第六次時鐘中斷

?任務描述

本關任務:通過相關知識以及實驗回答:版本 1 內核的第 6 次時鐘中斷發生時,斷點和恢復點(指令地址)分別是多少?此時 bochs 虛擬機輸出的 0/1 字符串是什么?(忽略空格)

相關知識

為了完成本關任務,你需要掌握: 1.使用 gdb 調試內核; 2.跟蹤分析時鐘中斷。

準備階段

本關卡基于前面關卡環境進行后續實驗,如果重置實驗環境請從第一關重新開始。

使用 gdb 調試內核

啟動兩個終端,在一個終端里切換到目錄~/os/linux-0.11-lab,然后運行腳本 rungdb,以啟動 bochs 虛擬機并等待 gdb 連接;

在另一個終端里切換到目錄~/os/linux-0.11-lab,然后執行腳本./mygdb,以啟動 gdb 并讀入符號信息,跟蹤到 main 函數入口。

跟蹤分析時鐘中斷

開始用 gdb 調試內核,跟蹤到 main 函數入口。方法與第 1 關的步驟(2)一樣。 (點擊右下角上一關可以直接查看上一關內容,不會對關卡造成影響,但是不要點擊評測,會改變環境)

捕獲第 6 次時鐘中斷的發生

方法與第 2 關的步驟(3)類似,跟蹤到斷點 do_timer 第 6 次出現時即可,此時 jiffies 的值也是 6 。

中斷/異常的恢復點分析

當一個中斷/異常被 gdb 捕獲時,通常正在運行中斷處理程序,這時可以繼續跟蹤,直至回到恢復點指令。以時鐘中斷為例,為了從函數 do_timer 跟蹤到恢復點,可以類似如下操作:

由上圖可見時鐘中斷處理程序的入口是 timer_interrupt 函數。 跟蹤到當前函數(do_timer)執行完畢返回到 timer_interrupt 函數;

跟蹤到 timer_interrupt 函數(用匯編語言寫的)末尾的 iret 指令;

使用調試命令 si 來執行該 iret 指令,返回到恢復點;

然后通過反匯編命令:disas ,來分析恢復點指令的地址。

斷點指令和恢復點指令的分析

對于外部中斷而言,恢復點指令是斷點指令的后一條。需要說明的是,loop 指令的功能是先將 ecx 寄存器減一,然后檢查其值,如果其值非 0 ,則繼續循環,否則中止循環,執行下一條指令。以如下指令為例:

其功能是:在地址 0x7977 處循環,每次 ecx 寄存器都減一,直到其值為 0 。因此,loop 指令的上一條有可能是它自己。 在 gdb 中查看寄存器值的命令是 info reg:

斷點指令和恢復點指令的分析

對于外部中斷而言,恢復點指令是斷點指令的后一條。需要說明的是,loop 指令的功能是先將 ecx 寄存器減一,然后檢查其值,如果其值非 0 ,則繼續循環,否則中止循環,執行下一條指令。以如下指令為例:

其功能是:在地址 0x7977 處循環,每次 ecx 寄存器都減一,直到其值為 0 。因此,loop 指令的上一條有可能是它自己。 在 gdb 中查看寄存器值的命令是 info reg:

答案

?

2-2 課后作業2.1:外部中斷

第1關修改版本 1 內核源碼,使得每次時鐘中斷發生時,都在屏幕上輸出字符 ‘t’

任務描述

本關任務:修改版本 0 內核,使得每發生 100 次時鐘中斷,就在屏幕上輸出一個字符‘t’和當時的進程號,如“t(0)”表示0號進程運行時發生了時鐘中斷。

相關知識

為了完成本關任務,你需要掌握: 1.內核態下的字符輸出; 2.判斷已經發生了多少次時鐘中斷。

內核態下的字符輸出

在版本 0 內核里,可以使用函數printk來輸出字符,其用法類似于printf注: 在版本 0 內核中,沒有實現用int 0x81指令輸出字符這個功能。

printk用法示例:

  1. printk("trying to free inode with count=%d\n",inode->i_count);
判斷已經發生了多少次時鐘中斷

已經發生的時鐘中斷的次數記錄在全局變量 jiffies 中,每發生一次時鐘中斷,該變量的值就增加 1 。

編程要求

根據相關知識,以及上課內容,對版本 0 內核進行修改,使得每發生 100 次時鐘中斷,就在屏幕上輸出一個字符‘t’和當時的進程號。

,

使用VScode打開1/linux文件夾,獲取版本1內核源代碼?

在timer_interrupt函數開頭添加輸出字符t的匯編代碼:

movb $116, %al
int $0x81

回到命令行中重新編譯1/linux,再啟動./rungdb和./mygdb虛擬機即可過關

第2關修改版本 0 內核

任務描述

本關任務:修改版本 0 內核,使得每發生 100 次時鐘中斷,就在屏幕上輸出一個字符‘t’和當時的進程號,如“t(0)”表示0號進程運行時發生了時鐘中斷。

相關知識

為了完成本關任務,你需要掌握: 1.內核態下的字符輸出; 2.判斷已經發生了多少次時鐘中斷。

內核態下的字符輸出

在版本 0 內核里,可以使用函數printk來輸出字符,其用法類似于printf注: 在版本 0 內核中,沒有實現用int 0x81指令輸出字符這個功能。

printk用法示例:

  1. printk("trying to free inode with count=%d\n",inode->i_count);
判斷已經發生了多少次時鐘中斷

已經發生的時鐘中斷的次數記錄在全局變量 jiffies 中,每發生一次時鐘中斷,該變量的值就增加 1 。

編程要求

根據相關知識,以及上課內容,對版本 0 內核進行修改,使得每發生 100 次時鐘中斷,就在屏幕上輸出一個字符‘t’和當時的進程號。

,

通過vscode找到do_timer

?在函數中添加

if(jiffies%100==0)
prink("t(%d),sys_getpid());

2-3 課堂練習2.2:中斷/異常的處理過程


第1關除零異常分析

任務描述

分析版本 1.1 內核,回答下列問題: 1.在函數 main 的語句jiffies = jiffies/0;所對應的匯編指令片段中,有一個 idiv 指令,此指令的地址是多少? 2.在該 idiv 指令執行之前,當前指令位置(CS:EIP)和棧位置(SS:ESP)分別是多少? 3.使用 si 命令執行了該指令后,新指令位置和棧位置分別是多少?此時棧中保存的恢復點位置和用戶棧位置分別是多少?

相關知識

為了完成本關任務,你需要掌握: 1.如何設置某版本的內核為分析對象; 2.如何開始用 gdb 調試內核; 3.查看 C 語句編譯之后對應的匯編指令片段; 4.分析響應中斷/異常時,CPU 做了哪些工作; 5.查看當前寄存器的狀態; 6.查看當前棧頂的狀態。

實驗準備

本關卡使用版本 1.1 內核作為分析對象,內核文件存放在/data/workspace/myshixun/exp1文件夾中,可以將其解壓到linux-0.11-lab下使用。

如何設置某版本的內核為分析對象

下面以版本1內核為例進行講解。

首先解壓版本1內核源碼。使用cp命令將/data/workspace/myshixun/exp1中的1.1.tgz復制到~/os/目錄下;

切換到~/os/linux-0.11-lab目錄下,將1.1.tgz解壓到當前目錄下;

然后調整cur的指向。先使用rm -rf curcur刪除,再使用ln命令創建符號鏈接。

如何開始用 gdb 調試內核

先關閉bochs虛擬機,然后打開兩個終端,其中一個終端在linux-0.11-lab目錄下運行rungdb腳本,以啟動 bochs 虛擬機并等待 gdb 連接;

在另一個終端里切換到目錄~/os/linux-0.11-lab/,然后啟動腳本./mygdb,這個命令會啟動 gdb 并讀入內核符號信息,同時會通過執行0.gdb中的調試命令來連接到 bochs 虛擬機,并進而跟蹤到 main 函數入口。

查看 C 語句編譯之后對應的匯編指令片段

如果要查看某條 C 語句編譯之后對應的匯編指令片段,可以在該 C 語句處設置斷點,并跟蹤到該斷點,然后反匯編,所看到的當前指令之后的一段匯編指令就對應于該 C 語句。

例如,jiffies = jiffies/0;是文件 main.c 的第 147 行,可以如下方式查看:

上面顯示的匯編指令中,有一行前面有箭頭標識,此即為當前指令,即馬上將要執行的指令。

分析響應中斷/異常時,CPU 做了哪些工作
  • 切換到核心棧,并在其中保存中斷現場。

  • 轉到中斷處理程序去運行,并切換到核心態。

如下圖所示:

上圖顯示了棧中中斷現場的結構,(OLD SS:OLD ESP) 描述了用戶棧頂的位置,(OLD CS:OLD EIP) 描述了恢復點的位置。

如何查看當前寄存器的狀態

使用 gdb 調試命令 info registers 即可,如下所示:

也可以單獨查看某一個寄存器:

如何查看當前棧頂的狀態

可以使用命令 x 來查看:

上面顯示了棧頂的 5 個長字,是某異常發生時的中斷現場,其中存儲的用戶棧頂的位置是 0x17:0x2573c ,存儲的恢復點的位置是 0xf:0x7967 。需要注意的是,x86 中棧是從高地址向低地址方向增長的,這里的棧頂位置是 0x1fa0c 。

編程要求

根據相關知識,回答問題:(將答案填寫在/data/workspace/myshixun/第一關.txt中) 1.在函數 main 的語句jiffies = jiffies/0;所對應的匯編指令片段中,有一個 idiv 指令,此指令的地址是多少? 2.在該 idiv 指令執行之前,當前指令位置(CS:EIP)和棧位置(SS:ESP)分別是多少? 3.使用 si 命令執行了該指令后,新指令位置和棧位置分別是多少?此時棧中保存的恢復點位置和用戶棧位置分別是多少?

答案

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/207408.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/207408.shtml
英文地址,請注明出處:http://en.pswp.cn/news/207408.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android 獲取進程名稱

Android 獲取進程名稱 本篇文章主要獲取下當前應用的進程名稱,具體代碼如下: public static String getProcessNameDevice(final Context context) {int myPid Process.myPid();if (context null || myPid < 0) {return "";}ActivityManager.RunningAppProces…

DHTMLX Scheduler PRO 6.0.5 Crack

功能豐富的 JavaScript調度程序 DHTMLX Scheduler 是一個 JavaScript 日程安排日歷&#xff0c;具有 10 個視圖和可定制的界面&#xff0c;用于開發任何類型的日程安排應用程序。 DHTMLX JS 調度程序庫的主要特性 我們的 JS 調度程序最需要的功能之一是時間軸視圖。借助時間軸…

vue-loader是如何工作的?

什么是單文件組件&#xff1f; 單文件組件是一種將模板、腳本和樣式封裝在一個 .vue 文件中的方式 例如&#xff1a; <template><div class"example">{{ msg }}</div> </template> <script>export default {data() {return {msg: &qu…

【語義分割數據集】——imagenet語義分割

地址&#xff1a;https://github.com/LUSSeg/ImageNet-S 1 例圖 2. 類別和數量信息 疑問 根據原文的描述&#xff1a;Based on the ImageNet dataset, we propose the ImageNet-S dataset with 1.2 million training images and 50k high-quality semantic segmentation annot…

【JNPF】好用、高性價比的低代碼開發平臺

目錄 1.JNPF介紹 突出優勢 2.JNPF的開放性與擴展性 平臺的開放性&#xff1a; 平臺高拓展性 在快速發展的軟件開發領域&#xff0c;低代碼平臺已經成為了一種重要的開發方法&#xff0c;它使非專業開發人員也能夠參與到軟件開發中去&#xff0c;大大加速了軟件開發的效率。…

2023年總結和2024年展望(以ue為主攻)

2023年就要過去了&#xff0c;總結下&#xff1a; 先說好的地方 1&#xff0c;pbr材質集成到了osg中&#xff0c;加上直接光和間接光。終于知道pbr咋回事了。光線追蹤的視頻也跟著敲了一個。 2&#xff0c;得到了認可。拿到了半年獎&#xff0c;leader讓我明年和架構師一起進行…

Leetcode—2034.股票價格波動【中等】

2023每日刷題&#xff08;五十二&#xff09; Leetcode—2034.股票價格波動 算法思想 實現代碼 class StockPrice { public:int last 0;multiset<int> total;unordered_map<int, int> m;StockPrice() {}void update(int timestamp, int price) {if(m.count(time…

VUE學習一、環境的安裝

1.node.js安裝 node.js是前端依賴的環境, 類似于java中的jdk 下載地址 node.js 下載 msi文件 下完就是一頓嘎嘎安裝 , 安裝后可以cmd看看node和npm的版本 1.2 yarn的安裝 Yarn是Facebook最近發布的一款依賴包安裝工具。Yarn是一個新的快速安全可信賴的可以替代NPM的依賴管…

計算機圖形學——消隱算法

目錄 消隱算法 &#xff08;1&#xff09;隱藏線消除算法 &#xff08;2&#xff09;隱藏面消除算法 曲面體消隱算法 3D Mesh 隱藏面消除算法 &#xff08;1&#xff09;深度緩沖器算法&#xff08;zBuffer&#xff09; 深度緩沖器 &#xff08;2&#xff09;深度排序…

SpringBoot的監控(Actuator) 功能

目錄 0、官方文檔 一、引入依賴 二、application.yml文件中開啟監控 三、具體使用 四、具體細節使用 五、端點開啟與禁用 六、定制Endpoint 1. 定制 /actuator/health 2. 定制 /actuator/info &#xff08;1&#xff09;直接在配置文件中寫死 &#xff08;2&#xff…

分頁顯示功能函數的核心 代碼主要參考思路

分頁顯示功能函數的核心 代碼主要參考思路 package org.utils;import java.util.List;import org.entity.Student;/*** * author 24519* 分頁的工具類**/ public class PageUtils {//頁大小&#xff08;每頁顯示多少條記錄&#xff09;private int pageSize;//當前頁private in…

如何進行代碼混淆?方法與常見工具介紹

? 目錄 什么是代碼混淆&#xff1f; 代碼混淆的方法 常見代碼混淆工具 什么是代碼混淆&#xff1f; 代碼混淆是指將計算機程序的代碼轉換成一種功能上等價&#xff0c;但難于閱讀和理解的形式的行為。混淆后的代碼很難被反編譯&#xff0c;即使反編譯成功也很難得出程序的…

【Linux系統化學習】命令行參數 | 環境變量的再次理解

個人主頁點擊直達&#xff1a;小白不是程序媛 Linux專欄&#xff1a;Linux系統化學習 代碼倉庫&#xff1a;Gitee 目錄 mian函數傳參獲取環境變量 手動添加環境變量 導出環境變量 environ獲取環境變量 本地變量和環境變量的區別 Linux的命令分類 常規命令 內建命令 …

前端面試JS—map 和 forEach 的區別

目錄 相同點&#xff1a; 不同點&#xff1a; 相同點&#xff1a; 都是循環遍歷數組中的每一項&#xff08;接收一個函數作為參數&#xff0c;并對每個數組元素執行一次&#xff09;每次執行匿名函數都支持三個參數&#xff1a;&#xff08;三個參數分別為item&#xff08;當前…

js獲取快遞單號小練習

目錄 1、css代碼 2、html代碼 3、js代碼 完整代碼 效果圖 1、css代碼 .box{width: 400px;height: 300px;margin: 100px auto;position: relative;}input{width: 250px;height: 40px;outline: none;}span{display: block;position: absolute;min-width: 270px;max-width: 40…

pytest +uiautomator2+weditor app自動化從零開始

目錄結構1.0 把設備連接單獨移出去了 模塊操作代碼&#xff0c;有一些流程操作和斷言方法 from devices import dv from time import sleep import random from tool.jt import capture_screenshotdef initialization(func):def wrapper():sleep(1)dv.app_stop(com.visteon.…

CSS特效025:旋轉的loading狀態

CSS常用示例100專欄目錄 本專欄記錄的是經常使用的CSS示例與技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花邊信息三部分內容。其中CSS布局主要是列出一些常用的CSS布局信息點&#xff0c;CSS特效主要是一些動畫示例&#xff0c;CSS花邊是描述了一些CSS…

Ubuntu 修改當前用戶的名稱

UBUNTU 2018.04 LTS 64位 修改當前用戶的名稱 操作步驟如下&#xff1a; 假設你的帳號AAA &#xff0c; 打算修改為BBB。開機進入桌面。按下ctrl alt F1~F7 三個組合鍵。功能鍵F1到F7任選1個。 進入黑屏。登陸root 用戶&#xff0c;進入后。修改以下三個文件 /etc/passwd&a…

Linux學習筆記(九)MISC設備驅動

前言 misc 的意思是混合、雜項的&#xff0c;因此 MISC 驅動也叫做雜項驅動。也就是當我們板子上的某些外設無法進行分類的時候就可以使用 MISC 驅動。 MISC 驅動其實就是最簡單的字符設備驅動&#xff0c;通常嵌套在 platform 總線驅動中&#xff0c;實現復雜的驅動&#xff0…

Mysql 索引概念回顧

一、什么是索引 在關系數據庫中&#xff0c;索引是一種單獨的、物理的對數據庫表中一列或多列的值進行排序的一種存儲結構&#xff0c;它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的數據頁的邏輯指針清單。索引的作用相當于圖書的目錄&#xff0c;可以根據…