Closed
Bug 16762
Opened 25 years ago
Closed 6 years ago
delete <interface pointer>
Categories
(Developer Infrastructure :: Source Code Analysis, defect)
Developer Infrastructure
Source Code Analysis
Tracking
(Not tracked)
RESOLVED
DUPLICATE
of bug 1181412
People
(Reporter: hjtoi-bugzilla, Unassigned)
Details
Attachments
(3 files)
24.57 KB,
patch
|
Details | Diff | Splinter Review | |
17.10 KB,
patch
|
Details | Diff | Splinter Review | |
1.51 KB,
text/plain
|
Details |
Because nsISupports and other interfaces do not have virtual destructors, using operator delete on an interface pointer can cause resource leaks. Typical pattern: nsISupports *inst = new Foo; : delete inst; LXR shows many instances of these if you seach for 'delete inst'. You can catch more by adding protected: ~nsISupports() {} to nsISupports interface. Best way might be to add private operator delete to nsISupports, but because people have introduced their own operator deletes this might be tricky. See http://www.develop.com/dbox/cxx/InterfacePtr.htm http://www.develop.com/dbox/cxx/SmartPtr.htm for more details. This can be fixed by a) Not using nsISupports above, i.e. it becomes nsFoo *inst = new Foo; : delete inst; which is safe. b) Avoid delete, use AddRef and Release instead. nsISupports *inst = new Foo; : NS_ADDREF(inst); nsresult rv = inst->QueryInterafce(...); NS_RELEASE(inst);
Reporter | ||
Comment 1•25 years ago
|
||
I have fixed most of these for Win. I am creating patch, but the network seems to be really slow...
Updated•25 years ago
|
Status: NEW → ASSIGNED
Comment 2•25 years ago
|
||
Thanks heikki.
Updated•25 years ago
|
Target Milestone: M16
Comment 3•25 years ago
|
||
If you send me a patch, I will fix it sooner.
Reporter | ||
Comment 4•25 years ago
|
||
Reporter | ||
Comment 5•25 years ago
|
||
I posted some explanation of the patch in n.p.m.patch.
Reporter | ||
Comment 6•25 years ago
|
||
By the way, this AddRef/Release trick can be achieved with nsCOMPtr as well: nsCOMPtr<nsISupports> inst; inst = new Foo; // AddRef called inst->QueryInterface(...) } // Release called
Comment 7•25 years ago
|
||
Right. shaver posted that too. COMPtr, if it can be used is the best implementation. but since most are doing something like new MyObject() using a comptr is like casting this right. I guess that is ok since this is the only time we can really cast at all. We know the object and who its base classes are.
Updated•25 years ago
|
Target Milestone: M16 → M11
Comment 8•25 years ago
|
||
I am compiling with your patch on unix. There seems to be unix specific files that I need to fix. That is causing a lot of good cleanup of factories to happen. After that I need to get this compiling on the mac too. Scott can you help me out with this.
Comment 9•25 years ago
|
||
One thing I'm concerned about, though, is that the code pattern in the bug is not type-correct. If the |nsISupports| that a |Foo| would return is not the same one that C++ implicitly casts to, then |nsCOMPtr| asserts after the assignment. It is easier to use the most derived interface, to get the right thing, e.g., // given class nsFooImpl : public nsIFoo, public nsIBar, ... { ... } // use... { nsCOMPtr<nsIFoo> foo = new nsFooImpl; // there's only one |nsIFoo| in a |nsFooImpl|, so no ambiguity // and prefer construction to construction+assignment nsresult rv = foo->QueryInterface(...); }
Comment 10•25 years ago
|
||
OK, unfortunately, the trick of making a potected destructor only makes a warning on the Mac, it doesn't stop the build. Same for a protected operator delete. A private destructor or operator delete make it impossible to build at all, because it denies even legal usage. I'll have to search through the warnings with a script. This is a compiler bug that needs to be reported to Metrowerks.
Reporter | ||
Comment 11•25 years ago
|
||
I realized nsCOMPtr probably should not be used in situations like this. Take a closer look at what happens on line: inst = new Foo; // AddRef called 1) new object is created 2) QueryInterface is called Now you see the problem: if QI fails, we leak.
Comment 12•25 years ago
|
||
|QueryInterface()| is not called implicitly by |nsCOMPtr|. In your example, | QueryInterface| is not called at all. To make |QueryInterface| be called, you must explicitly ask for it, e.g., inst = do_QueryInterface( new Foo ); which we all knew not to ask for. That's one of the reasons in my example I asked for a thing which I knew C++ could cast to _without_ needing a QI to get it right. It's OK not to use |nsCOMPtr| here if you don't want to, but I wanted to clear up the notion that it is automatically calling |QueryInterface|. It is not.
Comment 13•25 years ago
|
||
I have checked in the Mac specific fixes. The tree is clean, for the moment, with respect to this bug, for as well as we can detect it. We would probably find more if we instrumented XPIDL to (for this purpose only) add empty protected destructors to _every_ interface class. I'll try that and see what I get.
Reporter | ||
Comment 14•25 years ago
|
||
scc, could you please check again that: inst = new nsFoo; does not call QI, because when I tested it it DID call QI...
Updated•25 years ago
|
Status: ASSIGNED → RESOLVED
Closed: 25 years ago
Resolution: --- → FIXED
Comment 15•25 years ago
|
||
Plus I am going to mark this one closed. Once in a while we can go do this exercise. Plus people copy code. If we eliminate all code that they copy from, we just eliminated the possibility of this creeping in too. So let us not spend more time on this. Thanks scc and heikki. A lot more people will benefit from your QI being called if that was in a newsgroup.
Reporter | ||
Comment 16•25 years ago
|
||
scc replied in private email so I am just going to put this for all to see: The QI I saw happens only in DEBUG builds and the assignment is still safe. So you can use the nsCOMPtr way to fix these bugs.
Reporter | ||
Comment 17•25 years ago
|
||
I suggest we move the milestone of this bug forward, and should actually keep it open as some other reminder bugs. After all, there is nothing preventing anyone from making more of these mistakes. scc, did you instrument xpidl to catch these? If we introduced some debug flag to XPIDL and set up a separate tinderbox machine building with this flag we woul d be much better off. Still that would not solve the whole problem, because not all interfaces have been specified in XPIDL. I guess some special tool to add the protected destructor to all classes specified in files in dist/include and a new build (can you do this without overwriting the include dir?) would be needed to catch all cases. I am trying to find time to take a second round of this to see if we have introduced any new instances of this bug.
Reporter | ||
Comment 18•25 years ago
|
||
Reopened bug and cleared milestone. I hacked the xpidl compiler to emit protected destructor and tried to compile. As you can guess, it failed. I will create a patch for Win NT.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Target Milestone: M11
Comment 19•25 years ago
|
||
Scc is a better owner for this bug.
Assignee: dp → scc
Status: REOPENED → NEW
Updated•25 years ago
|
Status: NEW → ASSIGNED
Reporter | ||
Comment 20•25 years ago
|
||
Reporter | ||
Comment 21•25 years ago
|
||
Updated•24 years ago
|
Target Milestone: M16
Comment 22•24 years ago
|
||
Don't know if this is possible, but this is another good thing to look for with the [XP]COM lint script (tell me what the real name is going to be).
Target Milestone: M16 → M20
Comment 23•24 years ago
|
||
mass re-assigning to my new bugzilla account
Assignee: scc → scc
Status: ASSIGNED → NEW
Updated•24 years ago
|
Status: NEW → ASSIGNED
Comment 24•24 years ago
|
||
dp is no longer @netscape.com. changing qa contact to default for this product
QA Contact: dp → kandrot
Comment 25•20 years ago
|
||
Heikki, I saw you created 2 extra fixes, but I noticed action on this bug stopped pretty soon afterwards. Do you know if your patches were applied into the code? Is this problem still available?
Updated•18 years ago
|
QA Contact: kandrot → scc
Updated•18 years ago
|
Assignee: scc → nobody
Status: ASSIGNED → NEW
QA Contact: scc → xpcom
Updated•15 years ago
|
Component: XPCOM → Rewriting and Analysis
Priority: P3 → --
QA Contact: xpcom → rewriting-and-analysis
Comment 26•15 years ago
|
||
I think we could do this with static analysis as a destructor which may only be called from a subclass destructor.
Updated•6 years ago
|
Product: Core → Firefox Build System
Comment 27•6 years ago
|
||
I built with a protected: ~nsISupports() {} successfully. Does that imply this is fixed?
Flags: needinfo?(nika)
Comment 28•6 years ago
|
||
This is bug 1181412 I think - closing as dup.
Status: NEW → RESOLVED
Closed: 25 years ago → 6 years ago
Flags: needinfo?(nika)
Resolution: --- → DUPLICATE
Updated•2 years ago
|
Product: Firefox Build System → Developer Infrastructure
You need to log in
before you can comment on or make changes to this bug.
Description
•