解析Linux核心擷取當前進程指標的方法

來源:互聯網
上載者:User
一、記憶體資料表示:
推薦文章:《linux 進程管理》
我們在教材或閱讀中,經常需要直觀的用圖示來展示資料在記憶體中的分布,那麼資料是如何在記憶體

 

中組織的呢?不同的機器有不同的標記法,我們以最常見的Intel X86系列電腦為例來說明這個問題。  如示記憶體:記憶體低址在上。記憶體高址在下,記憶體單位為16bit。對於基於intel i386架構的電腦,系統採用小端位元組序來存放資料,所謂小端位元組序是指低序位元組低地址,高序位元組高地址(記憶體位址增大方向),大端位元組序反之,給定系統所用的位元組序稱為主機位元組序;CPU也以小端位元組序形式讀取資料,如所示,如果變數num是16位的short短整類型,則CPU從記憶體中讀出的num=0x1234;如果num是32位的int類型,則CPU從記憶體中讀出的是num=0x56781234,其中num地址是0x12345678,即&num=0x12345678 二、linux核心擷取進程任務結構的指標 明白了系統記憶體資料表示,我們現在來看看linux核心是如何擷取當前進程的任務結構指標的,以下代碼均參照linux核心2.4.0的源碼。 在include/asm-i386/ current.h中

#ifndef _I386_CURRENT_H#define _I386_CURRENT_H struct task_struct; static inline struct task_struct * get_current(void){       struct task_struct *current;       __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));       return current; }#define current get_current() #endif /* !(_I386_CURRENT_H) */

  每個進程都有一個task_struct任務結構,和一片用於系統空間堆棧的儲存空間,他們在實體記憶體空間中也是聯絡在一起的,當給進程申請task_struct任務結構空間時,系統將連同系統的堆棧空間一起分配,如為某個進程切換時刻的記憶體配置圖:  下面針對代碼實現來分析一下系統如何通過一系列操作擷取進程在核心中的任務結構指標的:由於linux核心分配進程任務結構空間時,是以8KB(2個頁面空間,即2^1*4KB,linux對實體記憶體空間和虛擬記憶體空間管理時,均規定其頁面單位的尺寸為4KB)為單位來分配的,所以記憶體應用地址是8KB(2^13)的整數倍,即指標地址的低13位全為0,所以根據小端位元組序,分配記憶體返回地址應該是指向struct task_struct結構,中的0xc2342000地址所指,至於為何採用代碼中的做法而不是直接將此指標儲存在全域變數中以供應用,核心是從其自身的效率方面來考慮的,我們在此只針對代碼解釋:根據,此刻記憶體esp內容必定在0xc2342000和0xc2344000之間的一個數值,我們假設取0xc2343ffe(即堆棧壓棧EIP、返回地址、內部資料等相關資料了,地址值要減小;只要符合0xc2342xxx 、0xc2343xxx的地址指標都是正確的),來通過代碼運算看是否current的指標是0xc2342000。__asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));語句的意思是將ESP的內容與8191UL的反碼按位進行與操作,之後再把結果賦值給current,其中8191UL=8192-1=2^13-1,計算過程如下:                         

8192UL=2^13               0000  0000  0000  0000  0010  0000  0000  00008191UL                          0000  0000  0000  0000  0001  1111  1111  1111~8191UL(反碼)             1111  1111  1111  1111  1110  0000  0000  00000xc2343ffe                     1100  0010  0011  0100  0011  1111  1111  1110andl結果:                     1100  0010  0011  0100  0010  0000  0000  0000                                                                  || (對照著看)                                          0xc     2         3           4      2       0         0       0

         

 

所以按位與操作之後的結果位0xc2342000,正好是struct task_struct結構的地址指標.通過觀察可知,只要符合0xc2342xxx 、0xc2343xxx的地址指標經過相同的計算,都可以得到核心進程任務結構的指標。 另外,在進入中斷或系統調用時所引用的宏操作(include/asm-i386/ hw_irq.h):
#define GET_CURRENT /       "movl %esp, %ebx/n/t" /       "andl $-8192, %ebx/n/t"

 其原理與上述描述也是一致的。

 

上一篇:《rh9實現視頻的捕獲》
下一篇:《【linux編程】C++記憶體管理詳解(一)》

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.