sirven sintaxis que para ejemplos comandos comando basicos c linux valgrind addr2line

sintaxis - comandos linux basicos



¿Cómo usar el comando addr2line en Linux? (5)

Así es exactamente como lo usas. Existe la posibilidad de que la dirección que tienes no se corresponda con algo directamente en tu código fuente.

Por ejemplo:

$ cat t.c #include <stdio.h> int main() { printf("hello/n"); return 0; } $ gcc -g t.c $ addr2line -e a.out 0x400534 /tmp/t.c:3 $ addr2line -e a.out 0x400550 ??:0

0x400534 es la dirección de main en mi caso. 0x400408 también es una dirección de función válida en a.out , pero es un fragmento de código generado / importado por GCC, que no tiene información de depuración. (En este caso, __libc_csu_init . Puede ver el diseño de su ejecutable con readelf -a your_exe ).

Otras veces cuando addr2line fallará es si está incluyendo una biblioteca que no tiene información de depuración.

Estoy tratando de usar el comando addr2line en Unix pero cada vez da el mismo resultado que ??: 0. Estoy dando el comando como addr2line -e a.out 0x4005BDC . valgrind esta dirección mientras ejecutaba este ejecutable a.out con la herramienta valgrind para encontrar la pérdida de memoria. También compilé el código fuente con la opción -g .


Debe especificar un desplazamiento para addr2line, no una dirección virtual (VA). Presumiblemente, si tuviera desactivada la asignación aleatoria de espacio de direcciones, podría usar un VA completo, pero en la mayoría de los sistemas operativos modernos, los espacios de direcciones se asignan al azar para un nuevo proceso.

Dado el VA 0x4005BDC por valgrind, encuentre la dirección base de su proceso o biblioteca en la memoria. Haga esto examinando el archivo /proc/<PID>/maps mientras su programa se está ejecutando. La línea de interés es el segmento de text de su proceso, que es identificable por los permisos r-xp y el nombre de su programa o biblioteca.

Digamos que la base VA es 0x0x4005000 . Entonces encontraría la diferencia entre el VA suministrado por valgrind y el VA base: 0xbdc . Luego, dale eso a add2line:

addr2line -e a.out -j .text 0xbdc

Y ver si eso te da su número de línea.


Intente agregar la opción -f para mostrar los nombres de las funciones:

addr2line -f -e a.out 0x4005BDC


Por favor, compruebe:

  • Si todas las funciones de su binario se compilan con -g , las funciones de soporte solo para addr2line tienen información de depuración, que se compila con -g
  • Si su desplazamiento es un desplazamiento válido. Eso significa que su desplazamiento no debe ser una dirección de memoria virtual, y solo debe ser un desplazamiento en la sección .text . En la sección .text significa que la dirección debe apuntar a una instrucción en el binario

uso addr2line

A continuación se muestra el mensaje de man addr2line .

addr2line: convierte las direcciones en nombres de archivos y números de línea.

Las addresses deben ser la dirección en un ejecutable o un desplazamiento en una sección de un objeto reubicable.

La salida es algo como FILENAME:LINENO , el nombre del archivo de origen y el número de línea en el archivo

Ejemplo.

Tomemos el helloworld como ejemplo.

#include <stdio.h> int main() { printf("hello/n"); return 0; }

Después de compilarlo con gcc -g hello.c , primero podríamos usar objdump para obtener una idea acerca de la información de desplazamiento en el archivo a.out generado.

Lo siguiente es parte del desmontaje desechado:

Disassembly of section .text: 0000000000400440 <_start>: 400440: 31 ed xor %ebp,%ebp 400442: 49 89 d1 mov %rdx,%r9 400445: 5e pop %rsi 400446: 48 89 e2 mov %rsp,%rdx 400449: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 40044d: 50 push %rax 40044e: 54 push %rsp 40044f: 49 c7 c0 c0 05 40 00 mov $0x4005c0,%r8 400456: 48 c7 c1 50 05 40 00 mov $0x400550,%rcx 40045d: 48 c7 c7 36 05 40 00 mov $0x400536,%rdi 400464: e8 b7 ff ff ff callq 400420 <__libc_start_main@plt> 400469: f4 hlt 40046a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) ... 0000000000400536 <main>: #include <stdio.h> int main() { 400536: 55 push %rbp 400537: 48 89 e5 mov %rsp,%rbp printf("hello/n"); 40053a: bf d4 05 40 00 mov $0x4005d4,%edi 40053f: e8 cc fe ff ff callq 400410 <puts@plt> return 0; 400544: b8 00 00 00 00 mov $0x0,%eax } 400549: 5d pop %rbp 40054a: c3 retq 40054b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)

La columna más a la izquierda del código es el desplazamiento en el archivo binario. __start función __start proviene de la biblioteca C estándar y se precompila sin información de depuración. main función main proviene de nuestro código helloworld que contiene información de depuración ya que compilamos el archivo con -g .

Lo siguiente es la salida de addr2line :

$ addr2line -e a.out 0x400442 #offset in the `__start` function ??:? $ addr2line -e a.out 0x400536 #offset in the `main` function hello.c:21 $ addr2line -e a.out 0x40054b -f #The last instruction of the `main` function main ??:?

Podríamos sacar algunas conclusiones de la salida anterior:

  1. Solo el segmento de código generado con el indicador -g (lo que significa que el segmento tiene información de depuración) podría generar correctamente el nombre de archivo y la información del número de código.
  2. No todas las compensaciones de un cuerpo de función compilado con el indicador -g generarán correctamente el nombre de archivo y el número de lino. El desplazamiento 0x40054b es la última instrucción después de la instrucción ret de la función main , pero no pudimos obtener la información.

También puede usar gdb en lugar de addr2line para examinar la dirección de memoria. Cargue el archivo ejecutable en gdb e imprima el nombre de un símbolo que se almacena en la dirección. 16 Examinando la tabla de símbolos .

(gdb) info symbol 0x4005BDC