2011-09-21 34 views
2

我們有一箇舊的ASP應用程序調用的遺留COM + dll。它會定期崩潰,並且調用堆棧看起來很奇怪幫助一個非常奇怪的COM + callstack

看來,調用DllUnregisterServer和CoInstall會出現在調用堆棧中(我們不會在代碼中動態安裝/卸載任何東西 - 它只是查詢一個數據庫)。

我想知道是否有可能MSI「文件保護」正在踢入並導致崩潰。你認爲這是可能的嗎?任何方式我可以挖掘更多的信息? (這是一個古老的VFP應用程序了,所以我不認爲我能得到適當的調試符號)

這裏的調用堆棧:

 

Call Stack: 
vfp9t! + 0x2272f 
vfp9t!VFPDllGetClassObject + 0xb6 
ctcvccomasyncproxy!DllGetClassObject + 0x3e 
ole32!CoInitializeSecurity + 0x5ff5 
ole32!CoInitializeSecurity + 0x5bdc 
ole32!CoGetTreatAsClass + 0x2a2 
ole32!CoInitializeSecurity + 0x3a2b 
COMSVCS!DispManGetContext + 0xbc07 
ole32!CoInitializeSecurity + 0x3a2b 
ole32!CoInstall + 0x6ed 
ole32!CoQueryAuthenticationServices + 0x21aa 
ole32!CoQueryAuthenticationServices + 0x2c56 
ole32!CoGetContextToken + 0xd48d 
ole32!CreateStreamOnHGlobal + 0x1b7c 
ole32!CoCreateObjectInContext + 0xd9f 
ole32!CoInstall + 0x903 
ole32!CoGetContextToken + 0x12f5b 
RPCRT4!NdrServerInitialize + 0x1fc 
RPCRT4!NdrStubCall2 + 0x217 
RPCRT4!CStdStubBuffer_Invoke + 0x82 
ole32!StgGetIFillLockBytesOnFile + 0x13b27 
ole32!StgGetIFillLockBytesOnFile + 0x13ad4 
ole32!DcomChannelSetHResult + 0xaab 
ole32!DcomChannelSetHResult + 0x495 
ole32!CoFreeUnusedLibrariesEx + 0xb06 
ole32!StgGetIFillLockBytesOnFile + 0x139e1 
ole32!StgGetIFillLockBytesOnFile + 0x13872 
ole32!StgGetIFillLockBytesOnFile + 0x12d59 
ole32!CoFreeUnusedLibrariesEx + 0x9f5 
ole32!CoFreeUnusedLibrariesEx + 0x9c0 
USER32!LoadCursorW + 0x4cf5 
USER32!LoadCursorW + 0x4e86 
USER32!TranslateMessageEx + 0x10d 
USER32!DispatchMessageW + 0xf 
COMSVCS!DllUnregisterServer + 0x270 
COMSVCS!DllUnregisterServer + 0x180 
COMSVCS!DllUnregisterServer + 0xc6c 
COMSVCS!DllUnregisterServer + 0xf4d 
msvcrt!_endthreadex + 0xa3 
kernel32!GetModuleHandleA + 0xdf 

 
+0

多線程應用程序中必須謹慎使用'GetModuleHandle'。也許你會更喜歡'GetModuleHandleEx',但這裏沒有太多可以繼續。 – AJG85

+0

我們遇到的一個問題是,這不是C++對象 - 它是Visual Fox Pro,因此GetModuleHandle的調用不在我們的控制之下 - 我們可以訪問的代碼只調用CreateObject(),調用堆棧只是顯示代表我們的代碼。 – JMarsch

+0

所以這是不兼容的錯誤代碼,你不能改變,但需要使用? FoxPro的最終版本是7年前...祝你好運! – AJG85

回答

2

OLE32!CoInstall + 0x6ed

的+ 0x6ed偏移量是一個重要的 '質量' 指標。它告訴你的是返回地址是來自已知的CoInstall的地址的1773個字節。這相當多。堆棧跟蹤生成器只是沒有其他已知地址,因此它只能提供CoInstall作爲猜測。一旦偏移量超過0x100,代碼實際上是已知功能的一部分,開始快速縮短的機率。

跟蹤中有很多條目有很大的偏移量。使整個痕跡相當低質量。編輯堆棧跟蹤,並在地方只留下良好的質量方針:

vfp9t!VFPDllGetClassObject + 0xb6 
ctcvccomasyncproxy!DllGetClassObject + 0x3e 
... 
RPCRT4!CStdStubBuffer_Invoke + 0x82 
... 
USER32!DispatchMessageW + 0xf 

這是一個跨公寓請求獲得一個COM對象類工廠相當標準堆棧跟蹤。爲什麼失敗是不可猜測的,你沒有foxpro的調試符號,也沒有記錄HRESULT。

+0

謝謝你的解釋。我知道沒有符號,轉儲是一個很大的衝突。據我所知,我需要的符號沒有公佈,所以看起來好像我們要從垃圾堆中得到答案。不管怎麼說,還是要謝謝你。 – JMarsch

0
  1. 該堆棧轉儲並不顯得似是而非。這幾乎肯定沒有用處。

  2. 我建議編寫一個未處理的異常處理程序,並試圖讓它再次崩潰。您的處理程序可以嘗試執行更好的堆棧轉儲或甚至正確的崩潰轉儲。

處理程序會在你的代碼調用該DLL的代碼。

+0

我將無法獲得VFP運行時的調試符號。你認爲我沒有他們會得到什麼有用的東西嗎?如果是這樣,我可以嘗試獲得一個小型轉儲。恐怕沒有這些符號,我正在看到一個死衚衕。你怎麼看? – JMarsch

+0

我不會建議它很容易,但有時你可以得到有用的信息。如果崩潰在VFP調用的Windows代碼中,則可能會從傳遞給Windows函數的參數中得到線索。如果它在VFP代碼中,您至少可以檢查您傳遞給VFP入口點的參數,但實際故障可能會降低幾個級別。如果真的絕望,你可以嘗試調試彙編代碼。這很難,但並非不可能。出於安全原因,您應該能夠弄清楚它是一個錯誤還是Windows正在關閉它。 –

+0

如果你能捕捉到異常,你可以嘗試解碼它。可能會附上錯誤消息或其他有用的信息。 Max Pietrik的文章(上面的第二個鏈接)是如何做到這一點的良好開端。 –