2008-09-30 10 views
15

En entorno Linux, al obtener errores "glibc detectados *** libre(): puntero no válido", cómo identifico qué línea de código lo está causando?Cómo forzar el aborto en "glibc detectado *** libre(): puntero no válido"

¿Hay alguna manera de forzar un aborto? Recuerdo que había una var ENV para controlar esto?

Cómo establecer un punto de interrupción en gdb para el error glibc?

+0

Creo que esta pregunta necesita respuestas diferentes dependiendo del sistema específico y no está restringida a Linux (por ejemplo, OpenBSD, OSX). – rwst

Respuesta

3

En general, parece que podría tener que recompilar glibc, ugh.

Usted no dice qué entorno se está ejecutando en, pero si se puede volver a compilar el código para OS X, entonces su versión de libc tiene un free() que escucha a esta variable de entorno:

MallocErrorAbort    If set, causes abort(3) to be called if an 
           error was encountered in malloc(3) or 
           free(3) , such as a calling free(3) on a 
           pointer previously freed. 

La página de manual de forma gratuita() en OS X tiene más información.

Si está en Linux, intente con Valgrind, puede encontrar algunos errores imposibles de cazar.

+0

+1 para promocionar Valgrind;) – 0xC0000022L

3

Cómo establecer un punto de interrupción en gdb?

(gdb) b nombre de archivo: linenumber // e.g. b main.cpp: 100

¿Hay alguna manera de forzar un aborto? Recuerdo que había una var ENV para controlar esto?

Tenía la impresión de que se interrumpió por defecto. Asegúrese de tener instalada la versión de depuración.

O utilizar libdmalloc5:. "Gota en el reemplazo para malloc', realloc del sistema y otras rutinas 'calloc', libres' de gestión de memoria al tiempo que proporciona potentes instalaciones de depuración configurables en tiempo de ejecución Estas instalaciones incluyen cosas tales como la memoria de seguimiento de fugas, fence- detección posterior a la escritura, informe de número de archivo/línea y registro general de estadísticas ".

Agregar a su comando de enlace

-L/usr/lib/debug/lib -ldmallocth 

GDB de control debe devolver automáticamente cuando glibc provoca un aborto.

O puede configurar un manejador de señal para SIGABRT para volcar la pila hasta un fd (descriptor de archivo). A continuación, mp_logfile es un archivo *

void *array[512/sizeof(void *)]; // 100 is just an arbitrary number of backtraces, increase if you want. 
size_t size; 

size = backtrace (array, 512/sizeof(void *)); 
backtrace_symbols_fd (array, size, fileno(mp_logfile)); 
7

le recomiendo que obtener valgrind:

valgrind --tool = memcheck --leak-check = ./a.out completa

+2

Tendrá varias ejecuciones, así que valgrind obtendrá un nombre de archivo basado en la hora actual. valgrind --herramienta = memcheck --leak-check = full --log-archivo = 'fecha +% s'-vg.txt ./a.out –

15

Creo que si setenv MALLOC_CHECK_ a 2, glibc llamará al abort() cuando detecte el error "libre(): puntero no válido". Tenga en cuenta el guión bajo final en el nombre de la variable de entorno.

Si MALLOC_CHECK_ es 1 glibc se imprimirá "libre(): puntero no válido" (y printfs similares para otros errores).Si MALLOC_CHECK_ es 0, glibc ignorará silenciosamente dichos errores y simplemente regresará. Si MALLOC_CHECK_ es 3, glibc imprimirá el mensaje y luego llamará al abort(). Es decir. es una máscara de bits.

También puede llamar al mallopt(M_CHECK_ACTION, arg) con un argumento de 0-3, y obtener el mismo resultado que con MALLOC_CHECK_.

Dado que está viendo el mensaje "free(): invalid pointer", creo que ya debe estar configurando MALLOC_CHECK_ o llamando al mallopt(). Por defecto, glibc no imprime esos mensajes.

En cuanto a cómo depurarlo, la instalación de un controlador para SIGABRT es probablemente la mejor manera de proceder. Puede establecer un punto de interrupción en su controlador o activar deliberadamente un volcado de núcleo.

+0

¿dónde puedo configurar MALLOC_CHECK para que tenga efecto? –

+0

'$ export MALLOC_CHECK_ = 2 – KAction

Cuestiones relacionadas