2010-02-18 25 views
8

He estado trabajando durante las últimas semanas tratando de rastrear un error realmente difícil que bloquea mi aplicación. En primer lugar, la aplicación se bloqueaba en la asignación de una cadena estándar, y luego durante la libre de una variable local.Complemento para valgrind?

Después de una cuidadosa inspección del código, no había ninguna razón para que fallara en estas ubicaciones; sin embargo, siempre se bloqueaba al intentar liberar un puntero no válido (es decir, un puntero que apuntaba a la memoria no válida). Y no tengo idea de por qué este puntero no apuntaba a la ubicación correcta.

Sospecho que el problema tiene que ver con un problema de corrupción de memoria o problema de corrupción de puntero de algún tipo. El problema es que no puedo rastrearlo visualmente ... todavía. No tengo idea de dónde empezar a buscar en el código, y hay miles de líneas de código por recorrer, por lo que no parece un enfoque realista del problema.

Así que en Valgrind viene ...

Una herramienta que he dependido de un tiempo muchos problemas para encontrar dentro del código que puede conducir a un accidente de este tipo. Sin embargo, ¡esta vez ha surgido con las manos vacías! No veo ningún error en valgrind cuando ocurre el problema y, por tanto, la razón por la que hago esta pregunta.

¿Existen otras aplicaciones que puedan complementar valgrind y ayudar a encontrar problemas en el código que puedan causar un bloqueo mencionado anteriormente?

¡Gracias!

+0

usted podría intentar publicar un ejemplo de código mínima, compilables que reproduce el problema. Estoy dispuesto a apostar que el acto de intentar escribir una muestra de código de este tipo te hará obvio el problema. Si no, estamos más que felices de ayudar. –

+0

¿Desea ver dónde se bloquea el código (es decir, una muestra de dónde se bloquea)? porque no hay ninguna razón para que se bloquee allí como mencioné, pero no me importa publicarlo – bbazso

Respuesta

0

Ha intentado utilizar lint, flexlint o cppcheck. Esto puede ayudar a identificar un problema.

Si sabe qué área de memoria se está dañando, intente marcar esta memoria como protegida. Esto puede enmascarar su problema y no ayudar en absoluto, pero si aún se bloquea el punto donde se modificó la memoria ayudará a resolver su problema.

+1

¿Cómo se puede proteger la memoria? Nunca hice esto antes ... – bbazso

5

En mi experiencia, coverity y purify han encontrado errores de este tipo que valgrind no (de hecho, todos encontraron problemas que no fueron vistos por los demás).

Pero a veces ninguna herramienta da una pista y hay que cavar más, agregar instrumentación, jugar con puntos de interrupción en "modificar memoria en la dirección", intentar simplemente el testcase que falla y así sucesivamente para descubrir la causa raíz. Eso puede ser muy doloroso.

+0

Estoy de acuerdo con el comentario del depurador. A veces lo mejor es establecer un punto de interrupción en la memoria que se desvanece y esperar. –

+0

Con gdb, ¿cómo puedo establecer un punto de interrupción en la memoria para ver cuándo está escrito? – bbazso

+0

el comando 'watch', potencialmente junto con una condición en lo que considera inválido –

1

No especificó la plataforma, pero puedo recomendar Gimpel PC-lint como una excelente herramienta de análisis estático (¡no se deje engañar por el nombre!). También ofrecen FlexeLint para otras plataformas, pero no tengo experiencia personal de ese producto.

+0

Gimpel Software es un gran conjunto. 1 –

6

Supongo que está utilizando la herramienta de validación de valgrind, que es por lo que es famoso. Dado que ya está utilizando valgrind, también puede intentar ejecutar su programa a través del valgrind --tool=exp-sgcheck (anteriormente exp-ptrcheck), que es una herramienta experimental diseñada para detectar ciertos tipos de errores que memcheck perderá, incluidos los controles de acceso para matrices globales y de pila, y de punteros que apuntan a un objeto válido pero no al objeto que se pretendía. Hace esto usando un mecanismo completamente diferente, esencialmente rastreando cada puntero en la memoria en lugar de seguir la memoria en sí, y mediante el uso de la heurística.

Tenga en cuenta que la herramienta es experimental, pero puede descubrir que capta algo significativo. Actualmente aún no es compatible con procesadores OS X o que no sean de Intel.

+0

lo probé, pero me siguen dando una: sysno == 233 exp-ptrcheck: el 'imposible' que pasó: syscall no controlada ¿Alguna idea? – bbazso

+0

Lo probé y luego bajó de uno a 232. :) ¿Dónde encontraste la asignación entre syscall no y qué es? – bbazso

+0

'/ usr/include/asm-i386/unistd.h' (o' asm-x86_64' para x86_64). Supongo que se puede ver por qué sigue siendo experimental ... – mark4o

2

¿Es posible que se esté produciendo algún daño en la pila? Si es así, intente habilitar stack canaries con la opción -fstack-protector-all, suponiendo que está usando g ++.

Aparte de eso, ¿ha levantado banderas de advertencia para ayudar a identificar el código sospechoso?

+0

Probé la bandera -fstack-protector-all y también probé libsafe y ambos salieron con las manos vacías. :( – bbazso

0

Si valgrind puede identificar el puntero malo que se pasa al free(), puede intentar ejecutar el programa bajo DDD, que puede establecer un hardware watchpoing en la ubicación de memoria y detener el programa cuando obtiene un valor incorrecto. Si el puntero se está cambiando mucho, es posible que deba escribir algún código alrededor de malloc y libre para realizar un seguimiento de qué valores son buenos y malos.

3

Mi experiencia es que a menudo este tipo de problema es causado por un desbordamiento de pila. Electric Fence es una herramienta de depuración de asignación relativamente simple que me gusta usar. Su uso principal es como una herramienta de análisis dinámico para comprobar desbordamientos de pila, un complemento de "-fstack-protector-all" que comprueba si hay desbordamientos de pila.

More links para efencia cosas.