Under what conditions will the IUnknown::AddRef method return 0?

A customer was debugging their application and discovered that for one of the objects they were using, the IUnknown::Add­Ref method returns 0. How is that possible? That would imply that the object's reference count was originally negative one?

The return value from IUnknown::Add­Ref is the object reference count by convention, but

This value is intended to be used only for test purposes.

The return value is purely advisory and is not required to be accurate.

For example, if the object is a proxy, it will most likely return the reference count of the local proxy rather than the raw reference count of the original object. Conversely, if you have an object with outstanding proxies, the IUnknown::Add­Ref will count only one reference per proxy, even if the proxies themselves have reference counts greater than one.

The object the customer was using came from MSHTML.DLL, and it so happens that the implementation of IUnknown::Add­Ref used by that component always returns zero. It is technically within their rights to do so.

I don't know for sure, but I suspect this is done on purpose to avoid applications relying on the exact reference count. Applications are known to do dubious things, such as call IUnknown:­Release in a loop until it says the reference count is zero. Making the objects return a value from IUnknown::Add­Ref that betrays no information about the object's true reference count may have been a defensive step to prevent applications from making any such dubious dependency.

If you install the debugging version of MSHTML.DLL, then the IUnknown::Add­Ref method will return the reference count. Which makes sense in its own way because the value is intended to be used only when debugging.

Comments (14)
  1. prshaw says:

    Where/how/what is the debugging version of MSHTML.DLL obtained? I don't think I have ever heard of that before. A quick google search didn't show any info in the first few results.

    This could be very helpful in a product I am working on.

    [Debugging versions of Windows are available on MSDN. -Raymond]
  2. You need an MSDN subscription to get at checked builds, iirc?

  3. prshaw says:

    Ok. I have the subscription but have never worked with the checked builds of Windows. Way back when (before virtualization) I didn't have a separate machine to run them on, now I don't have that excuse.

    General question about the debug builds, are they an all or nothing? Do I need to use the full debug build of windows, or are there DLLS (like MSHTML) that can be installed individually? Really need to explore this stuff.

    ]Officially, I think it's all or nothing, but in practice, you can generally mix and match. -Raymond]
  4. dirk gently says:

    What exactly that it means that it can only be used for test purposes? Can it be used to test what is the new reference count? Apparently not.

    I am wondering, since technically the value can be meaningless (as in the discussed implementation of IUnknown::Add­Ref) or I guess even random, is there an actual use where this value would be helpful?

    [If you're trying to debug a problem, you can look at the return value to give you a clue as to what is going on. But you shouldn't have business logic depend on it. -Raymond]
  5. I am reminded of this mathematical joke:


    A Mathematician, a Biologist and a Physicist are sitting in a street cafe watching people going in and coming out of the house on the other side of the street.

    First they see two people going into the house. Time passes. After a while they notice three persons coming out of the house.

    The Physicist: "The measurement wasn't accurate.".

    The Biologist: "They have reproduced".

    The Mathematician: "If now exactly one person enters the house then it will be empty again."

  6. Me says:

    So you're saying that if my program relies on MSHTML's component's AddRef to return an accurate value, I will need to get the debug version of Windows and ship its MSHTML.DLL alongside my application?

  7. Andrew says:

    @Me No, he's saying don't rely on the return value.

    [I'm pretty sure @Me was joking. -Raymond]
  8. Terry Denham says:

    @Me, no, what he's saying is that you shouldn't rely on the AddRef count. You should be tracking your own references. When you call AddRef, you need to call Release when you're done with the component – for each instance of the component you created. You shouldn't blindly call Release, especially for a system level component.

  9. wqw says:

    @Terry Denham: This is not a "system level" component — it's just the IE browser or part of, running in my process. I can probe and find the private m_dwRefCount if want to, so no need to play it rude.

    IE team has such a high bugs-to-features ratio. Custom heap, custom COM, custom GC, custom compiler (?) — do they think they or as import as OS or Office or something.

    They should start wiping from behind first, IMHO.

  10. Anon says:


    Terry had it right there.

    IE, on Windows, is 'OS-level'. You are almost never going to encounter a version of Windows without it.

    Additionally, I've encountered geometrically more bugs caused by third-party developers misusing IE than native to IE, so this is a case of "don't throw stones."

  11. Muzer_ says:

    "[I'm pretty sure @Me was joking. -Raymond]"

    I'd hope so. If there's one thing some of the stories on this blog have taught me, it's that you can never be as sure as you might hope that people won't really try things like this ;)

  12. Mark says:

    prshaw: but please, for the sake of the MS devs, don't raise a support issue against "debug mshtml.dll running on free Windows". Load the debug file on a debug version of Windows first and see if it reproduces.

  13. mh says:

    I'm pretty sure that debug DLLs are not redistributable.  Although (I hope) @Me was joking, we can be virtually certain that someone somewhere is seriously thinking the same thing.

  14. dirk gently says:

    [If you're trying to debug a problem, you can look at the return value to give you a clue as to what is going on. But you shouldn't have business logic depend on it. -Raymond]

    You mean, provided that you know what the implementation of AddRef that you're using is? because I don't get how looking at the value returned by "return 0;" can give you any clue about anything, other than that the function actually returns.

    [I said it was a clue, not a guaranteed solution. Sometimes, clues are not helpful. -Raymond]

Comments are closed.

Skip to main content