5

I'm writing a Direct3D 10 application and want to make sure I don't have COM objects leaking.

Yes, I am wrapping the interfaces with CComPtr, but I'd like a leak check anyway for the same reason I still use an ordinary heap allocation leak detector even though RAII and smart pointers guarantees there will be no leaks: sometimes (especially when interfacing to a C library like Direct3D) you have to fallback to lower levels of abstraction and use raw pointers, new, delete, and you make mistakes. (Not to mention some calls to Release() don't return 0 at the end of the program)

I've #defined _ATL_DEBUG_INTERFACES before I include atlbase.h but nothing appears in the output window! Is there something else I need to do to get _ATL_DEBUG_INTERFACES to work?

Jeff Linahan
  • 3,775
  • 5
  • 37
  • 56
  • I'd don't know a COM related solution, but for Direct3D you could use the Debug Version; as far as I can recall, this will tell you about memory leaks in the output windows. – JPW Aug 18 '11 at 17:05
  • while it does report memory leaks for regular heap allocated memory in debug mode, it doesn't report leaked COM objects if I make them leak – Jeff Linahan Aug 18 '11 at 23:34
  • I'm not sure whether we are talking about the same thing here. See http://msdn.microsoft.com/en-us/library/ee416791(v=vs.85).aspx If I switch to the Direct3D 9 Debug Version there (it's propbably more complicated for the newer versions) I get a lot of infomation about unfreed Direct3D memory. – JPW Aug 19 '11 at 09:43
  • yeah, sorry I should have said I was using DirectX 10 – Jeff Linahan Aug 19 '11 at 23:27
  • It seems as Direct3D 10's debug layer does not support reporting ref count errors, while Direct3D 9 and 11 both have this features; maybe PIX http://msdn.microsoft.com/en-us/library/ee417062(v=VS.85).aspx can help – JPW Aug 20 '11 at 15:13
  • hm really? Where did do find that D3D10 does not report ref count errors? – Jeff Linahan Aug 21 '11 at 05:32
  • Unfortunately I can't find an "official" source, the best I could find is http://forums.create.msdn.com/forums/t/38879.aspx , futhermore VS did report a leaking D3D device in a simple test program for DX 9 and 11 but not for 10 – JPW Aug 21 '11 at 17:59
  • You might want to set a DirectX or Direct3D tag as well on the post if you are ok with an DX only solution – JPW Aug 21 '11 at 18:01
  • `_ATL_DEBUG_INTERFACES` is for when you're compiling COM servers, it won't work for objects you use as a client. Calling `DllCanUnloadNow` on the server .dll will tell you yes/no (`S_OK`/`S_FALSE`). – Kevin Smyth Sep 20 '12 at 16:41

1 Answers1

4

If you're using CComPtr then that's generally the main thing I'd advise, but I did find something that might help, if you're using Visual Studio.

Sara Fords blog has a really cool tip:

Debugging AddRef/Release issues in VS

You might get a lot of information logged, but the basic idea is to trace your addref/release calls in Visual Studio and you can look for mismatched pairs of AddRef/Release.

Might be a bit of legwork but it looks like quite a cunning idea.

Edit 2: Good morning;

Ok, if you're not using DllGetClassObject then that's not going to be a reference problem. Using IUknowns as in/out parameters does have a caveat though; This is the blurb from MSDN for AddRef:

Call this method for every new copy of an interface pointer that you make. For example, if you are passing a copy of a pointer back from a method, you must call AddRef on that pointer. You must also call AddRef on a pointer before passing it as an in-out parameter to a method; the method will call IUnknown::Release before copying the out-value on top of it.

Similarly for release:

Call this method when you no longer need to use an interface pointer. If you are writing a method that takes an in-out parameter, call Release on the pointer you are passing in before copying the out-value on top of it.

Russ Clarke
  • 17,511
  • 4
  • 41
  • 45
  • seems clever, but I was hoping for something that is silent when everything is going fine and only prints debug info if there are interfaces still alive when the program exits. Will give it a try though. – Jeff Linahan Aug 19 '11 at 23:35
  • What about implementing your own CComPtr does that, or are you concerned that there are ways of using AddRef that don't get wrapped by the smart type ? – Russ Clarke Aug 19 '11 at 23:39
  • I'm concerned that there are AddRefs being called that aren't explicitly visible in my program, because when I take a COM object that is only created once at the beginning of the program and is destroyed at the end (like the d3d device), the return value of Release is something like 5, but should be 0. – Jeff Linahan Aug 19 '11 at 23:46
  • Are you using DllGetClassObject anywhere or using any COM interfaces as in or out parameters ? – Russ Clarke Aug 20 '11 at 00:00
  • Another thing I've noted (but I'm trying to find clarification) is that the return values of AddRef and Release are only meant to be used for testing, because under certain conditions, they are unstable. (http://www.mybestnotes.com/com-dcom/addref-release-functions.php) – Russ Clarke Aug 20 '11 at 00:06
  • never heard of DIIGetClassObject. I pass things like the d3d device as an out parameter for initialization and as an in parameter to other methods – Jeff Linahan Aug 20 '11 at 03:44
  • I've read that on msdn but don't think that's the problem. Yes, I'm passing these interfaces around but not to any methods that use the parameter as both an input and output – Jeff Linahan Aug 21 '11 at 05:37
  • Sorry jnm2, this was nearly 5 years ago though. – Russ Clarke Jan 22 '16 at 00:32
  • `Debugging AddRef/Release issues in VS` dead link. unable to find the blog on wayback machine – Sahil Singh Dec 08 '21 at 07:18