2010-06-23 7 views
22

Mi aplicación segmenta a veces y principalmente en malloc() y malloc_consolidate() cuando miro la traza inversa en gdb.Segfaults en malloc() y malloc_consolidate()

Comprobé que la máquina tiene suficiente memoria disponible, ni siquiera comenzó a intercambiar. Comprobé los ulimits para el segement de datos y el tamaño máximo de la memoria, y ambos están configurados como "ilimitados". También ejecuté la aplicación en valgrind y no encontré ningún error de memoria.

Ahora ya no tengo ideas sobre qué más podría estar causando estos segfaults. Algunas ideas ?

Actualización: ya que no estoy descubriendo nada con valgrind (o ptrcheck), ¿podría ser que otra aplicación está destrozando la estructura de la memoria de libc o hay una estructura separada para cada proceso?

+2

¿Has tenido un accidente en valgrind? –

+0

No, no se colgó. Es una aplicación en tiempo real y bajo valgrind solo puedo cargarlo con mucha ligereza y generalmente solo se cuelga bajo una carga más pesada. –

+0

¿Qué sistema operativo es este? A juzgar por la cadena de herramientas, parece que puede ser Linux. En este caso, no, otras aplicaciones no pueden destrozar su pila; es algo en tu aplicación. Si esto solo ocurre bajo carga, eso lo hace aún más difícil por supuesto ... ¿Qué es diferente bajo carga? ¿Cómo podría estar causando que arruines el montón? Intenta "torturar" tu aplicación lo mejor que puedas mientras se ejecuta en Valgrind ... ¿cómo puedes reproducir mejor las condiciones que existirían bajo carga? Tal vez asignar memoria gratuitamente, algo así? –

Respuesta

12

Lo más probable es que esté destrozando el montón, es decir, está escribiendo más allá de los límites de una pieza de memoria asignada, y esto está sobrescribiendo las estructuras de datos que malloc() usa para administrar el montón. Esto ocasiona que malloc() acceda a una dirección no válida y la aplicación se cuelga.

Si se queda sin memoria, no se bloqueará malloc(), sino que simplemente devolverá NULL. Eso podría hacer que su código se bloquee si no está buscando NULL, pero el sitio del bloqueo no estaría en malloc().

Es un poco extraño que Valgrind no reporte ningún error, pero hay algunos errores que la herramienta "Memcheck" predeterminada puede perderse. Intenta ejecutar Valgrid con el "Ptrcheck" tool en su lugar.

+0

Pero, ¿no debería haber aparecido en valgrind? (Suponiendo que mi cobertura de prueba fue lo suficientemente buena.) –

+1

Tu comentario parece haberse superpuesto con mi edición, como se sugiere allí, prueba ejecutar Valgrind con la herramienta "Ptrcheck". Si malloc() se bloquea, es casi seguro que estás destrozando el montón de alguna manera. –

+1

A partir de la versión 3.7.0 de Valgrind (5 de noviembre de 2011), la herramienta ** exp-ptrcheck ** ha sido renombrada y reducida en funcionalidad a _check para detectar desbordamientos en las matrices global y de pila_. Ahora se llama ** exp-sgcheck ** ("Stack y Global Array Checking"). [enlace] (http://valgrind.org/docs/manual/dist.news.html) – Amar

21

De http://www.gnu.org/s/libc/manual/html_node/Heap-Consistency-Checking.html#Heap-Consistency-Checking:

Otra posibilidad de comprobar y tenga cuidado con los errores en el uso de malloc, realloc y libre es establecer la variable de entorno MALLOC_CHECK_. Cuando se establece MALLOC_CHECK_, se usa una implementación especial (menos eficiente) que está diseñada para ser tolerante contra errores simples , como llamadas dobles de libre con el mismo argumento o sobrepasados ​​de un solo byte (off-by-one loco). Sin embargo, no todos estos errores pueden estar protegidos contra , y pueden producirse pérdidas de memoria. Si MALLOC_CHECK_ está establecido en 0, cualquier corrupción de montón detectada se ignora silenciosamente ; si se establece en 1, se imprime un diagnóstico en stderr; si se establece en 2, se llama aborto inmediatamente. Esto puede ser útil porque, de lo contrario, un bloqueo puede ocurrir mucho más tarde, y la verdadera causa del problema es y luego es muy difícil localizarlo.