Closed Bug 26803 Opened 25 years ago Closed 25 years ago

RFE: GetRefCount() to return the ref. counter, in debug mode

Categories

(Core :: XPCOM, defect, P3)

x86
Windows 98
defect

Tracking

()

VERIFIED FIXED

People

(Reporter: rbs, Assigned: scc-obsolete)

Details

nsCOMPtr provides a powerful way to minimize the number of leaks in the system. However, there are still a lot of places in the code that need, or are still based on, the other forms of NS_RELEASE. This bug is a request for the addition of a new method, GetRefCount(), alongside AddRef() and Release(). The purpose of the method is simply to return the current value of the ref. counter, in view of facilitating fine-grain tracking and/or debug purposes. Although several tools have been developped to track leaks, it is often the case that sneaky leaks have to be fixed by inspection. The motivations of GetRefCount() are: * Accessibility of the ref. counter anywhere/everyhwere; * It can ease the task of exactly pinpointing where an object is leaked; * A developper who is about to drop or overwrite a pointer, can simply test the value of the ref. counter at that point; * Generally, a developper can test the ref. counter against a known expected value at any point. Because a method such as GetRefCount() is only relevant in debug, it can then be enclosed in #ifdef NS_DEBUG .. #endif Better, a macro can be made, and just like there is a .get(), there could also be .getRefCount() via nsCOMPtr.
That is going to be hard to fix. We cannot touch nsISupports interface in any way. That would change the layout of the most basic interface. So say some objects are compiled debug and some optimized; we would be in major pain if we do this. I would suggest WONTFIX.
This is actually really hard. It touches every XPCOM interface in the product, since every interface inherits from |nsISupports| where this method would be. It makes every interface method beyond |nsISupports| have a different index number in debug and non-debug builds, which wreaks havoc on the machinery that lets us call through from JS, and through proxies, etc., using method indexes. Not every object keeps track of its refcount in the same way, e.g., with the macro, or even in a member variable with the same name. Some don't even have a refcount, | AddRef()| and |Release()| are advisory only ... that's legal! There is a workaround for this, however. If you want to know the refcount of an object, you can get as close an answer as it will allow by saying obj->AddRef(); nsrefcnt count = obj->Release(); This could easily be turned into a global inline function, e.g., inline nsrefcnt GetRefCount( nsISupports* obj ) // Warning: don't apply this to an object whose refcount is // |0| or not yet initialized ... it may be destroyed { nsrefcnt ref_count = 0; if ( obj ) { obj->AddRef(); result = obj->Release(); } return ref_count; } How well would this suit your needs? If this works for you I can check it in ASAP; other alternatives are extremely unattractive. Does this work for you?
Status: NEW → ASSIGNED
s/result/ref_count/
...and of course, put it inside |#ifdef NS_DEBUG|...|#endif|
[Adding dp to the Cc list] Yes, the function works. But what will happen for objects which simply return NS_OK in their Release()? Or for objects which don't have a refcount as you pointed out before? Mindful of your previous reservations and the unfortunate fact that a mis-use of the function can cause a premature destruction of an object, it is perhaps best to leave things as they are...
The first time someone writes debug code for a non-conforming class, they'll notice it doesn't do the right thing and they'll fix it. The function will be documented, so it will be known that one shouldn't call it on an object just returned by |new|. You decide. If you want this function, I'll add it. If you don't, I'll close the bug.
OK, I like the function and you have cleared my fears!
Marking M15, though I'll get this in as soon as I have a free moment.
Target Milestone: M15
FIXED in version 1.54 of "nsISupportsUtils.h". The new function is called | NS_DebugGetRefCount()|. It is only available in debug builds. It asserts if it accidentally causes the destruction of the object in question. Have fun with it.
Status: ASSIGNED → RESOLVED
Closed: 25 years ago
Resolution: --- → FIXED
Thanks Scott. Saw the function that is shining at: http://lxr.mozilla.org/seamonkey/source/xpcom/base/nsISupportsUtils.h#248 Marking verified...
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.