Estoy depurando utilizando volcados de núcleo, y tenga en cuenta que gdb necesita que suministre tanto el ejecutable como el volcado de núcleo. ¿Por qué es esto? Si el volcado del núcleo contiene toda la memoria que utiliza el proceso, ¿no está el ejecutable contenido en el volcado del núcleo? ¿Quizás no hay garantía de que todo el exe se cargue en la memoria (aunque los ejecutables individuales no suelen ser tan grandes) o tal vez el volcado del núcleo no contiene toda la memoria relevante después de todo? ¿Es por los símbolos (tal vez no están cargados en la memoria normalmente)?
11
Respuestas:
El volcado del núcleo es solo el volcado de la huella de memoria de sus programas, si sabe dónde estaba todo, podría usarlo.
Utiliza el ejecutable porque explica dónde (en términos de direcciones lógicas) se encuentran las cosas en la memoria, es decir, el archivo central.
Si usa un comando
objdump
, volcará los metadatos sobre el objeto ejecutable que está investigando. Usando un objeto ejecutable llamado a.out como ejemplo.objdump -h a.out
voltea solo la información del encabezado, verá secciones llamadas eg. .data o .bss o .text (hay muchos más). Estos informan al cargador del núcleo dónde se pueden encontrar varias secciones en el objeto y en qué parte del espacio de direcciones del proceso se debe cargar la sección, y para algunas secciones (por ejemplo, .data .text), qué se debe cargar. (La sección .bss no contiene ningún dato en el archivo, pero se refiere a la cantidad de memoria que se debe reservar en el proceso para datos no inicializados, se llena con ceros).El diseño del archivo de objeto ejecutable se ajusta a un estándar, ELF.
objdump -x a.out
- tira todoSi el objeto ejecutable todavía contiene sus tablas de símbolos (no se ha eliminado,
man strip
y solía-g
generar una generación de depuración paragcc
asumir la compilación de la fuente de CA), puede examinar el contenido principal por nombres de símbolos, por ejemplo, si tenía una variable / buffer llamado inputLine en su código fuente, puede usar ese nombregdb
para ver su contenido. es decirgdb
, conocería el desplazamiento desde el inicio del segmento de datos inicializado de sus programas donde comienza inputLine y la longitud de esa variable.Lecturas adicionales Artículo 1 , Artículo 2 y para la especificación del formato ejecutable y de enlace (ELF) .
Actualización después del comentario de @mirabilos a continuación.
Pero si usa la tabla de símbolos como en
Produce
y luego no usar la tabla de símbolos y examinar la dirección directamente en,
Produce
He examinado la memoria directamente sin usar la tabla de símbolos en el segundo comando.
También veo que la respuesta de @ user580082 agrega más explicaciones y votará positivamente.
fuente
El archivo central es una instantánea de la imagen de la pila, las asignaciones de memoria y los registros en el momento de la finalización del proceso. Los contenidos de los cuales se pueden manipular como se indica en la página principal del manual . Por defecto, las asignaciones privadas, las asignaciones compartidas y la información del encabezado ELF se vuelcan en el archivo principal.
Volviendo a su pregunta , la razón por la que gdb requiere un ejecutable es porque no simula la ejecución, al leer e interpretar las instrucciones binarias como lo hace valgrind, se convierte en el padre del proceso para controlar el comportamiento del proceso durante la ejecución hora. Utiliza el archivo central para determinar las asignaciones de memoria y el estado del proceso del procesador durante el bloqueo.
En Linux, los procesos principales pueden obtener información adicional sobre sus hijos, en particular la capacidad de localizarlos, lo que permite al depurador acceder a la información de bajo nivel del proceso, como leer / escribir su memoria, registros, cambiar asignaciones de señales, detener su ejecución, etc.
Comprenderá el requisito del ejecutable a pesar de tener un archivo core más una vez que lea cómo funciona cualquier depurador.
fuente
(además de otras buenas respuestas)
En los sistemas Linux modernos (y muchos de tipo Unix), la información de depuración (incluidos los metadatos sobre los tipos de símbolos, la ubicación del código fuente, el tipo de variables, etc., etc.) está en formato DWARF y se encuentra dentro del ejecutable ELF ( o bibliotecas compartidas ELF) cuando se compila con alguna
-g
opción. Recomiendo compilar programas para depurar-g3 -O0
y quizás-fno-inline
si se usa un GCC reciente ; sin embargo, con GCC puede incluso compilar con información de optimización y depuración, por ejemplo, con-O2 -g1
, aunque la información de depuración en ese caso puede ser un poco "confusa" (esto podría ayudar un poco a atrapar algunos errores de Heisenbugs ).Es bastante razonable evitar poner esa información en los archivos principales , ya que es posible que tenga muchos archivos principales diferentes (imagine un software ampliamente utilizado con muchos usuarios haciendo informes de errores, la mayoría de ellos con un
core
volcado) para el mismo ejecutable. También los archivos core (5) son volcados por el kernel, lo que no debería importarle la existencia de secciones DWARF en ejecutables elf (5) (porque estas secciones no están mapeadas en el espacio de direcciones virtuales del proceso de falla que volcó el núcleo en alguna señal ( 7) ). Incluso existe la posibilidad de que la información de depuración se coloque en archivos separados (fuera del ejecutable).Por cierto, GDB puede usarse dolorosamente para depurar volcados de núcleo para ejecutables sin ninguna información de depuración. Pero luego prácticamente depura en el nivel de código de máquina (no en el nivel simbólico proporcionado por los lenguajes de programación y sus compiladores).
fuente