El depurador LLDB ( LLDB ) es el componente depurador del proyecto LLVM . Está construido como un conjunto de componentes reutilizables que utilizan ampliamente las bibliotecas existentes de LLVM, como el analizador de expresiones Clang y el desensamblador LLVM . LLDB es un software libre y de código abierto bajo la Licencia de código abierto de la Universidad de Illinois/NCSA , [3] una licencia de software permisiva de estilo BSD . Desde la versión v9.0.0, se le cambió la licencia a la Licencia Apache 2.0 con excepciones LLVM. [2]
LLDB admite la depuración de programas escritos en C , Objective-C y C++ . La comunidad Swift mantiene una versión que agrega compatibilidad con el lenguaje. Free Pascal y el IDE Lazarus pueden usar LLDB como backend para su propio motor FpDebug.
Se sabe que el depurador LLDB funciona en macOS , Linux , FreeBSD , NetBSD y Windows , [4] y admite conjuntos de instrucciones i386 , x86-64 y ARM . [5] LLDB es el depurador predeterminado para Xcode 5 y versiones posteriores. Android Studio también utiliza LLDB para la depuración. [6] LLDB se puede utilizar desde otros IDE, incluidos Visual Studio Code , [7] C++Builder , [8] Eclipse , [9] y CLion . [10]
Considere el siguiente programa incorrecto escrito en C :
#incluir <stdio.h> int main ( void ) { char msg = "Hola, mundo! \n " ; printf ( "%s" , msg ); devuelve 0 ; }
Con el compilador clang en macOS , el código anterior se puede compilar utilizando el -g
indicador para incluir la información de depuración adecuada en el binario generado (incluido el código fuente), lo que facilita su inspección con LLDB. Suponiendo que el archivo que contiene el código anterior se llama test.c
, el comando para la compilación podría ser:
$ clang -Wno-error = int-conversion -g prueba.c -o prueba
Y ahora se puede ejecutar el binario:
$ ./test Fallo de segmentación
Dado que el código de ejemplo, al ejecutarse, genera un error de segmentación , se puede utilizar lldb para inspeccionar el problema:
$ lldb test (lldb) target create "test" El ejecutable actual está establecido en 'test' (x86_64). (lldb) ejecutar Proceso 70716 lanzado: '/Users/wikipedia/test' (x86_64) Proceso 70716 detenido * hilo #1, cola = 'com.apple.main-thread', motivo de detención = EXC_BAD_ACCESS (código=1, dirección=0xffffff90) marco #0: 0x00007fff6c7c46f2 libsystem_platform.dylib`_platform_strlen + 18 libsystem_platform.dylib`_platform_strlen: -> 0x7fff6c7c46f2 <+18>: pcmpeqb xmm0, xmmword ptr [rdi] 0x7fff6c7c46f6 <+22>: pmovmskb esi, xmm0 0x7fff6c7c46fa <+26>: y rcx, 0xf 0x7fff6c7c46fe <+30>: o rax, -0x1 Objetivo 0: (prueba) detenido.
El problema ocurre al llamar a la función strlen
, pero podemos ejecutar un backtrace para identificar la línea exacta de código que está causando el problema:
(lldb) bt * hilo n.° 1, cola = 'com.apple.main-thread', motivo de detención = EXC_BAD_ACCESS (código=1, dirección=0xffffff90) * marco n.° 0: 0x00007fff6c7c46f2 libsystem_platform.dylib`_platform_strlen + 18 marco n.° 1: 0x00007fff6c66b16a libsystem_c.dylib`__vfprintf + 8812 marco n.° 2: 0x00007fff6c6911c3 libsystem_c.dylib`__v2printf + 475 marco n.° 3: 0x00007fff6c668e22 libsystem_c.dylib`vfprintf_l + 54 marco n.° 4: 0x00007fff6c666f72 libsystem_c.dylib`printf + 174 marco n.° 5: 0x0000000100000f6d test`main en test.c:5:2 marco n.° 6: 0x00007fff6c5dc3d5 libdyld.dylib`start + 1 (lldb) lista de fuentes 3 int main(void) { 4 char msg = "Hola, mundo!\n"; 5 printf("%s", msg); 6 return 0; 7 }
Desde la línea que comienza con frame #5
, LLDB indica que el error está en la línea 5 de test.c
. Al ejecutar source list
, vemos que esto hace referencia a la llamada a printf
. Según el código de excepción EXC_BAD_ACCESS
del backtrace, strlen
está intentando leer desde una región de memoria a la que no tiene acceso desreferenciando un puntero no válido. [11] Volviendo al código fuente, vemos que la variable msg
es de tipo char
pero contiene una cadena en lugar de un carácter. Para solucionar el problema, modificamos el código para indicar que msg
es un puntero a una cadena de chars
agregando el *
operador :
#incluir <stdio.h> int main ( void ) { char * msg = "Hola, mundo! \n " ; printf ( "%s" , msg ); devuelve 0 ; }
Después de volver a compilar y ejecutar el ejecutable nuevamente, LLDB ahora da el resultado correcto:
(lldb) target create "test" El ejecutable actual está establecido en 'test' (x86_64). (lldb) run Proceso 93319 lanzado: '/Users/wikipedia/test' (x86_64) ¡Hola, mundo! El proceso 93319 salió con el estado = 0 (0x00000000) (lldb)
LLDB ejecuta el programa, que imprime el resultado printf
en la pantalla. Una vez que el programa finaliza normalmente, LLDB indica que el proceso que lo ejecuta ha finalizado e imprime su estado de salida.