una servicio segmento segmentar segmentacion público producto proceso practico objetivo mercado empresa ejemplos ejemplo como analisis c debugging memory-management segmentation-fault valgrind

servicio - Sugerencias para eliminar fallas de segmentación cuando no se encuentran fugas



segmentacion de mercado ejemplo practico (3)

Escribí una aplicación basada en C que parece funcionar bien, excepto en grandes conjuntos de datos como entrada.

Con una gran cantidad de datos, aparece un error de segmentación en los pasos finales de la funcionalidad del binario.

valgrind el binario (con la entrada de prueba) con valgrind :

valgrind --tool=memcheck --leak-check=yes /foo/bar/baz inputDataset > outputAnalysis

Este trabajo normalmente toma unas pocas horas, pero con valgrind tomó siete días.

Lamentablemente, en este punto, no sé cómo leer los resultados que obtengo de esta ejecución.

Recibo muchas de estas advertencias:

... ==4074== Conditional jump or move depends on uninitialised value(s) ==4074== at 0x435900: ??? (in /foo/bar/baz) ==4074== by 0x439CC5: ??? (in /foo/bar/baz) ==4074== by 0x400BF2: ??? (in /foo/bar/baz) ==4074== by 0x402086: ??? (in /foo/bar/baz) ==4074== by 0x402A0F: ??? (in /foo/bar/baz) ==4074== by 0x41684F: ??? (in /foo/bar/baz) ==4074== by 0x4001B8: ??? (in /foo/bar/baz) ==4074== by 0x7FEFFFF57: ??? ==4074== Uninitialised value was created ==4074== at 0x461D3A: ??? (in /foo/bar/baz) ==4074== by 0x43F926: ??? (in /foo/bar/baz) ==4074== by 0x416B9B: ??? (in /foo/bar/baz) ==4074== by 0x416725: ??? (in /foo/bar/baz) ==4074== by 0x4001B8: ??? (in /foo/bar/baz) ==4074== by 0x7FEFFFF57: ??? ...

No se sugieren partes del código, ni nombres de variables, etc. ¿Qué puedo hacer con esta información?

Al final, finalmente recibo el siguiente error, pero, como con los conjuntos de datos más pequeños que no se valgrind , valgrind no encuentra fugas:

... ==4074== Process terminating with default action of signal 11 (SIGSEGV) ==4074== Access not within mapped region at address 0x7158E7F7 ==4074== at 0x7158E7F7: ??? ==4074== by 0x4020B8: ??? (in /foo/bar/baz) ==4074== by 0x6322203A22656D6E: ??? ==4074== by 0x306C675F6E557267: ??? ==4074== by 0x202C22373232302F: ??? ==4074== by 0x6D616E656C696621: ??? ==4074== by 0x72686322203A2264: ??? ==4074== by 0x3030306C675F6E54: ??? ==4074== by 0x346469702E373231: ??? ==4074== by 0x646469662E34372F: ??? ==4074== by 0x722E64616568656B: ??? ==4074== by 0x63656D6F6C756764: ??? ==4074== If you believe this happened as a result of a stack ==4074== overflow in your program''s main thread (unlikely but ==4074== possible), you can try to increase the size of the ==4074== main thread stack using the --main-stacksize= flag. ==4074== The main thread stack size used in this run was 10485760. ==4074== ==4074== HEAP SUMMARY: ==4074== in use at exit: 0 bytes in 0 blocks ==4074== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==4074== ==4074== All heap blocks were freed -- no leaks are possible ==4074== ==4074== For counts of detected and suppressed errors, rerun with: -v ==4074== ERROR SUMMARY: 1603141870 errors from 86 contexts (suppressed: 0 from 0) Segmentation fault

Todo para lo que asigno espacio obtiene una declaración free equivalente, después de lo cual configuro los punteros a NULL .

En este punto, ¿cómo puedo depurar mejor esta aplicación para determinar qué más está causando la falla de segmentación?

22 de diciembre de 2011 - Editar

Recopilé una versión de depuración de mi binario, llamada debug-binary , utilizando los siguientes indicadores de compilación:

-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE=1 -DUSE_ZLIB -g -O0 -Wformat -Wall -pedantic -std=gnu99

Cuando lo ejecuto con valgrind , no obtengo mucha más información:

valgrind -v --tool=memcheck --leak-check=yes --error-limit=no --track-origins=yes debug-binary input > output

Aquí hay un fragmento de salida:

==25116== 2 errors in context 14 of 14: ==25116== Invalid read of size 4 ==25116== at 0x4045E8: ??? (in /foo/bar/debug-binary) ==25116== by 0x40682F: ??? (in /foo/bar/debug-binary) ==25116== by 0x404F0C: ??? (in /foo/bar/debug-binary) ==25116== by 0x401FA4: ??? (in /foo/bar/debug-binary) ==25116== by 0x402016: ??? (in /foo/bar/debug-binary) ==25116== by 0x403B27: ??? (in /foo/bar/debug-binary) ==25116== by 0x40295E: ??? (in /foo/bar/debug-binary) ==25116== by 0x31A021D993: (below main) (in /lib64/libc-2.5.so) ==25116== Address 0x539f188 is 24 bytes inside a block of size 48 free''d ==25116== at 0x4A05D21: free (vg_replace_malloc.c:325) ==25116== by 0x401F6B: ??? (in /foo/bar/debug-binary) ==25116== by 0x402016: ??? (in /foo/bar/debug-binary) ==25116== by 0x403B27: ??? (in /foo/bar/debug-binary) ==25116== by 0x40295E: ??? (in /foo/bar/debug-binary) ==25116== by 0x31A021D993: (below main) (in /lib64/libc-2.5.so)

¿Es esto un problema con mi binario, o con una biblioteca de sistema ( libc ) de la que depende mi aplicación?

Tampoco sé qué hacer para interpretar el ??? entradas. ¿Hay otra bandera de compilación que necesito para obtener valgrind para proporcionar más información?


El "salto o movimiento condicional depende del valor no inicializado" es un error grave que debe corregir. Indica que el comportamiento de su programa se ve afectado por el contenido de una variable no inicializada (incluida una región de memoria no inicializada devuelta por malloc() ).

Para obtener backtraces legibles de valgrind, debe compilar con -g .


No creo que valgrind sea capaz de encontrar todos los errores en los que haya sobrepasado un valor en la pila (pero no sobrecargue la pila en sí). Por lo tanto, es posible que desee probar la opción de gcc -f-stack-protector-all .

También debe probar mudflap, con -fmudflap (single-threaded) o -fmudflapth (multi-threaded).

Tanto el mudflap como el protector de pila deberían ser mucho más rápidos que valgrind.

Además, parece que no tiene símbolos de depuración, lo que dificulta la lectura de trazas inversas. Agregar -ggdb . Probablemente también desee habilitar la generación de archivos centrales (pruebe ulimit -c unlimited ). De esta manera, puede intentar depurar el proceso post-crash utilizando el gdb program core .

Como @wallyk indica, su segfault puede ser realmente bastante fácil de encontrar, por ejemplo, tal vez está desreferenciando NULL, y gdb puede indicarle la línea exacta (o, bueno, cerrar a menos que compile con -O0 ). Esto tendría sentido, por ejemplo, si solo está ejecutando memoria para sus conjuntos de datos más grandes, y así malloc devuelve NULL, y se olvidó de verificar eso en alguna parte.

Por último, si nada más tiene sentido, siempre existe la posibilidad de problemas de hardware. Pero se esperaría que sean bastante aleatorios, por ejemplo, diferentes valores se corrompan diferentes ejecuciones. Si prueba una máquina diferente, y sucede allí, es muy poco probable que sea un problema de hardware.


Valgrind básicamente dice que no hay problemas notables de administración del montón. El programa está segfaulting de una falla de programación menos compleja.

Si fuera yo, lo haría

  • compilarlo con gcc -g ,
  • habilitar los archivos de volcado del núcleo ( ulimit -c unlimited ),
  • ejecuta el programa normalmente,
  • y deja que falle
  • use gdb para examinar el archivo principal y observe qué estaba haciendo cuando fallaba:

    gdb (archivo de programa) (corefile)
    bt