【Windows】線程漫談——線程棧

來源:互聯網
上載者:User

本系列意在記錄Windwos線程的相關知識點,包括線程基礎、線程調度、線程同步、TLS、線程池等。

預備知識

眾所周知,線程在初始化時,系統會為其分配線程棧,用於局部變數、函數調用時的參數等。在開始討論前,先交代一些背景知識。

棧:一種先入後出的資料結構,push和pop是它典型的操作,對應“入棧”和“出棧”的術語。

系統記憶體的分配機制:簡單的說包括“預訂”和“調撥”兩個過程。預訂並不真正分配實體儲存體器,只是對進程虛擬位址空間中的記憶體進行“預分配”,以使得這塊記憶體不至於被當前進程的其他指令分配;調撥就是為預訂的記憶體空間分配實體儲存體器(windows中實體儲存體器可能是實體記憶體,也可能是記憶體頁分頁檔)。windows之所以這樣做,歸根到底是為了讓進程以為自己佔用了所有的實體儲存體器。記憶體以頁面為單位,x86平台的頁面大小為4KB,每個頁面會有一個保護屬性,例如:PAGE_READWRITE、PAGE_GUARD等。

 

棧記憶體結構和工作原理

預設情況下,線程棧的大小為1MB,對應256個頁面。可以用Microsoft C++連結器的連結選項改變預設棧的大小,也可以通過CreateThread方法的參數改變。(最近看了點彙編的東西,我覺得事實上並非線程一定需要棧,而是C++連結器會自動在PE檔案中寫入初始化棧的資訊,PE載入器能識別並初始化SS、SP。而編譯器在處理變數和函數調用時會預設用這個棧)。我們知道x86的進棧指令PUSH總是遞減棧頂指標,所以棧順序總是從高位到低位。初始預設情況下,作業系統會為線程棧預訂1MB的空間,並調撥2個頁面的空間。為線程棧初始化的狀態:

中我們看到,前兩個頁面是被調撥的,而只有第一個頁面被設定成了PAGE_READWRITE,第二個頁面被設定成PAGE_GUARD。隨著調用越來越多的函數,線程需要越來越多的棧,當訪問到第二個頁面的時候(PAGE_GUARD),系統會得到通知,接下來系統會修改PAGE_GUARD為PAGE_READWRITE,並為下一個頁面調撥儲存空間。

當線程訪問到倒數第三個頁面的的時候,系統會為倒數第二個頁面調撥實體儲存體器,此時還會拋出EXCEPTION_STACK_OVERFLOW,如果用結構化異常處理掉了,並且線程繼續使用棧空間,那麼倒數第二個頁面會被用盡,此時不得不訪問棧底頁面,然而棧底頁面並沒有被調撥,這時發生的訪問違規將終止整個進程!這就是棧溢出錯誤!系統這麼做自然是為了保護進程中的其他記憶體空間。

相比StackOverflow,還有一個StackUnderflow的錯誤。下面的代碼展示了StackUnderflow

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,PTSTR pszCmdLine,int nCmdShow){BYTE aBytes[100];aBytes[10000H] = 0;//預設分配1MB的棧,此時訪問了1MB以外的空間...}

如果此時,aBytes[10000H]處的記憶體沒有被調撥,則會發生訪問違規;如果已調撥了實體記憶體,則其他的記憶體被破壞。

 

C++運行庫的棧檢查函數

上面所述的調撥棧空間的策略看似“無懈可擊”,可是“暗藏漏洞”。先看下面這段代碼:

void SomeFunction(){int nValues[4000];nValues[0] = 0;//assign a value}

在32位系統中,這個函數至少需要4000*4=16000位元組,其中index為0的元素在哪裡呢?在棧的低地址!如果以預設1MB的棧空間分配的話,nValues[0]將訪問尚未調撥的空間。為瞭解決這個問題,編譯器會自動插入棧檢查代碼。編譯器能夠計算出函數所需要的棧空間,如果所需要的空間大於一個頁面的大小,編譯器就會為函數插入檢查代碼。檢查代碼的原理很簡單:每次試圖訪問下一個頁面中的某個地址,以使系統自動為它分配調撥記憶體,直到需要的棧空間都滿足為止。當然如果預設的棧空間不夠的話,還是會先引發溢出異常。

勞動果實,轉載請註明出處:http://www.cnblogs.com/P_Chou/archive/2012/06/14/thread-stack.html

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.