首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么AddRef返回零

为什么AddRef返回零
EN

Stack Overflow用户
提问于 2014-03-06 04:59:46
回答 1查看 253关注 0票数 3

我正在调试C++/COM应用程序,看看我们如何AddRef和释放COM对象。当AddRef返回0时,我遇到了奇怪的情况。下面是我获取返回值的方法:

代码语言:javascript
复制
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;
}

pUnk实际上是web控件的IWebBrowser2 COM接口:

代码语言:javascript
复制
pUnk    0x20d763ac  IUnknown *
__vfptr 0x5d85b0d8  const CFrameWebOC::`vftable'{for `IWebBrowser2'}

我研究了这一行的反汇编(调试构建模式):

代码语言:javascript
复制
    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

此时,6515A543线上的eax为0。

在调试器中,当我进入6515A53A行时,它将显示以下代码:

代码语言:javascript
复制
    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  

5D707B76行上,值dword ptr [edi-18h]似乎是一个引用计数器,它的值是正确的,在inc命令前后都是非零的。

我知道AddRef的返回值仅用于调试目的。返回0的AddRef似乎是一个错误。这个bug会影响我正在使用的COM对象的行为,特别是生命周期吗?

如果这对我有帮助,我使用的是VirtualBox内部的64位Win7,使用的是MSVS2010。DLL AddRef位于: mshtml.dll中

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2014-03-06 08:10:54

这看起来确实很奇怪,但Alan的猜测听起来是对的。从AddRef返回零应该不会影响COM内部的任何内容,因为正如您所提到的,该值仅用于调试。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22209110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档