全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1773
推到 Plurk!
推到 Facebook!

Rebase your modules (1.5) - comment

 
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-09-07 02:19:39 IP:61.219.xxx.xxx 未訂閱
上一回我們談到了 loader 在幹什壞事, 這一篇作一點解釋. dllee 大長老問到 Max/Min stack/heap size的部分. 我不太懂 Borland 的想法是什麼, 為什麼在 BCB 裡改了名字. 事實上, 無論是 tdump (Borland), dumpbin (MS), PE Specification 裡, 都是稱為 reserve / commit size. 對應是這樣: Max Stack/Heap Size <=> Reserve Stack/Heap size Min Stack/Heap size <=> Commit Stack/Heap Size 這個 Stack 指的是你這個 Main thread 所用的 Stack, Heap 則是 Default heap, 專供 Win32 系統所使用. 或是, 在 Win16 裡, LocalAlloc() / GlobalAlloc() 也會用default heap 去配置記憶體. 不過win32裡, 這些東西都是為了相容才活著, 動作已經跟以前不一樣了. Reserve Size = 最大可使用的大小, Commit = 初期被配置的大小. Microsoft 的策略是這樣的: 當程式一 load 起來之後, 他先在 Virtual memory 中, 將 Reserve size 大小的記憶體配置給該 process, 但是那一大塊記憶體, 實際上只有 Commit size 的記憶體有真的對映到 phsyical memory. 沒被分配到的部分則是標上 Guard 的屬性 (Win9x/Me 則是標上 No Access). 當你的程式一直跑, 所需求的 Stack / defautl heap space也會一直成長. 當長大到超過 commit size 時, 程式就會 access 到目前被標為 Guard/No Access 的記憶空間. 這時候會引發存取違規的現象. OS 攔截到這個錯誤之後會去判斷, 目前的 Stack/heap size 是否超過 Reserve size - 1 Page size 了. 如果沒有, 則將更多的physical memory 對映到已分配出去的 virtual memory. 如果這個動作試圖存取最後一頁, 則會引發 overflow 的 exception. 換句話說, 系統保留最後一頁當成 Guard. 不過反正也沒差, 這一頁又沒有實際對映到記憶體, 一般情況下, 在技術上的說法不算浪費. 另外, 我換一個方法講一下載入好了. 事實上, Loader 一開始會先把這個 PE Image 當成是 memory mapping file. 如果確定這個 Image 可以載入, 他就會試著先直接映對到default base address. 如果這個動作失敗, 且該 PE Module 可以被 relocation, Loader 就會根據 .reloc section 去修正 .text (code) section 的資料. 一般說來, .text section 都會被標上 Write-On-Copy 的屬性, 而當 Loader 嘗試著去寫入有這種屬性的分頁, 必然引發 exception, 而 OS 會攔截到這個 exception, 並且為這個 page 建立一個 copy, 然後偷偷的把對映過去的 Page 偷換掉, 然後把資料填下去. 不過請注意, 這個只對於有 On-Write Copy 屬性的 section 才有效, 被標為 Read Write 的 Page 則直接建立一份 Copy, 然後 mapping 到該 Process 的 virtual memory. 而 Win32 中有一個很特殊的屬性叫作 Share, 凡是被標成這個屬性的 Section (屬性的標記是以 Section 為單位), 任何被執行起來的副本, Loader 都會把那個 section 的 page(s) 直接 mapping 給所有的副本. 這就是為什麼 VC 中, 使用 #pragma comment(linker, "/SECTION:Shared, RWS") 的 section 可以作到跨行程 share data 了. --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-09-07 14:41:13 IP:203.204.xxx.xxx 未訂閱
感謝分享 < > 寫以下內容時是還沒看到以上這篇... < > 不過,應該貼在此比較合適。 不過,我還是有一些疑點,是關於 heap/stack ,或許大家可以一起來討論討論。 對於 heap/stack 個人粗淺的認知如下:(或許有錯,請指正,謝謝) stack 是區域變數暫放的空間,包含函式叫用的參數,及遞迴函數時,可能需要較多的 stack。 heap 則是在程式中 new 或 malloc 之類動態產生或配置的記憶體空間。 對於 stack ,因為懶得動態配置記憶體,而且變數使用量在可控制的範圍,於是直接使用較大的靜態陣列,省去動態配置、判斷有沒有配到、還有釋放的時間等等,因此,我直接將 BCB 中的 Min/Max Stack Size 加大了。 而發生 IDE 不能除錯的現象是,假設主程式 Main.exe 以 LoadLibrary 的方式按順序動態載入 A.dll, B.dll, C.dll,在正常的狀況下,我們可以在 Main,A,B,C 內的任何原始碼內設定中斷點,而當 Main 在 IDE 內執行時,所有可設中斷位置的原始碼前都會出現小藍點,如果有設中斷就變成打勾紅點。 但如果我把 A.dll 的 Min/Max Stack Size 加大了,那 B.dll, C.dll 在執行時就不會出現小藍點,自然也不會有中斷點。 因為是多人開發的 CASE,使得別人不能除錯,真是麻煩,最後,我取消設定改回原值,就又 OK 可以中斷除錯了。只是... 我也沒去算過我到底會用掉多少 stack... 會不會有任何意外發生呢? 對於 heap ... 說真的,我就更不解了,以最大值 0x00100000 才 1MB ,可是以之前所寫過的記憶體釋放程式,可以用全部的記憶體,甚至我也試過一次要求近 1GB 的記憶體也都可以過... 那這個最大值的設定有何用意? 以下是 BCB5 線上說明提到的內容:
引言: PE File Options Use these edit boxes to specify the minimum and maximum stack size and heap image base for the compiled executable. Min stack size specifies the minimum size of the stack in hexadecimal. The minimum allowable value for this field is 4K (0x1000). (only applicable to .EXE projects ?disabled for DLLs) Default = 0x00004000 Max stack size specifies the maximum size of the stack in hexadecimal. (only applicable to .EXE projects ?disabled for DLLs) Min heap size specifies the minimum size of the heap in hexadecimal. The minimum allowable value for this field is 0. Max heap size specifies the maximum size of the heap in hexadecimal. Image base gives your executable an image base address. If this setting is turned on, internal fixes are removed from the image and the requested load address of the first object in the application is set to the number you specify. All successive objects are aligned on 64K linear address boundaries. This option makes applications smaller on disk and improves both load-time and runtime performance (the operating system no longer has to apply internal fixes). Although this option can greatly reduce the size of your final application module; it is not recommended for producing a DLL. The recommended setting for true Win32 systems: 0x400000 Do not use the default setting of 0x400000 if you intend to run your application on Win32s systems.
由其說明好像 stack 的設定只對 exe 有效,對 dll 無效... 真的是這樣嗎? 沒空更新的網頁... http://dllee.ktop.com.tw C及指標教學,計算機概論,資訊管理導論... http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell.... 發表人 - dllee 於 2003/09/07 14:41:59
------
http://www.ViewMove.com
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-09-07 15:49:44 IP:61.219.xxx.xxx 未訂閱
引言: 由其說明好像 stack 的設定只對 exe 有效,對 dll 無效... 真的是這樣嗎?
PE Specification 如是說.. 不過我記得 DLL stack 是 caller 要負責準備的. --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-09-07 23:47:15 IP:61.219.xxx.xxx 未訂閱
引言: 這個 Stack 指的是你這個 Main thread 所用的 Stack, Heap 則是 Default heap, 專供 Win32 系統所使用. 或是, 在 Win16 裡, LocalAlloc() / GlobalAlloc() 也會用default heap 去配置記憶體. 不過win32裡, 這些東西都是為了相容才活著, 動作已經跟以前不一樣了.
抱歉, 我覺得這一段會引起一點誤會. 更正一下. 因為自己看了覺得好像是在說這整段的動作是 Win16 這樣作.. Default Heap 在 Win16 的年代, 除了供 Windows APIs 去使用以外, 如果你呼叫 Win16 API LocalAlloc() or GlobalAlloc(), 系統會將 Default Heap 分配給你. 在 Win32 中, 雖然這兩個 APIs 還是存在, 但是它們的動作已經跟 Win16 年代不一樣了. 存在的目的應該只是為了相容性. --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子
系統時間:2024-05-19 8:50:50
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!