作者VictorTom (鬼翼&娃娃魚)
看板C_and_CPP
標題[問題] 多層dll load之後自動被OS unload的問題....
時間Tue Oct 20 19:15:04 2009
小弟的工作遇到一個問題, 我們會提供一個介面dll讓AP使用....
而這個dll會再去呼叫底層我們提供的另一個dll來做事情....
用個簡單的圖解大概長得像這個樣子(PS. MS Windows + VC 2005/08)
static link
User AP ---------------> AAA.lib
^
| AP執行時會自動load dll
|
| LoadLibrary
AAA.dll ---------------> BBB.dll -> ....
AP必須先呼叫AAA的Initialize函數, 這個函數便會去LoadLibrary(BBB.dll)
結束前AP應該要呼叫AAA的DeInitialize函數, 那AAA會UnLoadLibrary(BBB.dll)
其中AAA裡會有一些context的管理, 但是主要工作是call進BBB.dll做事....
AAA還會使用GetProcessAddress取得BBB裡的一個主要的set function....
接著AAA利用這個set function傳入一個struct....
讓BBB把自己的介面function address寫進struct....
之後AAA就利用這些function pointer去叫BBB做事情....
當然也包含一些resource的動態create, destroy等等....
如果今天AP有好好的呼叫DeInitialize函數....
那麼AAA可以妥善的管理context資訊....
因為BBB的resource記錄在這些context裡...
並且依需要call進BBB去做內部資源的處理....
問題在於如果今天AP沒有好好的呼叫Terminate函數而逕行EXIT....
這時OS的機制是會先unload BBB.dll, 即BBB會先收到detachProcess....
然後才輪到AAA.dll, 即AAA會之後才收到detachProcess....
這樣AAA釋放資源發現有需要再call進BBB時就access violation了....
或者AAA會一直loop嘗試要call去free這些BBB的resource就無窮迴圈了....
所以現在小弟比較苦惱的是不太曉得該如何解決/避免這樣的問題....
最好是能讓OS不要主動/自動UnLoad dll, 而讓AAA來做UnLoadLibrary....
只是目前實測看windows的機制, 似乎難以避免這樣子的問題說....
合併AAA.dll與BBB.dll也是不可行的, 因為spec規定應該這麼做....
有想過一些方法, 不過好像都不是很好, 會破壞兩個dll的呼叫結構的感覺....
比如BBB.dll收到detachProcess時, 呼叫AAA.dll的某個function hint這件事....
(比如說重設function pointer啦, 設定某些flag讓AAA能知道這件事之類的)
並且自己把本來應該從AAA主動call進來處理的resource在此時全部釋放掉....
還是user mode的dll unload時, 動態要來的resource本來就會被OS free掉....
無窮迴圈什麼的OS等timeout了也會強迫關掉, 所以不用管它嗎??感覺很不好@_@"
所以小弟po上來請教大家的意見這樣....<(_ _)>
當然能強迫BBB.dll一定要由AAA.dll UnLoadLibrary就最好了XD
不然, 現在這樣子的架構與兩邊resource的管理大概要大修了Q_Q~
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.134.41.4
※ 編輯: VictorTom 來自: 220.134.41.4 (10/20 19:17)
→ fuha: delay load dll ? 不知可不可行 10/20 22:36
→ VictorTom:Delay Load不是用於AP啟動時嗎?? BBB.dll已經是我自己由 10/21 01:33
→ VictorTom:AAA.dll load的了所以應該沒有delay load可以作用的地方 10/21 01:33
→ VictorTom:另外AP那邊load AAA.dll似乎沒有delay的必要, 我們也無 10/21 01:33
→ VictorTom:法限制它要delay load喔....@_@" 10/21 01:34
推 marukocc:AP alloc resource,本來就應由AP free 10/21 01:43
→ VictorTom:應該算AP透過AAA.dll來allocate resource, 但是比較麻煩 10/21 01:46
→ VictorTom:的是, AP關掉卻沒Terminate的時候, 我們提供的.dll至少 10/21 01:47
→ VictorTom:要保證自己不要出事, 但是現在的狀況是我們自己提供的 10/21 01:47
→ VictorTom:.dll就會因為unload順序就產生問題了....Orz 10/21 01:48
推 avhacker:為什麼不想辦法讓 AP 執行該有的 clean up 程序即可 10/21 10:43
→ avhacker:從 DLL 那端著手才是麻煩的事吧 10/21 10:43
→ VictorTom:簡單的說, 我們是寫driver的, 我們不能強迫AP做任何事, 10/21 10:46
→ VictorTom:但是我們要保證driver dll自己不可以死掉Orz 10/21 10:46
→ VictorTom:AP不呼叫應有的Terminate程序導致memory leak之類的問題 10/21 10:47
→ VictorTom:我想不歸我們負責, 但是AP關掉時我們dll的unload會因為 10/21 10:47
→ VictorTom:底層的dll先被free掉了導致上層的dll access violation 10/21 10:47
→ VictorTom:我想這個可能就沒辦法被接受了....Orz 10/21 10:48
推 avhacker:在AAA load 出 BBB 後,把 AAA 的 instance 丟給 BBB 10/21 14:59
→ avhacker:在 BBB deatch 時去偵測是否是正常結束,如果不是,就通 10/21 14:59
→ avhacker:知 AAA,讓 AAA 在 detach 時不要做 BBB 的 clean up 10/21 14:59