views:

264

answers:

6

I have a handle leak in a big old program. Using sysinternals handle.exe I deduced that the type of handle that is leaking is an "Event" handle. But I'm not sure what parts of my code I should be looking at. Is there a list somewhere of functions that return handles to events?

EDIT: There is not a single instance of CreateEvent, CreateEventEx or OpenEvent in the entire program.

A: 

As far as I know, nearly the only things that create an event are CreateEvent and CreateEventEx. Quite a few other functions can return a handle to an event (e.g. WaitForMultipleObjects) but it's a handle that you previously created and passed to it..

Edit: Since your code apparently isn't creating the event's directly, you might want to start by using detours to look at calls to CreateEvent(Ex), and trace back the stack to see what part of your code is causing them to be created, and what it's calling that is creating them.

Jerry Coffin
See edit to question
Mick
A: 

The following link should get you started: http://msdn.microsoft.com/en-us/library/ms682655%28VS.85%29.aspx

CreateEvent and CreateEventEx will create events and return handles to them.

Matt Breckon
See edit to question
Mick
+1  A: 

As other people have mentioned, CreateEvent / CreateEventEx are used to create "Event" handles. These represent synchronization objects that are frequently used to gate access, provide signals (potentially) to other threads, and may also be used as the basis for locks.

If you're trying to debug a leak involving Event handles, you should try to look for places where CreateEvent(Ex) is called without a corresponding CloseHandle(). Depending on what frameworks you used to obtain Events, you may also find that you might just be missing them on cleanup if they are members of another object/structure (Ex. something that has a generic HANDLE member variable that is skipped on cleanup, or a pointer to a HANDLE, etc).

If you don't recall having created these objects in your own code, it is possible you are missing a analogous Close() or other cleanup method on another class or provider that uses them internally. Things that do background processing, signaling, or provide methods to wait for operations to finish are the usual suspects here.

Create Event Handles
CreateEvent Function @ MSDN
CreateEventEx Function @ MSDN

Cleanup Handles
CloseHandle Function @ MSDN

meklarian
+1  A: 

If you don't know what DLLs or third party components are calling CreateEvent or CreateEventEx then use the Dependency Walker to see what each DLL imports:

http://www.dependencywalker.com/ (it is free)

That will at least help to narrow down the problem to a particular set of interactions - then you'll need to look at all the calls to that library and check that everything is cleaned up correctly.

Matt Breckon
+1  A: 

Even if you don't create Events yourself directly, the OS or other library code certainly can and will. You might want to look at the possibility that there's some other resource your application is opening/creating that's not being cleaned up. It's possible that you're really leaking something else, but that thing is bringing an event object along for the ride.

It might help to set a debugger breakpoint on CreateEvent (and friends), to see what's creating it, but I wouldn't be surprised if that occurs often enough that your problem gets lost in the noise.

Michael Burr
+2  A: 

How much of these leaked handles do you see?

Events are created implicitly by critical sections (see InitializeCriticalSection et.al.) and, probably, some other Win32 elements which I can't remember at the moment. Also, they can be created by the framework you are using (if any) such as MFC, or by libraries you are using.

To track down the leak, you can use a print-only breakpoint. Step into CreateEvent function (using assembly view) and put a breakpoint on its first instruction. Then right-click the breakpoint, choose 'When Hit...' and edit the options so it won't break into debugger but will print some useful information (e.g. see $CALLER macro). Then run your app... and be prepared to see a HUGE log. If there is a true leak, you'll see a repeating pattern in the log, which identifies the offender.

atzz
After the initial flurry, the program settles down to creating about one or two per second. - this answer sounds very doable, but I can't try it out till tomorrow. Cheers.
Mick