2012-03-28 15 views
21

Durante il mio lavoro ho affrontato regolarmente errori di programmazione piuttosto comuni, utilizzando alcuni oggetti che sono già stati liberati. Questo richiama UB in C++. Su linux, questo tipo di problemi viene in genere risolto utilizzando lo strumento Valgrind Memcheck. Da Memcheck manual:C'è Valgrind Memcheck come strumento per Windows per eseguire il debug di utilizzo dopo errori gratuiti?

MemCheck cerca di stabilire quale sia l'indirizzo illegale potrebbe riguardare, dato che è spesso utile. Quindi, se punta a un blocco di memoria che è già stato liberato, sarai informato di questo, e anche dove il blocco è stato liberato.

Memcheck fornisce lo stack di chiamate, in cui l'oggetto è stato deallocato e posso andare avanti ed eseguire il debug del problema. C'è uno strumento simile per windows con la stessa funzionalità, preferibilmente gratuito?

+0

Ho avuto fortuna con Purify in passato ma non è sicuramente gratuito. –

+2

http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows – stanwise

+0

Se sei interessato a una risposta solo per C, ne ho uno. –

risposta

4

In base alla documentazione del Dr. Memory, è disponibile l'opzione -delay_frees_stack con esattamente la stessa funzionalità di Valgrind.Da Option Reference:

-delay_frees_stack 
default: false 
Record callstacks on free to use when reporting use-after-free or other errors that overlap with freed objects. There is a slight performance hit incurred by this feature for malloc-intensive applications. 

Anche qui è un esempio di error reported by Dr. Memory:

Here is another example, using the -delay_frees_stack option to obtain the callstack of the freed memory: 

Error #8: UNADDRESSABLE ACCESS: reading 0x001338a8-0x001338ac 4 byte(s) 
# 0 unaddr_test1     [e:\derek\drmemory\git\src\tests\suppress.c:110] 
# 1 test       [e:\derek\drmemory\git\src\tests\suppress.c:269] 
# 2 main       [e:\derek\drmemory\git\src\tests\suppress.c:297] 
Note: @0:00:02.141 in thread 3024 
Note: next higher malloc: 0x001338e8-0x00133938 
Note: prev lower malloc: 0x001337e8-0x00133820 
Note: 0x001338a8-0x001338ac overlaps memory 0x001338a8-0x001338c4 that was freed here: 
Note: # 0 test       [e:\derek\drmemory\git\src\tests\suppress.c:269] 
Note: # 1 main       [e:\derek\drmemory\git\src\tests\suppress.c:297] 
Note: instruction: mov (%eax) -> %eax 
17

Come Lailin Chen ha sottolineato nella sua risposta alla domanda this provare uno di questi:

Dr. Memoria: https://github.com/dynamorio/drmemory

UMDH: http://support.microsoft.com/kb/268343

AppVerifier: http://msdn.microsoft.com/en-us/library/dd371695%28v=vs.85%29.aspx

+0

Ho provato AppVerifier, non dice dove è stato deallocato l'oggetto. – ks1322

+1

Application Verifier dovrebbe rilevarlo con protezione completa della memoria. Quando si libera l'oggetto, protegge le pagine deallocate, con il risultato di future operazioni su di esso generando un'eccezione. –

+0

AppVerifier è crap, quando si esegue un programma con esso si attiva un punto di interruzione nel codice TBB intel ... programma crappy, ma idk forse va bene se si disabilita tale controllo – NoSenseEtAl

5

The method that worked for me è stato quello di scrivi un gestore di memoria personalizzato che fornisce agli operatori globali "nuovi" e "cancella" e blocca tutti i blocchi di memoria liberati/usati con VirtualProtect. In questo modo qualsiasi tentativo di utilizzare la memoria liberata attiverà immediatamente la violazione di accesso che è possibile catturare ed eseguire il debug. Tuttavia, per essere in grado di fare ciò, devi "afferrare" tutta la memoria disponibile (o 3/4 di essa) usando qualcosa come VirtualAlloc e ogni blocco di memoria che ritorni (da questo blocco inizialmente assegnato) deve essere allineato PAGE_SIZE (vedi documentazione GetSystemInfo), altrimenti non sarai in grado di bloccarlo in modo affidabile. Ciò significa che anche un'applicazione banale potrebbe richiedere una grande quantità di memoria per utilizzare questo metodo.

Per quanto riguarda "valgrind alternative for windows", non ne ho sentito parlare. Qualcuno da qualche parte ha scritto che potrebbe essere possibile compilare/usare valgrind con cygwin, ma non so se questo è vero o no.

4

Ecco un tentativo Valgring coraggioso, e Auguro loro il meglio:

http://sourceforge.net/p/valgrind4win/wiki/Home/

temo, però, che al fine di attuare un "Valgrind per Windows" corretta, l'accesso al codice sorgente di Windows è obbligatorio.

IOW: Quando i maiali volano.

+0

Perché sarebbe necessario l'accesso al codice sorgente di Windows? – Jeff

3

quello che ha funzionato meglio per me stavo usando Visual leak Detector, tutto quello che dovevo fare era di includere:

#include <vld.h> 

all'inizio degli eseguibili volevo testare. Quindi eseguire un eseguibile di debug da Windows, fornirebbe informazioni dettagliate su tutta la memoria trapelata. Dall'output è possibile ottenere direttamente la riga in cui è stata allocata la memoria, quindi è possibile fare attenzione

Problemi correlati