¿Cómo asigno una dirección de puntero de instrucciones segfault de / var / log / messages a una dirección / función en mi archivo .map?

StackOverflow https://stackoverflow.com/questions/1408788

  •  05-07-2019
  •  | 
  •  

Pregunta

(Mi entorno es Ubuntu de 64 bits, mi aplicación es C ++ compilada y enlazada con g ++.)

Cuando una aplicación hace algo como dividir por cero o ejecutar un asm (" int $ 3 ") dejado en el código, uno de los siguientes se registra a través de syslog en / var /log/kern.log y / var / log / messages :

Sep 10 18:06:47 VM kernel: [117194.123452] a.out[20288] trap divide error ip:45c59d sp:7fff65a91810 error:0 in a.out[400000+144000]
Sep 10 18:07:10 VM kernel: [117217.020833] a.out[20294] trap int3 ip:45c493 sp:7fff5cc559f0 error:0

En ambos casos, la dirección del puntero de instrucción apunta a algo que puedo buscar fácilmente en el archivo .map producido en el momento del enlace (usando el " -Wl, -Map , output.map ").

Pero si causo una falla de seg, en este caso por una llamada a memcpy () con la fuente establecida en NULL, el puntero de instrucción está tan fuera de rango, no tengo idea de cómo se supone que debe ser asignado:

Sep 10 18:06:13 VM kernel: [117160.228587] a.out[20282]: segfault at 0 ip 00007f7e79209092 sp 00007fff831faf08 error 4 in libc-2.9.so[7f7e79185000+168000]

En este ejemplo, habría esperado que la IP estuviera en el rango de 0x445e70-0x445e7f, que es la ubicación de memcpy () de acuerdo con mi archivo .map.

Mi pregunta: ¿cuál es el truco para interpretar la ip en este caso?

¿Fue útil?

Solución

Según el mensaje, parece que se estrelló dentro de memcpy () , de libc-2.9.so , que se asigna a su proceso a partir de 0x7f7e79185000. Esto se espera ya que memcpy es la función que está intentando eliminar la referencia al puntero. El puntero de instrucciones parece válido ya que está dentro del rango de libc. Si pretendía anular memcpy y llamar a su propia versión, es posible que deba compilar con -fno-builtin-memcpy .

Editar: Puede estar vinculando libc de forma estática, pero de acuerdo con el mensaje, también tiene la biblioteca compartida de libc asignada a la memoria de proceso. Debería verlo listado en /proc/pid / maps mientras su programa se está ejecutando. Puede ser que esté enlazando con otra biblioteca compartida, como libstdc ++, y depende de la biblioteca compartida libc. Como resultado, tiene dos versiones de memcpy y, en este caso, está llamando a la versión de la biblioteca compartida libc que se asigna a la dirección superior. Si no desea la biblioteca compartida libc, asegúrese de que está enlazando las bibliotecas todas de forma estática; use la opción -static al principio de su línea de enlace.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top