2009-07-25 16 views
15

Chicos, ¿podrían recomendar una herramienta para detectar una corrupción de memoria en un servidor multiproceso de producción creado con C++ y que funciona bajo Linux x86_64? Actualmente estoy enfrentando el siguiente problema: cada varias horas mi servidor se bloquea con un segfault y el volcado del núcleo muestra que el error ocurre en malloc/calloc, que es definitivamente un signo de que la memoria está corrupta en alguna parte.Corrupción de la corrupción de la información en un servidor de producción Linux

En realidad, ya he probado algunas herramientas sin mucha suerte. Aquí está mi experiencia hasta ahora:

  • Valgrind es un gran (incluso diría mejor) herramienta, sino que ralentiza el servidor demasiado lo que es inutilizable en la producción. Lo probé en un servidor de escenario y realmente me ayudó a encontrar algunos problemas relacionados con la memoria, pero incluso después de solucionarlos sigo teniendo bloqueos en el servidor de producción. Ejecuté mi servidor de escenario en Valgrind durante varias horas, pero aún no pude detectar ningún error grave.

  • Se dice que ElectricFence es una verdadera fuente de memoria, pero ni siquiera pude hacerlo funcionar correctamente. Se segfaults casi de inmediato en el servidor de escenario en lugares aleatorios al azar donde Valgrind no mostró ningún problema en absoluto. ¿Tal vez ElectricFence no admite el enhebrado? ... No tengo idea.

  • DUMA - la misma historia que ElectricFence pero aún peor. Mientras EF producía volcados centrales con backtraces legibles, DUMA solo me muestra "?????" (y sí, el servidor está construido con la bandera -g)

  • dmalloc - Configuré el servidor para usarlo en lugar del malloc estándar rutinas, sin embargo, se bloquea después de varios minutos. . Colocación de un GDB al proceso revela que está colgado en algún lugar de Dmalloc :(

Me estoy poniendo poco a poco loco y simplemente no saben qué hacer a continuación he las siguientes herramientas para ser juzgado: mtrace, mpatrol pero tal vez alguien tiene una idea mejor

le agradecería cualquier ayuda en este tema

actualización:?.. he conseguido encontrar la fuente del error sin embargo, me encontré en el servidor de etapa no producción uno usando helgrind/DRD/tsan - hubo una datarace entre varios hilos que resultó en memoria corrupta ion. La clave era usar supresiones de valgrind adecuadas ya que estas herramientas mostraban demasiados falsos positivos. Todavía no se sabe muy bien cómo esto puede ser descubierto en el servidor de producción sin ningún tipo de retrasos significativos ...

+1

¿Compiló libefence en o usó LD_PRELOAD env variable? ElectricFence es seguro para hilos supuestamente si se compila con -DUSE_SEMAPHORE –

+0

estoy usando libefense.a no .so. Y no lo compilé yo mismo, instalé usando emerge en Gentoo. ¿Recomendaría instalarlo manualmente con esta bandera? – pachanga

+2

Una cosa que podría ayudar es buscar +/- 200 bytes de donde la falla seg dijo que los datos estaban corruptos. Al observar los datos, es posible que pueda hacerse una idea de lo que está causando la corrupción de la memoria. – steve

Respuesta

4

Amigos, me las arreglé para encontrar la fuente del error. Sin embargo, lo encontré en el servidor de escenario usando helgrind/DRD/tsan - hubo una datarace entre varios hilos que resultó en corrupción de memoria. La clave era usar propia valgrind supresiones ya que estas herramientas mostraban demasiados falsos positivos. Todavía no sé realmente cómo se puede descubrir esto en el servidor de producción sin ninguna desaceleración significativa ...

1

puede intentar purificar IBM, pero me temo que no es de código abierto ..

+0

Bueno, si nada funciona ... Pero sigo creyendo que debería haber una solución OpenSource para esto. – pachanga

+0

Purificar también ralentiza considerablemente la aplicación y no se puede utilizar en una máquina de producción. – steve

7

Sí, C/Los problemas de corrupción de memoria C++ son difíciles. También utilicé varias veces valgrind, a veces reveló el problema y otras no.

Al examinar la salida de valgrind no tiende a ignorar su resultado demasiado rápido. A veces, después de un tiempo considerable, verás que valgrind te dio la pista desde el principio, pero la ignoró.

Otro consejo es comparar los cambios de código de la versión estable previamente conocida. No es un problema si usa algún tipo de sistema de control de versiones de origen (por ejemplo, svn). Examine todas las funciones relacionadas con la memoria (por ejemplo, memcpy, memset, sprintf, new, delete/delete []).

+1

1 por ignorar valgrind devolver el golpe – LiraNuna

+0

En cuanto a examinar todas las funciones relacionadas con la memoria - No uso directamente en cualquier lugar, todos los punteros son shared_ptrs o weak_ptrs y todos los contenedores son de STL ... – pachanga

+1

STL es buena, pero aún con AWL se puede encontrarse con un problema de corrupción de memoria, por ejemplo, por qué usar el iterador invalidado. Ver http://www.angelikalanger.com/Conferences/Slides/CppInvalidIterators-DevConnections-2002.pdf – dimba

1

Google Perftools --- que es de código abierto --- puede ser de ayuda, consulte la documentación heap checker.

+0

Gracias, voy a probarlo ahora mismo – pachanga

+0

Desafortunadamente, el corrector de montones es bastante limitado, solo puede detectar fugas de memoria y no excesos de memoria. Ni siquiera podía detectar el desajuste nuevo []/delete :( – pachanga

6

compilar el programa con gcc 4.1 y el -fstack-protector-todos los conmutadores. Si la corrupción de la memoria es causada por la destrucción de la pila, esto debería poder detectarlo. Es posible que necesite jugar con algunos de los parámetros adicionales de SSP.

3

¿Has probado -fmudflap? (desplácese hacia arriba unas pocas líneas para ver las opciones disponibles).

+0

Gracias, también encontré este enlace http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging – pachanga

+0

Actualmente estoy documentando con el "error: mudflap no puede rastrear el tamaño desconocido externo '__prime_list' "errors :(¿Alguna idea de por qué pueden suceder? No tengo el símbolo __prime_list en ningún lugar del código ... – pachanga

+0

No se necesita instalar libmudflap. Tal vez no lo esté? – supercheetah

1

Prueba con esto: http://www.hexco.de/rmdebug/ que lo utilizaron ampliamente, su tiene un bajo impacto en el rendimiento (en su mayoría impactos cantidad de RAM), pero el algoritmo de asignación es el mismo. Siempre ha demostrado lo suficiente como para encontrar errores de asignación. Su programa se bloqueará tan pronto como se produzca el error, y tendrá un registro detallado.

+0

Gracias, I ' Lo echaré un vistazo.Me pregunto si funciona bien en una aplicación de multiprocesamiento C++ ... – pachanga

+0

Sí, el enhebrado no debería tener ningún impacto – daniel

1

No estoy seguro de si hubiera detectado su error en particular, pero la variable de entorno MALLOC_CHECK_ (malloc man page) gira en la comprobación adicional en la implementación predeterminada de Linux malloc, y normalmente no tiene un costo de tiempo de ejecución significativo.

+0

Gracias, lo he intentado también (MALLOC_CHECK_ = 3), sin embargo, no mostró ninguna fuente de memoria corrupción desde (como escribí antes) la memoria fue corrompida por datarace no por el uso incorrecto de malloc/free ... – pachanga

Cuestiones relacionadas