objective-c gdb debug-symbols

objective c - Importar información de volcado de clase en GDB



objective-c debug-symbols (3)

Es posible cargar un archivo de símbolos en gdb con el comando add-symbol-file . La parte más difícil es producir este archivo de símbolos.

Con la ayuda de libMachObjC (que es parte de class-dump de class-dump ), es muy fácil volcar todas las direcciones y sus correspondientes métodos Objective-C. He escrito una pequeña herramienta, objc-symbols que hace exactamente esto.

Usemos Calendar.app como ejemplo. Si intenta enumerar los símbolos con la herramienta nm , notará que la aplicación Calendario se ha eliminado:

$ nm -U /Applications/Calendar.app/Contents/MacOS/Calendar 0000000100000000 T __mh_execute_header 0000000005614542 - 00 0000 OPT radr://5614542

Pero con objc-symbols puede recuperar fácilmente las direcciones de todos los métodos faltados de Objective-C:

$ objc-symbols /Applications/Calendar.app 00000001000c774c +[CALCanvasAttributedText textWithPosition:size:text:] 00000001000c8936 -[CALCanvasAttributedText createTextureIfNeeded] 00000001000c8886 -[CALCanvasAttributedText bounds] 00000001000c883b -[CALCanvasAttributedText updateBezierRepresentation] ... 00000001000309eb -[CALApplication applicationDidFinishLaunching:] ...

Luego, con SymTabCreator puede crear un archivo de símbolos, que en realidad es un dylib vacío con todos los símbolos.

Usar objc-symbols y SymTabCreator juntos es sencillo:

$ objc-symbols /Applications/Calendar.app | SymTabCreator -o Calendar.stabs

Puedes comprobar que Calendar.stabs contiene todos los símbolos:

$ nm Calendar.stabs 000000010014a58b T +[APLCALSource printingCachedTextSize] 000000010013e7c5 T +[APLColorSource alternateGenerator] 000000010013e780 T +[APLColorSource defaultColorSource] 000000010013e7bd T +[APLColorSource defaultGenerator] 000000010011eb12 T +[APLConstraint constraintOfClass:withProperties:] ... 00000001000309eb T -[CALApplication applicationDidFinishLaunching:] ...

Ahora veamos que pasa en gdb:

$ gdb --silent /Applications/Calendar.app Reading symbols for shared libraries ................................. done

Sin el archivo de símbolos:

(gdb) b -[CALApplication applicationDidFinishLaunching:] Function "-[CALApplication applicationDidFinishLaunching:]" not defined. Make breakpoint pending on future shared library load? (y or [n]) n

Y después de cargar el archivo de símbolos:

(gdb) add-symbol-file Calendar.stabs add symbol table from file "Calendar.stabs"? (y or n) y Reading symbols from /Users/0xced/Calendar.stabs...done. (gdb) b -[CALApplication applicationDidFinishLaunching:] Breakpoint 1 at 0x1000309f2

Notará que la dirección del punto de interrupción no coincide exactamente con la dirección del símbolo (0x1000309f2 frente a 0x1000309eb, 7 bytes de diferencia), esto se debe a que gdb reconoce automáticamente el prólogo de la función y establece el punto de interrupción justo después.

Script GDB

Puede usar este script GDB para automatizar esto, dado que el ejecutable eliminado es el objetivo actual.

Agregue la secuencia de comandos de abajo a su .gdbinit , apunte al ejecutable eliminado y ejecute el comando objc_symbols en gdb:

$ gdb test ... (gdb) b +[TestClass randomNum] Function "+[TestClass randomNum]" not defined. (gdb) objc_symbols (gdb) b +[TestClass randomNum] Breakpoint 1 at 0x100000ee1 (gdb) ^D

define objc_symbols shell rm -f /tmp/gdb-objc_symbols set logging redirect on set logging file /tmp/gdb-objc_symbols set logging on info target set logging off shell target="$(head -1 /tmp/gdb-objc_symbols | head -1 | awk -F ''"'' ''{ print $2 }'')"; objc-symbols "$target" | SymTabCreator -o /tmp/gdb-symtab set logging on add-symbol-file /tmp/gdb-symtab set logging off end

¿Hay una manera de importar la salida de class-dump de class-dump a GDB?

Código de ejemplo:

$ cat > test.m #include <stdio.h> #import <Foundation/Foundation.h> @interface TestClass : NSObject + (int)randomNum; @end @implementation TestClass + (int)randomNum { return 4; // chosen by fair dice roll. // guaranteed to be random. } @end int main(void) { printf("num: %d/n", [TestClass randomNum]); return 0; } ^D

$ gcc test.m -lobjc -o test $ ./test num: 4 $ gdb test ... (gdb) b +[TestClass randomNum] Breakpoint 1 at 0x100000e5c (gdb) ^D $ strip test $ gdb test ... (gdb) b +[TestClass randomNum] Function "+[TestClass randomNum]" not defined. (gdb) ^D

$ class-dump -A test ... @interface TestClass : NSObject { } + (int)randomNum; // IMP=0x0000000100000e50 @end

Sé que ahora puedo usar b *0x0000000100000e50 en gdb , pero ¿hay alguna forma de modificar la tabla de símbolos de GDB para que acepte b +[TestClass randomNum] ?

Edición: sería preferible si funcionara con GDB v6 y no solo GDB v7, ya que GDB v6 es la última versión con los parches de Apple.


Puedes usar DSYMCreator .

  1. Con DSYMCreator, puede crear un archivo de símbolos a partir de un binario ejecutable de iOS.

    Es una cadena de herramientas, así que puedes usarla así.

    $ ./main.py --only-objc /path/to/binary/xxx

    Luego se /path/to/binary/xxx.symbol un archivo /path/to/binary/xxx.symbol , que es un símbolo de formato DWARF. Puedes importarlo a lldb por ti mismo.

  2. Aparte de eso, DSYMCreator también admite la exportación de símbolos desde IDA Pro, puede usarlo así.

    $ ./main.py /path/to/binary/xxx

    SÍ, simplemente ignora --only-objc flag. Luego, el IDA Pro se ejecutará automáticamente, y luego se /path/to/binary/xxx.symbol un archivo /path/to/binary/xxx.symbol , que es el archivo de símbolos.

Gracias por crear objc-symbols , que forma parte de la cadena de herramientas DSYMCreator.

Por cierto, https://github.com/tobefuturer/restore-symbol es otra opción.


No hay una forma directa de hacer esto (que yo sepa), pero parece una gran idea.

Y ahora hay una manera de hacerlo ... buena respuesta, ¡0xced!

El formato de archivo DWARF está bien documentado , IIRC y, como la fuente lldb está disponible, tiene un ejemplo funcional de un analizador.

Dado que la class-dump también está disponible, no debería ser demasiado difícil modificarla para generar la salida DWARF que luego podría cargarse en el depurador.

Obviamente, no podrías volcar símbolos con total fidelidad, pero esto probablemente sería muy útil.