2009-07-25 15 views
15

Ragazzi, si può raccomandare uno strumento per individuare un danneggiamento della memoria su un server multithreaded di produzione creato con C++ e funzionante con linux x86_64? Attualmente sto affrontando il seguente problema: ogni ora il mio server si blocca con un segfault e il core dump mostra che l'errore si verifica in malloc/calloc che è sicuramente un segno di memoria corrotta da qualche parte.Tracciamento della memoria danneggiata su un server Linux di produzione

In realtà ho già provato alcuni strumenti senza molta fortuna. Ecco la mia esperienza finora:

  • Valgrind è un grande (mi piacerebbe anche dire migliore) strumento, ma rallenta il server di troppo che lo rende inutilizzabile in produzione. L'ho provato su un server stage e mi ha davvero aiutato a trovare alcuni problemi relativi alla memoria, ma anche dopo averli risolti ho ancora degli arresti anomali sul server di produzione. Ho eseguito il mio stage server sotto Valgrind per diverse ore ma non sono riuscito a individuare errori gravi.

  • Si dice che ElectricFence sia un vero e proprio mago della memoria, ma non riuscivo nemmeno a farlo funzionare correttamente. Segfaults quasi immediatamente sul server del palcoscenico in luoghi strani e casuali in cui Valgrind non mostrava alcun problema. Forse ElectricFence non supporta il threading bene? .. Non ne ho idea.

  • DUMA - stessa storia di ElectricFence ma anche peggio. Mentre EF produceva core dump con backtrace leggibili DUMA mi mostra solo "?????" (e sì server è costruito con -g flag di sicuro)

  • dmalloc - Ho configurato il server per usarlo al posto di malloc standard routine tuttavia si blocca dopo diversi minuti. . Collegamento di un gdb al processo rivela che è appeso da qualche parte nel dmalloc :(

sto gradualmente ricevendo pazzo e semplicemente non so che cosa fare dopo che ho i seguenti strumenti per essere processato: mtrace, mpatrol ma forse qualcuno ha un'idea migliore

apprezzerei molto di aiuto su questa edizione

Update:?.. sono riuscito a trovare la fonte del bug Tuttavia ho trovato sul server palco non uno di produzione usando helgrind/DRD/tsan - c'era un datarace tra diversi thread che portava alla memoria corrotta ionico. La chiave era usare le appropriate soppressioni valgrind poiché questi strumenti mostravano troppi falsi positivi. Ancora non so davvero come questo può essere scoperto sul server di produzione senza rallentamenti significativi ...

+1

Hai compilato libefence in o usa la variabile env LD_PRELOAD? electricfence è thread safe presumibilmente se è compilato con -DUSE_SEMAPHORE –

+0

Sto usando libefense.a not .so. E non l'ho compilato da solo, l'ho installato usando emerge su Gentoo. Consiglieresti di installarlo manualmente invece con questo flag? – pachanga

+2

Una cosa che potrebbe aiutare è guardare +/- 200 byte di dove l'errore seg ha detto che i dati sono corrotti. Osservando i dati potresti essere in grado di avere un'idea di cosa sta causando il danneggiamento della memoria. – steve

risposta

4

Gente, sono riuscito a trovare la fonte del bug. Comunque l'ho trovato sul server stage usando helgrind/DRD/tsan - c'era un datarace tra diversi thread che portava alla corruzione della memoria. La chiave era usare soppressioni valgrind in quanto questi strumenti mostravano troppi falsi positivi. Ancora non so come questo possa essere scoperto sul server di produzione senza rallentamenti significativi ...

1

si può provare IBM purificare, ma temo che non è opensource ..

+0

Beh, se nient'altro funziona ... Ma credo ancora che ci dovrebbe essere una soluzione OpenSource a questo. – pachanga

+0

Anche purificare rallenta notevolmente l'applicazione e non può essere utilizzata su una macchina di produzione. – steve

7

Sì, C I problemi di corruzione della memoria in C++ sono difficili. Ho anche usato più volte valgrind, a volte ha rivelato il problema e talvolta no.

Mentre l'esame dell'uscita valgrind non tende a ignorare il suo risultato troppo velocemente. A volte, dopo un considerevole periodo di tempo trascorso, vedrai che Valgrind ti ha dato l'indizio sul primo posto, ma tu l'hai ignorato.

Un altro consiglio è di confrontare le modifiche al codice rispetto al rilascio stabile precedentemente noto. Non è un problema se si utilizza una sorta di sistema di controllo delle versioni di origine (ad esempio svn). Esamina tutte le funzioni relative alla memoria (ad esempio memcpy, memset, sprintf, new, delete/delete []).

+1

+1 per ignorare valgrind che colpisce indietro – LiraNuna

+0

Come per esaminare tutte le funzioni relative alla memoria - Non li uso direttamente da nessuna parte, tutti i puntatori sono shared_ptrs o weak_ptrs e tutti i contenitori provengono da ... – pachanga

+1

STL è buono ma anche con STL voi può incorrere in problemi di corruzione della memoria, ad esempio perché utilizzare iteratore invalidato. Vedi http://www.angelikalanger.com/Conferences/Slides/CppInvalidIterators-DevConnections-2002.pdf – dimba

1

Google Perftools --- che è Open Source --- può essere di aiuto, vedere la documentazione heap checker.

+0

Grazie, provo adesso – pachanga

+0

Sfortunatamente il controllo heap è abbastanza limitato, può rilevare solo perdite di memoria e non sovraccarichi di memoria. Non è stato possibile rilevare anche la mancata corrispondenza di nuovo []/delete :( – pachanga

6

Compila il tuo programma con gcc 4.1 e l'interruttore -fstack-protector-all. Se il danneggiamento della memoria è causato dallo stacking, questo dovrebbe essere in grado di rilevarlo. Potrebbe essere necessario giocare con alcuni dei parametri aggiuntivi di SSP.

3

Hai provato -fmudflap? (scorrere su alcune righe per vedere le opzioni disponibili).

+0

Grazie, ho trovato anche questo link http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging – pachanga

+0

Attualmente sto facendo un po 'di "errore: mudflap non può tracciare la dimensione sconosciuta extern errori "__prime_list" ": Qualche idea sul motivo per cui possono accadere? Non ho il simbolo __prime_list in nessuna parte del codice ... – pachanga

+0

Si basa su libmudflap per essere installato. Forse non lo è? – supercheetah

1

Prova questo: http://www.hexco.de/rmdebug/ ho usato estensivamente, la sua ha un basso impatto nelle prestazioni (per lo più impatti quantità di RAM), ma l'algoritmo di allocazione è lo stesso. È sempre stato abbastanza provato da trovare eventuali bug di allocazione. Il tuo programma si bloccherà non appena si verifica il bug, e avrà un registro dettagliato.

+0

Grazie, I ' Lo daremo un'occhiata.Mi chiedo se funziona bene in un'app multithreading in C++ ... – pachanga

+0

Sì, il threading non dovrebbe avere alcun impatto – daniel

1

Non sono sicuro che avrebbe colto il tuo particolare bug, ma la variabile di ambiente MALLOC_CHECK_ (malloc man page) gira su ulteriori controlli nell'implementazione Linux malloc predefinita e in genere non ha un costo di runtime significativo.

+0

Grazie, l'ho provato anch'io (MALLOC_CHECK_ = 3), tuttavia, non ha mostrato alcuna mia fonte di memoria corruzione da quando (come ho scritto prima) la memoria è stata corrotta dal datarace non dall'uso improprio di malloc/free ... – pachanga