Domanda

Ho un crash dump di un'applicazione che presumibilmente perde GDI. L'app è in esecuzione su XP e non ho problemi a caricarla in WinDbg per guardarla. In precedenza abbiamo utilizzato estensione Gdikdx.dll per esaminare le informazioni Gdi ma questa estensione non è supportata su XP o Vista.

Qualcuno ha qualche puntatore per trovare l'utilizzo degli oggetti GDI in WinDbg.

In alternativa, ho accesso al programma in errore (e alla sua suite di prove di stress), quindi posso riprodurlo su un sistema in esecuzione se si conoscono strumenti di debug "live" per XP e Vista (o Windows 2000, anche se non lo è il nostro obiettivo).

È stato utile?

Soluzione

C'era un un articolo di MSDN Magazine di diversi anni fa che parlato di perdite GDI. Questo indica diversi luoghi con buone informazioni.

In WinDbg, puoi anche provare il comando ! poolused per alcune informazioni.

Trovare perdite di risorse da un crash dump (post-mortem) può essere difficile - se era sempre lo stesso posto, usando la stessa variabile che perde la memoria, e sei fortunato, potresti vedere l'ultimo posto che sarà trapelato, ecc. Probabilmente sarebbe molto più facile con un programma live in esecuzione con il debugger.

Puoi anche provare a utilizzare Microsoft Detours , ma la licenza non funziona sempre su. È anche un po 'più invasivo e avanzato.

Altri suggerimenti

Ho trascorso l'ultima settimana a lavorare su uno strumento di ricerca delle perdite GDI. Eseguiamo anche test di stress regolari e non è mai durato più di un giorno senza fermarsi a causa del consumo eccessivo di gestione utente / oggetto gdi.

I miei tentativi hanno avuto un discreto successo, per quanto ne so. Certo, ho trascorso un po 'di tempo in anticipo alla ricerca di una soluzione alternativa e più rapida. Vale la pena ricordare che ho avuto una precedente esperienza semi-fortunata con lo strumento GDILeaks dall'articolo di msdn menzionato sopra. Per non parlare del fatto che ho dovuto risolvere alcuni problemi prima di metterlo in funzione e questa volta non mi ha dato cosa e come lo desideravo. L'aspetto negativo del loro approccio è l'interfaccia debugger dei pesi massimi (rallenta l'obiettivo ricercato di ordini di grandezza che ho trovato inaccettabile). Un altro aspetto negativo è che non ha funzionato tutto il tempo - su alcune esecuzioni semplicemente non sono riuscito a riportare / calcolare nulla! La sua complessità (a giudicare dalla quantità di codice) era un altro fattore di paura. Non sono un grande fan delle GUI, in quanto credo di essere più produttivo senza finestre; o). Ho anche trovato difficile trovare e usare i miei simboli.

Un altro strumento che ho usato prima di iniziare a scrivere il mio, era leakbrowser .

Ad ogni modo, ho finalmente optato per un approccio iterativo per raggiungere i seguenti obiettivi:

  • penalità di prestazione minori
  • semplicità di implementazione
  • non invasività (utilizzato per più prodotti)
  • basandosi sul più disponibile possibile

Ho usato deviazioni (uso non commerciale) per funzionalità di base (è una DLL iniettabile). Usa Javascript per la generazione automatica del codice (script da 15K a codice sorgente gen 100K - non posso codificarlo manualmente e non sono coinvolto un preprocessore C!) Più un'estensione windbg per l'analisi dei dati e il supporto di istantanee / diff.

Per raccontare la lunga storia - dopo che ho finito, sono state poche ore a raccogliere informazioni durante un altro stress test e un'altra ora per analizzare e correggere le perdite.

Sarò più che felice di condividere i miei risultati.

P.S. ho passato del tempo a cercare di migliorare il lavoro precedente. La mia intenzione era quella di ridurre al minimo i falsi positivi (ne ho visti quasi troppi durante lo sviluppo), quindi controllerà anche la coerenza di allocazione / rilascio ed eviterà di tenere conto delle allocazioni che non sono mai trapelate.

Modifica: trova lo strumento qui

Ho creato uno script Windbg per questo. Guarda la risposta di

Comando per ottenere GDI handle conta da una discarica di crash

Per tenere traccia dello stack di allocazione è possibile impostare un breakpoint ba (Break on Access) oltre l'ultimo oggetto GDICell allocato in modo che si interrompa proprio nel momento in cui si verifica un'altra allocazione GDI. Potrebbe essere un po 'complesso perché l'indirizzo cambia, ma potrebbe essere abbastanza per trovare praticamente qualsiasi perdita.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top