background
After the launch of App, we usually use some tools such as Bugly to collect online crash, and the function call stack on the collection are all some function addresses. We cannot know which code under which file caused the crash. If we want to know which function caused the crash, We need to upload dSYM files generated after compilation. Why do we need dSYM files?
DSYM concept
What is a DWARF
DWARF is a fixed data format used by many compilers and debuggers to support source-level debugging
What is the dSYM
DSYM is a file that stores debugging information in DWARF format, that is, dSYM is a file.
To explore the dSYM
.o with debug symbol
1, we use firstclang
willtest.m
Compiled into.o
File,test.m
The content is shown below
clang -g -c test.m -o test.o
Copy the code
2, we use objcdump to view the header information of test.o
objdump --macho --private-headers test.o
Section
sectname __debug_str
segname __DWARF
addr 0x0000000000000158
size 0x00000000000000a9
offset 1616
align 2^0 (1)
reloff 0
nreloc 0
type S_REGULAR
attributes DEBUG
reserved1 0
reserved2 0
Copy the code
We can see that at compile time, the debugging information is stored in a section named __DWARF.
Executable file with debug symbol
1. We continue to use clang as an executable with debug symbols, and no longer use -c arguments
clang -g test.m -o test
Copy the code
2. View the segment information
bel@beldeMacBook-Pro dSYM % objdump --macho --private-headers test test: Mach header magic cputype cpusubtype caps filetype ncmds sizeofcmds flags MH_MAGIC_64 X86_64 ALL 0x00 EXECUTE 16 1048 NOUNDEFS DYLDLINK TWOLEVEL PIE Load command 0 cmd LC_SEGMENT_64 cmdsize 72 segname __PAGEZERO vmaddr 0x0000000000000000 vmsize 0x0000000100000000 fileoff 0 filesize 0 maxprot --- initprot --- nsects 0 flags (none) Load command 1 cmd LC_SEGMENT_64 cmdsize 232 segname __TEXT ... Section sectname __text segname __TEXT ... Section sectname __unwind_info segname __TEXT ... Load command 2 cmd LC_SEGMENT_64 cmdsize 152 segname __DATA_CONST ... Section sectname __objc_imageinfo segname __DATA_CONST ... Load command 3 cmd LC_SEGMENT_64 cmdsize 152 segname __DATA ... Section sectname __data segname __DATA ... Load command 4 cmd LC_SEGMENT_64 cmdsize 72 segname __LINKEDIT ... Load command 5 cmd LC_DYLD_INFO_ONLY cmdsize 48 rebase_off 0 rebase_size 0 bind_off 0 bind_size 0 weak_bind_off 0 weak_bind_size 0 lazy_bind_off 0 lazy_bind_size 0 export_off 49152 export_size 80 Load command 6 cmd LC_SYMTAB cmdsize 24 symoff 49240 nsyms 23 stroff 49608 strsize 192 Load command 7 cmd LC_DYSYMTAB cmdsize 80 .... Load command 8 cmd LC_LOAD_DYLINKER cmdsize 32 name /usr/lib/dyld (offset 12) Load command 9 cmd LC_UUID cmdsize 24 uuid 2890FF4F-897E-30b1-a90C-48a58b0b0146 Load Command 10 CMD LC_BUILD_VERSION cmdsize 32 Platform MacOS SDK 11.3 Minos 11.0 Ntools 1 tool ld version 650.9 Load command 11 CMD LC_SOURCE_VERSION cmdsize 16 version 0.0 Load command 12 CMD LC_MAIN cmdsize 24 entryoff 16256 stacksize 0 Load command 13 cmd LC_LOAD_DYLIB cmdsize 56 name /usr/lib/libSystem.B.dylib (offset 24) ....Copy the code
At this point, we find no information about __DWARF in the Mach O file,
3. View its symbol table
nm -pa test
bel@beldeMacBook-Pro dSYM % nm -pa test
0000000000000000 - 00 0000 SO /Users/bel/Desktop/dSYM/
0000000000000000 - 00 0000 SO test.m
0000000060e97f85 - 03 0001 OSO /var/folders/d2/_hhc47fd0cvd4b7n2hrcpxt80000gn/T/test-b74f6a.o
0000000100003f60 - 01 0000 BNSYM
0000000100003f60 - 01 0000 FUN _test
0000000000000010 - 00 0000 FUN
0000000000000010 - 01 0000 ENSYM
0000000100003f70 - 01 0000 BNSYM
0000000100003f70 - 01 0000 FUN _test_1
0000000000000010 - 00 0000 FUN
0000000000000010 - 01 0000 ENSYM
0000000100003f80 - 01 0000 BNSYM
0000000100003f80 - 01 0000 FUN _main
0000000000000035 - 00 0000 FUN
0000000000000035 - 01 0000 ENSYM
0000000000000000 - 00 0000 GSYM _global
0000000000000000 - 01 0000 SO
0000000100000000 T __mh_execute_header
0000000100008000 D _global
0000000100003f80 T _main
0000000100003f60 T _test
0000000100003f70 T _test_1
U dyld_stub_binder
Copy the code
In its symbol table, we see the _test, _test_1 symbols that we use,
summary
The compiler puts debugging information in the __DWARF section at compile time, removes the __DWARF section when linking, and puts symbolic information in the __DWARF section.
Generate a dSYM file
1. We use the compiled -g1 parameter to generate the dSYM file
clang -g1 test.m -o test
Copy the code
2. Run the dwarfdump command to view dSYM files
bel@beldeMacBook-Pro dSYM % dwarfdump test.dSYM test.dSYM/Contents/Resources/DWARF/test: file format Mach-O 64-bit x86-64 .debug_info contents: 0x00000000: Compile Unit: length = 0x00000063, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000067) 0x0000000b: DW_TAG_compile_unit DW_AT_producer ("Apple clang Version 12.0.5 (clang-1205.0.22.9)") DW_AT_language (DW_LANG_ObjC) DW_AT_name ("test.m") DW_AT_LLVM_sysroot ("/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk") DW_AT_APPLE_sdk ("MacOSX.sdk") DW_AT_stmt_list (0x00000000) DW_AT_comp_dir ("/Users/bel/Desktop/dSYM") DW_AT_APPLE_major_runtime_vers (0x02) DW_AT_low_pc (0x0000000100003f60) DW_AT_high_pc (0x0000000100003fb5) 0x00000033: DW_TAG_subprogram DW_AT_low_pc (0x0000000100003f60) DW_AT_high_pc (0x0000000100003f66) DW_AT_name ("test") 0x00000044: DW_TAG_subprogram DW_AT_low_pc (0x0000000100003f70) DW_AT_high_pc (0x0000000100003f76) DW_AT_name ("test_1") 0x00000055: DW_TAG_subprogram DW_AT_low_pc (0x0000000100003f80) DW_AT_high_pc (0x0000000100003fb5) DW_AT_name ("main") 0x00000066: NULLCopy the code
We can see that in dSYM files, debug symbols are stored in a certain format, including virtual memory address values and symbol names.
How to restore virtual memory addresses to symbols
Call stack containing debug symbols
Let’s open Xcode and create a new project to crash the App 3 seconds after it starts. The code is as follows:
Its CRSAH information is as follows:
crash
Occur in the-[ViewController warfTest]
Method inside.
Call stack without debug symbols
By default, we are inRelease
In modeThe App package
.Xcode
Will usestrip
Command,Local symbol
Take off, exportipa
Package generated whendSYM
File,Debug
In the mode, we need to putDeployment Postprocessing
Set toYes
. It is executed after each compilationstrip
Carry off sign
At this time, the crash log is:
From the log, we can not determine which function caused the crash.
After compiling and running, dSYM is generated
At this point, in Debug mode, the compilation only completes using strip to strip symbols, We set PROJECT -> Build Settings -> Build Options -> Debug Information Format to DWARF with dSYM File. And set Deployment Postprocessing to NO(NO unsigned) so that we can get the dSYM file
Restore debug symbols based on virtual addresses and dSYM
And then we run the project again, and then crash,
In line 3, the memory address value is 0x000000010A107eb4, which is equal to the virtual address value of the ASLR + function during execution.
First we need to get the ASLR value for this run:
(lldb) image list [ 0] 3B857210-92BA-359F-A96E-856AC9E5CB8F 0x000000010a107000 /Users/bel/Library/Developer/Xcode/DerivedData/dSYMProject-ccrqorgatcanaacgnyihzhjcjcwi/Build/Products/Debug-iphonesimul ator/dSYMProject.app/dSYMProject /Users/bel/Library/Developer/Xcode/DerivedData/dSYMProject-ccrqorgatcanaacgnyihzhjcjcwi/Build/Products/Debug-iphonesimul ator/dSYMProject.app.dSYM/Contents/Resources/DWARF/dSYMProjectCopy the code
ASLR = 0x000000010A107000-0x0000000100000000 (vmsize), The virtual address of this function is 0x000000010a107eb4-0x00000000A107000 = 0x100000EB4
Find the symbol for this address in the dSYM file:
bel@beldeMacBook-Pro ~ % dwarfdump --lookup 0x100000EB4 /Users/bel/Library/Developer/Xcode/DerivedData/dSYMProject-ccrqorgatcanaacgnyihzhjcjcwi/Build/Products/Debug-iphonesimul ator/dSYMProject.app.dSYM /Users/bel/Library/Developer/Xcode/DerivedData/dSYMProject-ccrqorgatcanaacgnyihzhjcjcwi/Build/Products/Debug-iphonesimul ator/dSYMProject.app.dSYM/Contents/Resources/DWARF/dSYMProject: file format Mach-O 64-bit x86-64 0x000474bb: Compile Unit: length = 0x0000023d, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x000476fc) 0x000474c6: DW_TAG_compile_unit DW_AT_producer ("Apple clang Version 11.0.3 (clang-1103.0.32.62)") DW_AT_language (DW_LANG_ObjC) DW_AT_name ("/Users/bel/Desktop/dSYMProject/dSYMProject/ViewController.m") DW_AT_stmt_list (0x0000a891) DW_AT_comp_dir ("/Users/bel/Desktop/dSYMProject") DW_AT_APPLE_major_runtime_vers (0x02) DW_AT_low_pc (0x0000000100000ce0) DW_AT_high_pc (0x0000000100000ef6) 0x000475dd: DW_TAG_subprogram DW_AT_low_pc (0x0000000100000e70) DW_AT_high_pc (0x0000000100000ef6) DW_AT_frame_base (DW_OP_reg6 RBP) DW_AT_object_pointer (0x000475f6) DW_AT_name ("-[ViewController warfTest]") DW_AT_decl_file ("/Users/bel/Desktop/dSYMProject/dSYMProject/ViewController.m") DW_AT_decl_line (26) DW_AT_prototyped (true) Line info: file 'ViewController.m', line 29, column 18, start line 26 bel@beldeMacBook-Pro ~ %Copy the code
Thus, we can conclude that 0x000000010A107eb4 represents the [ViewController warfTest] method at line 29 in the viewController.m file. This allows us to restore debug symbols based on address values and dSYM files.
conclusion
1. DSYM is a file in DWARF format,DWARF is a format for storing debugging information. 2, Deployment Postprocessing == YES and strip == All Symbols will remove All local Symbols during compilation. 3, When Deployment Postprocessing == NO and Debug Information Format == DWAR with dSYM File, dSYM will be generated after compilation. 4. According to the offset memory address value and ASLR, the real virtual address value of the function can be obtained. According to the real virtual address value, its debugging information can be obtained in the dSYM file.