what the structure of dsym file?
Asked Answered
P

3

6

What's structure of a dsym file generated when build the app. I know it contain DWARF debug info, but what's a dsym file. I want to read the DWARF info in it.

Is it just a Mach-O binary file that contain only debug sections? How do I pass it to a DWARF parse tool like pyelftool, which read the DWARF info in a ELF file's debug sections.

I use objdump -h to print the sections of a dsym file ( a .dsym file is a package, I just refer the binary file in the package )

/Users/luna/Desktop/EarList.app.dSYM/Contents/Resources/DWARF/EarList:     file format mach-o-i386

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00001738  000026e0  000026e0  00000000  2**4
                  ALLOC, LOAD, CODE
  1 .symbol_stub  00000054  00003e18  00003e18  00000000  2**1
                  ALLOC, LOAD, CODE
  2 __TEXT.__stub_helper 00000098  00003e6c  00003e6c  00000000  2**2
                  ALLOC, LOAD, READONLY, CODE
  3 .const        00000010  00003f08  00003f08  00000000  2**3
                  ALLOC, LOAD, READONLY, DATA
  4 __TEXT.__objc_methname 000007db  00003f18  00003f18  00000000  2**0
                  ALLOC, LOAD, READONLY, CODE
  5 .cstring      000001a9  000046f3  000046f3  00000000  2**0
                  ALLOC, LOAD, READONLY, DATA
  6 __TEXT.__objc_classname 0000003c  0000489c  0000489c  00000000  2**0
                  ALLOC, LOAD, READONLY, CODE
  7 __TEXT.__objc_methtype 0000049d  000048d8  000048d8  00000000  2**0
                  ALLOC, LOAD, READONLY, CODE
  8 __TEXT.__unwind_info 0000007c  00004d75  00004d75  00000000  2**0
                  ALLOC, LOAD, READONLY, CODE
  9 .eh_frame     00000204  00004df8  00004df8  00000000  2**3
                  ALLOC, LOAD, READONLY, DATA
 10 __DATA.__program_vars 00000014  00005000  00005000  00000000  2**2
                  ALLOC, LOAD, DATA
 11 .non_lazy_symbol_pointer 00000008  00005014  00005014  00000000  2**2
                  ALLOC, LOAD, DATA
 12 .lazy_symbol_pointer 00000038  0000501c  0000501c  00000000  2**2
                  ALLOC, LOAD, DATA
 13 __DATA.__objc_classlist 00000008  00005054  00005054  00000000  2**2
                  ALLOC, LOAD, DATA
 14 __DATA.__objc_protolist 00000008  0000505c  0000505c  00000000  2**2
                  ALLOC, LOAD, DATA
 15 __DATA.__objc_imageinfo 00000008  00005064  00005064  00000000  2**2
                  ALLOC, LOAD, DATA
 16 __DATA.__objc_const 00000518  00005070  00005070  00000000  2**3
                  ALLOC, LOAD, DATA
 17 __DATA.__objc_selrefs 00000054  00005588  00005588  00000000  2**2
                  ALLOC, LOAD, DATA
 18 __DATA.__objc_classrefs 00000010  000055dc  000055dc  00000000  2**2
                  ALLOC, LOAD, DATA
 19 __DATA.__objc_superrefs 00000004  000055ec  000055ec  00000000  2**2
                  ALLOC, LOAD, DATA
 20 __DATA.__objc_data 00000050  000055f0  000055f0  00000000  2**2
                  ALLOC, LOAD, DATA
 21 .cfstring     00000290  00005640  00005640  00000000  2**2
                  ALLOC, LOAD, DATA
 22 __DATA.__objc_ivar 00000004  000058d0  000058d0  00000000  2**2
                  ALLOC, LOAD, DATA
 23 .data         00000058  000058d4  000058d4  00000000  2**2
                  ALLOC, LOAD, DATA
 24 __DATA.__common 00000010  0000592c  0000592c  00000000  2**2
                  ALLOC
 25 .debug_abbrev 0000028a  00008000  00008000  00002000  2**0
                  CONTENTS, DEBUGGING
 26 .debug_aranges 000000c0  0000828a  0000828a  0000228a  2**0
                  CONTENTS, DEBUGGING
 27 .debug_info   0000813c  0000834a  0000834a  0000234a  2**0
                  CONTENTS, DEBUGGING
 28 __DWARF.__debug_inlined 00000038  00010486  00010486  0000a486  2**0
                  CONTENTS, ALLOC, LOAD, DATA
 29 .debug_line   00001205  000104be  000104be  0000a4be  2**0
                  CONTENTS, DEBUGGING
 30 .debug_pubnames 0000028e  000116c3  000116c3  0000b6c3  2**0
                  CONTENTS, DEBUGGING
 31 .debug_pubtypes 0000159f  00011951  00011951  0000b951  2**0
                  CONTENTS, DEBUGGING
 32 .debug_str    00005e4f  00012ef0  00012ef0  0000cef0  2**0
                  CONTENTS, DEBUGGING
 33 __DWARF.__apple_names 0000033c  00018d3f  00018d3f  00012d3f  2**0
                  CONTENTS, ALLOC, LOAD, DATA
 34 __DWARF.__apple_types 000016a3  0001907b  0001907b  0001307b  2**0
                  CONTENTS, ALLOC, LOAD, DATA
 35 __DWARF.__apple_namespac 00000024  0001a71e  0001a71e  0001471e  2**0
                  CONTENTS, ALLOC, LOAD, DATA
 36 __DWARF.__apple_objc 00000088  0001a742  0001a742  00014742  2**0
                  CONTENTS, ALLOC, LOAD, DATA
Polytonality answered 25/7, 2014 at 17:53 Comment(0)
D
3

dSYM is indeed a container (directory), within which is a Mach O binary containing only DWARF debug data, and no code.

You can inspect it in Python using filebytes and pyelftools:

import io
from filebytes.mach_o import MachO
from elftools.dwarf.dwarfinfo import DWARFInfo, DebugSectionDescriptor, DwarfConfig

macho = MachO(filename)

data = {
    section.name: DebugSectionDescriptor(io.BytesIO(section.bytes), section.name, None, len(section.bytes), 0)
    for loadcmd in macho.loadCommands
    if getattr(loadcmd, 'name', None) == '__DWARF'
    for section in loadcmd.sections
}

dwarfinfo = DWARFInfo(
    config=DwarfConfig(
        little_endian=True,
        default_address_size=8, # 64 bit
        machine_arch='x64',
    ),
    debug_info_sec=data['__debug_info'],
    debug_aranges_sec=None,
    debug_abbrev_sec=data['__debug_abbrev'],
    debug_frame_sec=None,
    eh_frame_sec=data['__eh_frame'],
    debug_str_sec=data['__debug_str'],
    debug_loc_sec=data['__debug_loc'],
    debug_ranges_sec=data['__debug_ranges'],
    debug_line_sec=data['__debug_line']
)
Duran answered 24/10, 2017 at 12:25 Comment(4)
@SevaAlekseyev Even using filebytes from master, parsing a dsym file returns sections with .bytes == None, is that the expected behaviour?Cavour
As far as I can tell, the DSYM file doesn't physically have the non-DWARF sections in it, but they're still listed in the header. I guess the idea is that those sections reside in the application file proper, and those are expected to live side by side.Dipeptide
FYI: in Mach-O object files by Xcode, the load command with the debug info is not called "__DWARF". So the if statement in the data =... fragment should go if loadcmd.header.cmd in (LC.SEGMENT, LC.SEGMENT_64), if you want to parse .o files.Dipeptide
Update: the dSYM compatibility pull request in filebytes was accepted, it's out on PyPI.Dipeptide
F
2

You will be able to read the DWARF debug info with the dwarfdump command.

Favus answered 7/12, 2014 at 22:20 Comment(0)
D
1

There's also a GUI DWARF Explorer at https://pypi.org/project/dwex/ . Install by running pip install dwex from the command, then run with dwex.

It supports dSYM bundles. Drag one over the main window, and watch the tree.

Dipeptide answered 7/2, 2020 at 18:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.