2014-03-05 186 views
3

我在調試C++/COM應用程序,查看我們如何AddRef和Release COM對象。我走過來怪異的情況下的AddRef返回0。這裏是我得到的返回值:爲什麼AddRef返回零

ULONG TraceAddRef(LPUNKNOWN pUnk, const std::string &a_msg) { 
    ULONG count = pUnk->AddRef(); // count == 0 at some point after execution 
    ATLTRACE("%s *** AddRef: pUnk = 0x%p, referenceCount = %lu\n", a_msg.c_str(), pUnk, count); 
    return count; 
} 

朋克實際上是IWebBrowser2的COM接口的web控件:

pUnk 0x20d763ac IUnknown * 
__vfptr 0x5d85b0d8 const CFrameWebOC::`vftable'{for `IWebBrowser2'} 

我看着拆卸(調試構建模式),選擇那些線:

ULONG count = pUnk->AddRef(); 
6515A52C mov   eax,dword ptr [pUnk] 
6515A52F mov   ecx,dword ptr [eax] 
6515A531 mov   esi,esp 
6515A533 mov   edx,dword ptr [pUnk] 
6515A536 push  edx 
6515A537 mov   eax,dword ptr [ecx+4] 
6515A53A call  eax 
6515A53C cmp   esi,esp 
6515A53E call  _RTC_CheckEsp (65323F90h) 
6515A543 mov   dword ptr [count],eax 

在那一刻eax是0就行6515A543

在調試時,我進入訂單6515A53A,那裏會顯示如下代碼:

CFrameWebOC::AddRef: 
5D707B6D mov   edi,edi 
5D707B6F push  ebp 
5D707B70 mov   ebp,esp 
5D707B72 push  edi 
5D707B73 mov   edi,dword ptr [ebp+8] 
5D707B76 inc   dword ptr [edi-18h] 
5D707B79 cmp   dword ptr [edi-18h],2 
5D707B7D je   CFrameWebOC::AddRef+26h (5D707B93h) 
5D707B7F test  dword ptr [edi-4],0FFFFFFFCh 
5D707B86 jne   5DF2DD04 
5D707B8C xor   eax,eax 
5D707B8E pop   edi 
5D707B8F pop   ebp 
5D707B90 ret   4 
5D707B93 push  esi 
5D707B94 lea   esi,[edi-8] 
5D707B97 call  CTrackerHelper::SetAsRoot (5D85AD2Fh) 
5D707B9C pop   esi 
5D707B9D jmp   CFrameWebOC::AddRef+12h (5D707B7Fh) 
5D707B9F nop 

上線5D707B76dword ptr [edi-18h]似乎是一個引用計數器,它的值是正確的,在inc命令之前和之後非零。

我知道AddRef的返回值僅用於調試目的。 AddRef返回0看起來像一個錯誤。這個bug會影響我使用的COM對象的行爲,特別是生命期嗎?

如果這能幫助我Win7上64位的VirtualBox內,使用MSVS 2010年DLL的AddRef是:Mshtml.dll的

mshtml.dll C:\Windows\SysWOW64\mshtml.dll Symbols loaded (source information stripped). C:\SYMBOLS\PUBLIC\mshtml.pdb\049E32F8F9F84F8EB494D8324AC1C3112\mshtml.pdb 104 10.00.9200.16521 (win8_gdr_soc_ie.130216-2100) 10/24/2013 8:37 PM 5D380000-5E137000 [0x21DFC] MyApplication.exe: Native 
+0

xor eax,eax肯定會返回0,它會像跳轉到5DF2DD04的錯誤返回一樣嘎嘎。異常。 –

+4

我懷疑實際的對象可能是一個singleton,從來沒有真正釋放,所以引用計數被忽略。但是回報價值並不打算依賴,所以我不擔心。合同是如果你有參考資料,則該物件必須保持有效;其他一切都是可選的。 –

+0

MSDN文檔確實說明了返回值,「此值僅用於測試目的。」 –

回答

2

它似乎不可思議,但對右艾倫的猜測聲。從AddRef返回零不應該影響COM內部的任何內容,因爲正如您提到的那樣,該值僅用於調試。

相關問題