Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mach-O, lldb, dSYM на практике — Владислав Алек...

AvitoTech
December 02, 2017

Mach-O, lldb, dSYM на практике — Владислав Алексеев (Avito)

В докладе речь пойдёт о бинарном формате исполняемых файлов Mach-O, об отладочной информации и объектных файлах. Рассмотрим, как работают брейкпоинты и символизация крешлогов. Поймем, когда и зачем нам нужны файлы dSYM, а в каких случаях их создавать совершенно не требуется. Также изучим случаи непрямого использования dSYM-файлов для анализа содержимого скомпилированного бинарного файла.

Avito iOS Winter Edition
02/12/2017

AvitoTech

December 02, 2017
Tweet

More Decks by AvitoTech

Other Decks in Technology

Transcript

  1. 21

  2. 22

  3. 38

  4. Брейкпоинт «со стороны» (lldb) b -[SimpleClass crash] Breakpoint 1: where

    = mytool`-[SimpleClass crash] + 35 at SimpleClass.m:14, address = 0x0000000100000d53 Установка брейкпоинта по имени метода: 39
  5. Брейкпоинт «со стороны» (lldb) b SimpleClass.m:17 Breakpoint 4: where =

    mytool`-[SimpleClass crash] + 117 at SimpleClass.m:17, address = 0x0000000100000da5 Установка брейкпоинта в конкретной позиции в исходном файле: 40
  6. Брейкпоинт «со стороны» (lldb) b /Users/vvalekseev/Developer/SimpleTool/SimpleTool/SimpleClass.m:17 Breakpoint 4: where =

    mytool`-[SimpleClass crash] + 117 at SimpleClass.m:17, address = 0x0000000100000da5 Установка брейкпоинта в конкретной позиции в исходном файле, Xcode-way: 41
  7. Брейкпоинт «со стороны» (lldb) b /Users/vvalekseev/Developer/SimpleTool/SimpleTool/SimpleClass.m:17 Breakpoint 4: where =

    mytool`-[SimpleClass crash] + 117 at SimpleClass.m:17, address = 0x0000000100000da5 (lldb) b 0x0000000100000da5 Breakpoint 5: address = 0x0000000100000da5 Установка брейкпоинта по адресу: 42
  8. Как работают брейкпоинты? ❖ Аппаратно - в debug регистр записывается

    адрес остановки ❖ Программно - по адресу остановки подменяется инструкция ❖ Интересный доклад - http://events.linuxfoundation.org/sites/events/ files/slides/slides_16.pdf 44
  9. Генерация debug info $ clang -fobjc-arc -g -c SimpleClass.m -o

    SimpleClass.o $ clang -fobjc-arc -g -c main.m -o main.o $ clang -fobjc-arc -fobjc-link-runtime SimpleClass.o main.o -o mytool Компиляция: Линковка: 49
  10. 55

  11. loader.h struct mach_header { uint32_t magic; /* mach magic number

    identifier */ cpu_type_t cputype; /* cpu specifier */ cpu_subtype_t cpusubtype; /* machine specifier */ uint32_t filetype; /* type of file */ uint32_t ncmds; /* number of load commands */ uint32_t sizeofcmds; /* the size of all the load commands */ uint32_t flags; /* flags */ }; #define MH_MAGIC 0xfeedface /* the mach magic number */ #define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */ 61
  12. loader.h struct load_command { uint32_t cmd; /* type of load

    command */ uint32_t cmdsize; /* total size of command in bytes */ }; 62
  13. loader.h #define LC_SEGMENT 0x1 /* segment of this file to

    be mapped */ #define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ #define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ #define LC_THREAD 0x4 /* thread */ #define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ #define LC_LOADFVMLIB 0x6 /* load a specified fixed VM shared library */ #define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */ #define LC_IDENT 0x8 /* object identification info (obsolete) */ #define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ #define LC_PREPAGE 0xa /* prepage command (internal use) */ #define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ #define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ #define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ #define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ #define LC_ID_DYLINKER 0xf /* dynamic linker identification */ #define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ … 63
  14. loader.h struct symtab_command { uint32_t cmd; /* LC_SYMTAB */ uint32_t

    cmdsize; /* sizeof(struct symtab_command) */ uint32_t symoff; /* symbol table offset */ uint32_t nsyms; /* number of symbol table entries */ uint32_t stroff; /* string table offset */ uint32_t strsize; /* string table size in bytes */ }; 64 struct load_command { uint32_t cmd; uint32_t cmdsize; };
  15. struct symtab_command { uint32_t cmd; /* LC_SYMTAB */ uint32_t cmdsize;

    /* sizeof(struct symtab_command) */ uint32_t symoff; /* symbol table offset */ uint32_t nsyms; /* number of symbol table entries */ uint32_t stroff; /* string table offset */ uint32_t strsize; /* string table size in bytes */ }; struct load_command { uint32_t cmd; uint32_t cmdsize; }; loader.h 65
  16. loader.h struct symtab_command { uint32_t cmd; /* LC_SYMTAB */ uint32_t

    cmdsize; /* sizeof(struct symtab_command) */ uint32_t symoff; /* symbol table offset */ uint32_t nsyms; /* number of symbol table entries */ uint32_t stroff; /* string table offset */ uint32_t strsize; /* string table size in bytes */ }; 66
  17. loader.h struct symtab_command { uint32_t cmd; /* LC_SYMTAB */ uint32_t

    cmdsize; /* sizeof(struct symtab_command) */ uint32_t symoff; /* symbol table offset */ uint32_t nsyms; /* number of symbol table entries */ uint32_t stroff; /* string table offset */ uint32_t strsize; /* string table size in bytes */ }; 67
  18. Mach-O $ nm -a mytool 0000000000000000 - 01 0000 SO

    0000000000000000 - 01 0000 SO 0000000000000074 - 00 0000 FUN 0000000000000074 - 01 0000 ENSYM 000000000000007f - 01 0000 ENSYM 000000000000007f - 00 0000 FUN 0000000100000de0 - 01 0000 BNSYM 0000000100000e60 - 01 0000 BNSYM 0000000100000de0 t -[SimpleClass crash] 0000000100000de0 - 01 0000 FUN -[SimpleClass crash] 0000000000000000 - 00 0000 SO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/ 0000000000000000 - 00 0000 SO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/ 000000005a0c056a - 03 0001 OSO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/SimpleClass.o 000000005a0c0572 - 03 0001 OSO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/main.o 68
  19. Mach-O 0000000000000074 - 00 0000 FUN 0000000000000074 - 01 0000

    ENSYM 000000000000007f - 01 0000 ENSYM 000000000000007f - 00 0000 FUN 0000000100000de0 - 01 0000 BNSYM 0000000100000e60 - 01 0000 BNSYM 0000000100000de0 t -[SimpleClass crash] 0000000100000de0 - 01 0000 FUN -[SimpleClass crash] 0000000000000000 - 00 0000 SO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/ 0000000000000000 - 00 0000 SO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/ 000000005a0c056a - 03 0001 OSO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/SimpleClass.o 000000005a0c0572 - 03 0001 OSO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/main.o 0000000000000000 - 00 0000 SO SimpleClass.m U _OBJC_CLASS_$_NSException U _OBJC_CLASS_$_NSObject 0000000000000000 - 00 0000 GSYM _OBJC_CLASS_$_SimpleClass 00000001000011a0 S _OBJC_CLASS_$_SimpleClass U _OBJC_METACLASS_$_NSObject 0000000000000000 - 00 0000 GSYM _OBJC_METACLASS_$_SimpleClass 0000000100001178 S _OBJC_METACLASS_$_SimpleClass U ___CFConstantStringClassReference 69
  20. dwarfdump $ dwarfdump SimpleClass.o ---------------------------------------------------------------------- File: SimpleClass.o (x86_64) ---------------------------------------------------------------------- .debug_info

    contents: 0x00000000: Compile Unit: length = 0x000000b3 version = 0x0004 abbr_offset = 0x00000000 addr_size = 0x08 (next CU at 0x000000b7) 0x0000000b: TAG_compile_unit [1] * AT_producer( "Apple LLVM version 9.0.0 (clang-900.0.38)" ) AT_language( DW_LANG_ObjC ) AT_name( "SimpleClass.m" ) AT_stmt_list( 0x00000000 ) AT_comp_dir( "/Users/vvalekseev/Developer/SimpleTool/SimpleTool" ) AT_APPLE_major_runtime_vers( 0x02 ) AT_low_pc( 0x0000000000000000 ) AT_high_pc( 0x00000074 ) 71
  21. dwarfdump 0x0000005d: TAG_pointer_type [7] AT_type( {0x00000062} ( objc_class ) )

    0x00000062: TAG_structure_type [8] AT_name( "objc_class" ) AT_declaration( true ) 0x00000067: TAG_subprogram [9] * AT_low_pc( 0x0000000000000000 ) AT_high_pc( 0x00000074 ) AT_frame_base( rbp ) AT_object_pointer( {0x00000080} ) AT_name( "-[SimpleClass crash]" ) AT_decl_file( "/Users/vvalekseev/Developer/SimpleTool/ SimpleTool/SimpleClass.m" ) AT_decl_line( 13 ) AT_prototyped( true ) 0x00000080: TAG_formal_parameter [10] AT_location( fbreg -8 ) AT_name( "self" ) AT_type( {0x00000099} ( const SimpleClass* ) ) AT_artificial( true ) 72
  22. dwarfdump 0x0000005d: TAG_pointer_type [7] AT_type( {0x00000062} ( objc_class ) )

    0x00000062: TAG_structure_type [8] AT_name( "objc_class" ) AT_declaration( true ) 0x00000067: TAG_subprogram [9] * AT_low_pc( 0x0000000000000000 ) AT_high_pc( 0x00000074 ) AT_frame_base( rbp ) AT_object_pointer( {0x00000080} ) AT_name( "-[SimpleClass crash]" ) AT_decl_file( "/Users/vvalekseev/Developer/SimpleTool/ SimpleTool/SimpleClass.m" ) AT_decl_line( 13 ) AT_prototyped( true ) 0x00000080: TAG_formal_parameter [10] AT_location( fbreg -8 ) AT_name( "self" ) AT_type( {0x00000099} ( const SimpleClass* ) ) AT_artificial( true ) 73
  23. 0x00000067: TAG_subprogram [9] * AT_low_pc( 0x0000000000000000 ) AT_high_pc( 0x00000074 )

    AT_frame_base( rbp ) AT_object_pointer( {0x00000080} ) AT_name( "-[SimpleClass crash]" ) AT_decl_file( "/Users/vvalekseev/Developer/SimpleTool/ SimpleTool/SimpleClass.m" ) AT_decl_line( 13 ) AT_prototyped( true ) 0x00000080: TAG_formal_parameter [10] AT_location( fbreg -8 ) AT_name( "self" ) AT_type( {0x00000099} ( const SimpleClass* ) ) AT_artificial( true ) 0x0000008c: TAG_formal_parameter [10] AT_location( fbreg -16 ) AT_name( "_cmd" ) AT_type( {0x000000a3} ( SEL ) ) AT_artificial( true ) 0x00000098: NULL 74
  24. $ dwarfdump --debug-line SimpleClass.o ---------------------------------------------------------------------- File: SimpleClass.o (x86_64) ---------------------------------------------------------------------- .debug_line

    contents: ---------------------------------------------------------------------- debug_line[0x00000000] ---------------------------------------------------------------------- Line table prologue: total_length: 0x000000a9 version: 0x0002 prologue_length: 0x00000057 min_inst_length: 0x01 default_is_stmt: 0x01 line_base: -5 line_range: 14 opcode_base: 0x0d standard_opcode_lengths[ DW_LNS_copy ] = 0 standard_opcode_lengths[ DW_LNS_advance_pc ] = 1 standard_opcode_lengths[ DW_LNS_advance_line ] = 1 standard_opcode_lengths[ DW_LNS_set_file ] = 1 standard_opcode_lengths[ DW_LNS_set_column ] = 1 standard_opcode_lengths[ DW_LNS_negate_stmt ] = 0 77
  25. $ dwarfdump --debug-line SimpleClass.o ---------------------------------------------------------------------- File: SimpleClass.o (x86_64) ---------------------------------------------------------------------- .debug_line

    contents: ---------------------------------------------------------------------- debug_line[0x00000000] ---------------------------------------------------------------------- Line table prologue: total_length: 0x000000a9 version: 0x0002 prologue_length: 0x00000057 min_inst_length: 0x01 default_is_stmt: 0x01 line_base: -5 line_range: 14 opcode_base: 0x0d standard_opcode_lengths[ DW_LNS_copy ] = 0 standard_opcode_lengths[ DW_LNS_advance_pc ] = 1 standard_opcode_lengths[ DW_LNS_advance_line ] = 1 standard_opcode_lengths[ DW_LNS_set_file ] = 1 standard_opcode_lengths[ DW_LNS_set_column ] = 1 standard_opcode_lengths[ DW_LNS_negate_stmt ] = 0 78
  26. file_names[ 1] 0 0x00000000 0x00000000 SimpleClass.m file_names[ 2] 1 0x00000000

    0x00000000 NSObject.h file_names[ 3] 2 0x00000000 0x00000000 SimpleClass.h 0x00000061: DW_LNE_set_address( 0x0000000000000000 ) 0x0000006c: DW_LNS_advance_line( 12 ) 0x0000006e: DW_LNS_copy 0x0000000000000000 1 13 0 is_stmt 0x0000006f: DW_LNS_set_column( 6 ) 0x00000071: DW_LNS_set_prologue_end 0x00000072: DW_LNS_advance_pc( 35 ) 0x00000074: address += 0, line += 1 0x0000000000000023 1 14 6 is_stmt prologue_end 0x00000075: DW_LNE_set_discriminator( 1 ) 0x00000079: DW_LNS_negate_stmt 0x0000007a: DW_LNS_const_add_pc( 0x0000000000000011 ) 0x0000007b: address += 10, line += 0 0x0000000000000044 1 14 6 0x0000007c: DW_LNS_set_column( 5 ) 0x0000007e: address += 8, line += 0 0x000000000000004c 1 14 5 0x0000007f: DW_LNE_set_discriminator( 2 ) 79
  27. 0x0000007f: DW_LNE_set_discriminator( 2 ) 0x00000083: address += a, line +=

    0 0x0000000000000056 1 14 5 0x00000084: address += c, line += 0 0x0000000000000062 1 14 5 0x00000085: DW_LNE_set_discriminator( 3 ) 0x00000089: address += 4, line += 0 0x0000000000000066 1 14 5 0x0000008a: DW_LNS_negate_stmt 0x0000008b: address += f, line += 3 0x0000000000000075 1 17 5 is_stmt 0x0000008c: DW_LNS_set_column( 9 ) 0x0000008e: address += a, line += 1 0x000000000000007f 1 18 9 is_stmt 0x0000008f: DW_LNS_set_column( 6 ) 0x00000091: address += 7, line += 1 0x0000000000000086 1 19 6 is_stmt 0x00000092: DW_LNS_set_column( 1 ) 80
  28. 0x0000008a: DW_LNS_negate_stmt 0x0000008b: address += f, line += 3 0x0000000000000075

    1 17 5 is_stmt $ dwarfdump -a SimpleClass.o ---------------------------------------------------------------------- File: SimpleClass.o (x86_64) ---------------------------------------------------------------------- 0x00000067: [0x0000000000000000 - 0x0000000000000098) -[SimpleClass crash] 0x000000a7: [0x00000000000000a0 - 0x00000000000000d1) -[SimpleClass anotherMethod] Адрес строки 17 внутри файла SimpleClass.o: Адреса всех функций внутри SimpleClass.o: 82
  29. $ dwarfdump -a -e SimpleClass.o ---------------------------------------------------------------------- File: SimpleClass.o (x86_64) ----------------------------------------------------------------------

    0x00000067: [0x0000000000000000 - 0x0000000000000098) -[SimpleClass crash] 0x000000a7: [0x00000000000000a0 - 0x00000000000000d1) -[SimpleClass anotherMethod] Адреса всех функций внутри SimpleClass.o: Файл начинается с -[SimpleClass crash]. Внутри слинкованого бинарника функция имеет адрес: $ nm -a mytool 0000000000000000 - 01 0000 SO 0000000000000000 - 01 0000 SO 0000000000000031 - 00 0000 FUN 0000000000000031 - 01 0000 ENSYM 000000000000007f - 01 0000 ENSYM 000000000000007f - 00 0000 FUN 00000000000000a0 - 00 0000 FUN 83
  30. Файл начинается с -[SimpleClass crash]. Внутри слинкованого бинарника функция имеет

    адрес: $ nm -a mytool 0000000000000000 - 01 0000 SO 0000000000000000 - 01 0000 SO 0000000000000031 - 00 0000 FUN 0000000000000031 - 01 0000 ENSYM 000000000000007f - 01 0000 ENSYM 000000000000007f - 00 0000 FUN 00000000000000a0 - 00 0000 FUN 00000000000000a0 - 01 0000 ENSYM 0000000100000d30 - 01 0000 BNSYM 0000000100000dd0 - 01 0000 BNSYM 0000000100000e10 - 01 0000 BNSYM 0000000100000dd0 t -[SimpleClass anotherMethod] 0000000100000dd0 - 01 0000 FUN -[SimpleClass anotherMethod] 0000000100000d30 t -[SimpleClass crash] 0000000100000d30 - 01 0000 FUN -[SimpleClass crash] 0000000000000000 - 00 0000 SO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/ 0000000000000000 - 00 0000 SO /Users/vvalekseev/Developer/SimpleTool/ SimpleTool/ 84
  31. 0000000100000d30 - 01 0000 FUN -[SimpleClass crash] + 0000000000000075 =

    0x00000100000DA5 Значит, брейкпоинт ставим по адресу: 85
  32. Проверяем через LLDB: $ lldb (lldb) target create mytool Current

    executable set to 'mytool' (x86_64). (lldb) b SimpleClass.m:17 Breakpoint 1: where = mytool`-[SimpleClass crash] + 117 at SimpleClass.m:17, address = 0x0000000100000da5 87
  33. Аналогично дебаггер подцепляет контекст из исходного кода: (lldb) b -[SimpleClass

    crash] Breakpoint 1: where = mytool`-[SimpleClass crash] + 35 at SimpleClass.m:14, address = 0x0000000100000d53 (lldb) run Process 5325 launched: '/Users/vvalekseev/Developer/SimpleTool/SimpleTool/ mytool' (x86_64) Process 5325 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000d53 mytool`-[SimpleClass crash] (self=0x0000000100406720, _cmd="crash") at SimpleClass.m:14 11 @implementation SimpleClass 12 13 - (void)crash { -> 14 [[NSException exceptionWithName:@"ExceptionName" 15 reason:@"Reason!" 16 userInfo:nil] raise]; 17 NSLog(@"I raised an exception!"); Target 0: (mytool) stopped. 90
  34. Крешлоги $ ./mytool.stripped 2017-11-15 14:34:53.100 mytool.stripped[5385:4492270] *** Terminating app due

    to uncaught exception 'ExceptionName', reason: 'Reason!' *** First throw call stack: ( 0 CoreFoundation 0x00007fff56f922fb __exceptionPreprocess + 171 1 libobjc.A.dylib 0x00007fff7d903c76 objc_exception_throw + 48 2 CoreFoundation 0x00007fff56f92249 -[NSException raise] + 9 3 mytool.stripped 0x000000010facfd92 mytool.stripped + 3474 4 mytool.stripped 0x000000010facfe6e mytool.stripped + 3694 5 libdyld.dylib 0x00007fff7e4f2145 start + 1 6 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException Abort trap: 6 102
  35. dsymutil $ dsymutil mytool $ dwarfdump -a mytool.dSYM/ ---------------------------------------------------------------------- File:

    mytool.dSYM/Contents/Resources/DWARF/mytool (x86_64) ---------------------------------------------------------------------- 0x00000067: [0x0000000100000d30 - 0x0000000100000dc8) -[SimpleClass crash] 0x000000a7: [0x0000000100000dd0 - 0x0000000100000e01) -[SimpleClass anotherMethod] 0x00000137: [0x0000000100000e10 - 0x0000000100000e8f) main .debug_abbrev contents: Abbrev table for offset: 0x00000000 ... 107
  36. Невидимая связь $ dwarfdump --uuid mytool UUID: 65C365E2-5955-3AF1-B12E-1403E3B3ACF4 (x86_64) mytool

    $ dwarfdump --uuid mytool.dSYM/ UUID: 65C365E2-5955-3AF1-B12E-1403E3B3ACF4 (x86_64) mytool.dSYM/Contents/ Resources/DWARF/mytool 108
  37. Невидимая связь LLDB не загрузит dSYM, если UUID не совпадают:

    $ lldb (lldb) target create mytool.stripped.wronguuid (lldb) target symbols add mytool.dSYM/Contents/Resources/DWARF/mytool error: symbol file '/Users/vvalekseev/Developer/SimpleTool/SimpleTool/ mytool.dSYM/Contents/Resources/DWARF/mytool' does not match any existing module 109
  38. Крешлог LLDB умеет символизировать крешлоги: (lldb) target create mytool.stripped Current

    executable set to 'mytool.stripped' (x86_64). (lldb) target symbols add mytool.dSYM/Contents/Resources/DWARF/mytool symbol file '/Users/vvalekseev/Developer/SimpleTool/SimpleTool/mytool.dSYM/ Contents/Resources/DWARF/mytool' has been added to '/Users/vvalekseev/ Developer/SimpleTool/SimpleTool/mytool.stripped' 115
  39. Крешлог LLDB умеет символизировать крешлоги: (lldb) target create mytool.stripped Current

    executable set to 'mytool.stripped' (x86_64). (lldb) target symbols add mytool.dSYM/Contents/Resources/DWARF/mytool symbol file '/Users/vvalekseev/Developer/SimpleTool/SimpleTool/mytool.dSYM/ Contents/Resources/DWARF/mytool' has been added to '/Users/vvalekseev/ Developer/SimpleTool/SimpleTool/mytool.stripped' (lldb) command script import lldb.macosx.crashlog "crashlog" and "save_crashlog" command installed, use the "--help" option for detailed help "malloc_info", "ptr_refs", "cstr_refs", "find_variable", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help. 116
  40. Крешлог LLDB умеет символизировать крешлоги: (lldb) crashlog /Users/vvalekseev/Developer/SimpleTool/SimpleTool/log.crash Getting symbols

    for 65C365E2-5955-3AF1-B12E-1403E3B3ACF4 /Users/vvalekseev/ Developer/SimpleTool/SimpleTool/mytool.stripped... ok Application Specific Backtrace[1] [ 0] 0x00007fff56f922fb CoreFoundation`__exceptionPreprocess + 171 0x00007fff56f922e9: callq 0x8b100 ; __CFLookUpClass 0x00007fff56f922ee: movq 0x4cf5fb(%rip), %rsi ; "" 0x00007fff56f922f5: movq %rax, %rdi 0x00007fff56f922f8: callq *%r12 -> 0x00007fff56f922fb: movq %rax, %r14 0x00007fff56f922fe: testq %r15, %r15 0x00007fff56f92301: je 0x10b325 ; <+213> 0x00007fff56f92303: movq 0x4d1006(%rip), %rax ; NSException.reserved 0x00007fff56f9230a: movq (%rbx,%rax), %rdi 117
  41. 0x00007fff56f922fe: testq %r15, %r15 0x00007fff56f92301: je 0x10b325 ; <+213> 0x00007fff56f92303:

    movq 0x4d1006(%rip), %rax ; NSException.reserved 0x00007fff56f9230a: movq (%rbx,%rax), %rdi [ 1] 0x00007fff7d903c75 libobjc.A.dylib`objc_exception_throw + 47 [ 2] 0x00007fff56f92248 CoreFoundation`-[NSException raise] + 8 [ 3] 0x0000000102de4d91 mytool.stripped`-[SimpleClass crash] + 97 at SimpleClass.m:14:5 [ 4] 0x0000000102de4e6d mytool.stripped`main + 93 at main.m:10:9 [ 5] 0x00007fff7e4f2144 libdyld.dylib`start Thread[0] EXC_CRASH (SIGABRT) (0x0000000000000000, 0x0000000000000000) [ 0] 0x00007fff7e641fce libsystem_kernel.dylib`__pthread_kill + 10 0x00007fff7e641fc4: movl $0x2000148, %eax ; imm = 0x2000148 0x00007fff7e641fc9: movq %rcx, %r10 0x00007fff7e641fcc: syscall -> 0x00007fff7e641fce: jae 0x1bfd8 ; <+20> 0x00007fff7e641fd0: movq %rax, %rdi 0x00007fff7e641fd3: jmp 0x1376c ; cerror_nocancel 0x00007fff7e641fd8: retq 0x00007fff7e641fd9: nop [ 1] 0x00007fff7e77f14f libsystem_pthread.dylib`pthread_kill + 332 118
  42. 126

  43. 145

  44. 148 Полностью выключаем dSYM для Pod-ов: post_install do |installer| installer.pods_project.targets.each

    do |target| target.build_configurations.each do |config| config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf' end end
  45. 149 Выключаем dSYM для не-Release сборок у основного таргета: post_install

    do |installer| installer.aggregate_targets.each do |target| target.xcconfigs.each do |config_name, config_file| if ['Debug', 'Test'].include? config_name config_file.attributes['DEBUG_INFORMATION_FORMAT'] = 'dwarf' config_file.attributes['ONLY_ACTIVE_ARCH'] = 'YES' elsif ['Enterprise', 'Release'].include? config_name config_file.attributes['DEBUG_INFORMATION_FORMAT'] = 'dwarf-with-dsym' config_file.attributes['ONLY_ACTIVE_ARCH'] = 'NO' else raise "Unknown configuration: " + config_name end xcconfig_path = target.xcconfig_path(config_name) config_file.save_as(xcconfig_path) end end
  46. 150 Выключаем dSYM для не-Release сборок у основного таргета: post_install

    do |installer| installer.aggregate_targets.each do |target| target.xcconfigs.each do |config_name, config_file| if ['Debug', 'Test'].include? config_name config_file.attributes['DEBUG_INFORMATION_FORMAT'] = 'dwarf' config_file.attributes['ONLY_ACTIVE_ARCH'] = 'YES' elsif ['Enterprise', 'Release'].include? config_name config_file.attributes['DEBUG_INFORMATION_FORMAT'] = 'dwarf-with-dsym' config_file.attributes['ONLY_ACTIVE_ARCH'] = 'NO' else raise "Unknown configuration: " + config_name end xcconfig_path = target.xcconfig_path(config_name) config_file.save_as(xcconfig_path) end end
  47. 151 Выключаем dSYM для не-Release сборок у основного таргета: post_install

    do |installer| installer.aggregate_targets.each do |target| target.xcconfigs.each do |config_name, config_file| if ['Debug', 'Test'].include? config_name config_file.attributes['DEBUG_INFORMATION_FORMAT'] = 'dwarf' config_file.attributes['ONLY_ACTIVE_ARCH'] = 'YES' elsif ['Enterprise', 'Release'].include? config_name config_file.attributes['DEBUG_INFORMATION_FORMAT'] = 'dwarf-with-dsym' config_file.attributes['ONLY_ACTIVE_ARCH'] = 'NO' else raise "Unknown configuration: " + config_name end xcconfig_path = target.xcconfig_path(config_name) config_file.save_as(xcconfig_path) end end
  48. Recap ❖ Проверьте ваши настройки генерации dSYM - не нужен

    для Debug! ❖ Прогоните скриптик - может, есть возможность уменьшить бинарник ❖ Амимоно - нестрашный зверь, но стоит использовать по-умному 152
  49. Ссылки ❖ Доклад про дебаггинг под Линуксом: http://events.linuxfoundation.org/ sites/events/files/slides/slides_16.pdf ❖

    Apple’s Lazy DWARF Scheme: http://wiki.dwarfstd.org/index.php? title=Apple%27s_%22Lazy%22_DWARF_Scheme ❖ Точки врезания в LLDB для поддержки Lazy DWARF Scheme: https://lldb.llvm.org/symbols.html
  50. КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ

    КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ КОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦКОНЕЦ 154