2009-11-17 12 views
5

Ho una perdita di handle in un vecchio programma di grandi dimensioni. Utilizzando sysinternals handle.exe ho dedotto che il tipo di handle che perde è un handle "Event". Ma non sono sicuro di quali parti del mio codice dovrei guardare. Esiste una lista di funzioni che restituiscono gli handle agli eventi?Che cos'è un handle di evento?

MODIFICA: Non esiste una singola istanza di CreateEvent, CreateEventEx o OpenEvent nell'intero programma.

risposta

2

Quante di queste maniglie trapelate vedete?

Gli eventi vengono creati implicitamente da sezioni critiche (vedere InitializeCriticalSection et.al.) e, probabilmente, alcuni altri elementi di Win32 che non riesco a ricordare al momento. Inoltre, possono essere creati dal framework che si sta utilizzando (se presente) come MFC o dalle librerie che si stanno utilizzando.

Per rintracciare la perdita, è possibile utilizzare un punto di interruzione di sola stampa. Passare alla funzione CreateEvent (utilizzando la vista dell'assieme) e inserire un punto di interruzione nella prima istruzione. Quindi fai clic con il pulsante destro del punto di interruzione, scegli 'Quando premi ...' e modifica le opzioni in modo che non si introducano nel debugger ma stamperà alcune informazioni utili (ad esempio, vedi la macro $ CALLER). Quindi esegui la tua app ... e preparati a vedere un registro ENORME. Se c'è una vera perdita, vedrai uno schema ripetuto nel registro, che identifica l'autore del reato.

+0

Dopo la tempesta iniziale, il programma si assesta fino a creare circa uno o due al secondo. - questa risposta sembra molto fattibile, ma non posso provarlo fino a domani. Saluti. – Mick

0

Per quanto ne so, quasi le uniche cose che creano un evento sono CreateEvent e CreateEventEx. Molte altre funzioni possono restituire un handle a un evento (ad esempio WaitForMultipleObjects) ma è un handle precedentemente creato e passato ad esso.

Modifica: Poiché il codice in apparenza non sta creando direttamente l'evento, è possibile voglio iniziare usando le deviazioni per esaminare le chiamate a CreateEvent (Ex) e tracciare di nuovo lo stack per vedere quale parte del codice sta causando la loro creazione, e cosa sta chiamando che le sta creando.

1

Come altre persone hanno menzionato, CreateEvent/CreateEventEx vengono utilizzati per creare handle "Event". Questi rappresentano oggetti di sincronizzazione che vengono frequentemente usati per accedere al gate, fornire segnali (potenzialmente) ad altri thread e possono anche essere usati come base per i lock.

Se si sta tentando di eseguire il debug di una perdita che coinvolge gli handle di evento, si dovrebbe cercare di cercare i luoghi in cui CreateEvent (Ex) viene chiamato senza un corrispondente CloseHandle(). A seconda di quali framework hai utilizzato per ottenere gli eventi, potresti anche scoprire che potresti semplicemente mancarli alla pulizia se sono membri di un altro oggetto/struttura (ad esempio qualcosa che ha una variabile membro HANDLE generica che viene saltata alla pulizia, o un puntatore a una MANIGLIA, ecc.).

Se non si ricorda di aver creato questi oggetti nel proprio codice, è possibile che manchi un analogo metodo Close() o altro metodo di pulizia su un'altra classe o provider che li utilizza internamente. Le cose che fanno l'elaborazione in background, la segnalazione, o forniscono metodi per attendere che le operazioni finiscano sono i soliti sospetti qui.

Crea evento Maniglie
CreateEvent Function @ MSDN
CreateEventEx Function @ MSDN

Cleanup Maniglie
CloseHandle Function @ MSDN

1

Se non sai cosa DLL o componenti di terze parti stanno chiamando CreateEvent o CreateEventEx quindi utilizzare il Dependency Walker per vedere cosa importa ogni DLL:

http://www.dependencywalker.com/ (è gratuito)

Questo aiuterà almeno a restringere il problema a un particolare insieme di interazioni - quindi dovrai controllare tutte le chiamate a quella libreria e controllare che tutto sia pulito correttamente.

1

Anche se non si creano eventi direttamente, il sistema operativo o altro codice di libreria certamente possono e lo saranno. Potresti voler considerare la possibilità che ci siano altre risorse che la tua applicazione sta aprendo/creando che non viene ripulita.È possibile che tu stia davvero perdendo qualcos'altro, ma quella cosa sta portando un oggetto evento per la corsa.

Potrebbe essere utile impostare un punto di interruzione del debugger su CreateEvent (e amici), per vedere cosa lo sta creando, ma non sarei sorpreso se ciò si verifica abbastanza spesso che il problema si perde nel rumore.