2012-03-10 19 views
6

me encontré con tal de error al ejecutar comandos ni durante el BGF depuración:BGF strace muestra que trata de PTRACE en una dirección no válida

Advertencia:
No se puede insertar punto de interrupción 0.
Error de acceso a 0x3ac706a dirección de memoria: Error de entrada/salida.

0xf6fa4771 en siglongjmp() desde /lib/libc.so.6

para investigar lo que GDB problema se reúne con I Strace BGF y obtener tal resultado:

rt_sigprocmask (SIG_BLOCK , NULL, [RT_1], 8) = 0
ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fdf60, [0x1cc4fe470]) = 0
ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0
rt_sigprocmask (SIG_BLOCK, NULL, [RT_1], 8) = 0
...
...
rt_sigprocmask (SIG_BLOCK, NULL, [RT_1], 8) = 0
rt_sigprocmask (SIG_BLOCK, NULL, [ RT_1], 8) = 0
ptrace (PTRACE_GETREGS, 27781, 0, 0x7fff8990e8b0) = 0
ptrace (PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO error (entrada/salida)
ptrace (PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (error de entrada/salida)

Implica que el BGF primera ptrace en dirección de memoria 0xcc4fe480 y obtiene el valor 0x3ac706a4506fa1d (en realidad un valor de 8 bytes 0x03ac706a4506fa1d). Más tarde obtiene una dirección alineada 0x3ac7068 de los primeros 4 bytes de ese valor, que es una dirección no válida y hace que gdb no pueda rastrear.

contenido de/proc/[pid]/mapas:

cbce2000-cc353000 r-xp 00000000 08:03 295479 xxx.so
cc353000-cc3f0000 r - p 00.670.000 8:03 295479 xxx .so
cc3f0000-cc3f6000 rw-p 0070d000 8:03 295479 xxx.so
cc3f6000-cc3fe000 rw-p cc3f6000 00:00 0
cc3fe000-cc3ff000 --- p cc3fe000 00:00 0
cc3ff000- cc4ff000 rwxp cc3ff000 00:00 0
cc4ff000-cc500000 --- p cc4ff000 00:00 0

cc500000-cc600000 rwxp cc500000 00:00 0
cc62d000-cc673000 r-xp 00000000 08:03 295545 yyy.so
cc673000-cc674000 - -p 00046000 08:03 295545 yyy.so
cc674000-cc675000 r - p 00046000 08:03 295545 yyy.así
cc675000-cc676000 rw-p 00047000 08:03 295545 yyy.so

Muestra que dirección 0xcc4fe480 es de la sección con la fuente negrita anteriormente. Esta sección no está relacionada con ningún archivo .so o bin.

Esta pregunta está realmente relacionada con otra pregunta http://stackoverflow.com/questions/9564417/gdb-cant-insert-internal-breakpoint, que aún no se ha resuelto. Encontré estos problemas durante la investigación de la edición anterior.

Tengo 3 preguntas aquí:
1. miren salida de strace para ptrace aquí:
ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0
Por qué está anotado el último parámetro por corchetes? ¿Significa que representa el valor de retorno? La página del manual dice que ptrace debe devolver la palabra leída para PTRACE_PEEKTEXT, pero parece que la salida de la cadena no sigue eso, así que sospecho que muestra el valor de retorno en el último parámetro.
2. Hay una sección (con letra en negrita) entre dos .so pero no asociada con ningún inodo. ¿Qué representa esa sección?
3. Gdb lee una palabra de esa sección y usa esa palabra como una dirección, pero en realidad esa es una dirección no válida. ¿Cuáles son las causas posibles de tal error?

Gracias!

Respuesta

5
  1. Echa un vistazo a la salida de strace para ptrace aquí: ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0 ¿Por qué es el último parámetro anotado por corchetes? ¿Significa que representa el valor de retorno?

Correcto.

  1. Hay una sección (que en negrita) entre dos .so pero no asociada con ningún nodo-i. ¿Qué representa esa sección?

Es una región de memoria que ha sido mmap ed con MAP_ANONYMOUNS bandera (es decir, que no se corresponde con cualquier archivo en el disco).

Dado que el tamaño de esa región es exactamente 1MB, y dado que está rodeado por regiones privadas mapeadas con PROT_NONE, es una apuesta segura que esta región representa una pila de subprocesos, rodeada por zonas de protección de pila.

  1. Gdb lee una palabra de esa sección y utiliza esa palabra como una dirección, pero en realidad eso es una dirección no válida. ¿Cuáles son las causas posibles de tal error?

Por alguna razón GDB considera que debe ser el código en la dirección 0x3ac7068, y quiere poner un punto de interrupción interna allí. GDB utiliza puntos de interrupción internos para realizar un seguimiento de las bibliotecas compartidas cargadas (entre otras cosas).

La salida de maintenance info break debe revelar qué código cree GDB que reside en la dirección "incorrecta".

0

Supongo que su código se está desbordando y escribiendo sobre una dirección válida, y gdb está accediendo a esa área de memoria esperando una dirección pero obteniendo datos basura. ¿Cuál es la sección de código que intentas depurar? Podría ayudarnos.

+0

Estoy depurando una función en una biblioteca compartida (.so). Pero no es ninguna de las dos libs que enumeré arriba. Eso dice que estoy depurando lib A y gdb lee una dirección no válida de una sección entre lib B y lib C. Es por eso que me confunde. –

Cuestiones relacionadas