/usr/bin/symbols fails without indication of underlying issues

Originator:aman
Number:rdar://49599876 Date Originated:
Status: Resolved:
Product:Xcode Product Version:
Classification: Reproducible:Always
 
Summary:

The /usr/bin/symbols program in Xcode can fail on certain types of mach-o objects and DWARF data, and does not provide much helpful information about why those mach-o objects are being rejected.

Steps to Reproduce:

See three attachements: go.o.broken, go.o.nodwarf, go.o.dwarf

`symbols go.o.broken` produces a confusing error message, even though the command exits with status 0.

`symbols go.o.nodwarf` works as expected, producing symbol data from the TEXT segment.

`symbols go.o.dwarf` states the object is Empty, even though DWARF data is present.

See next comment for detailed output and analysis of each command.

Version/Build:

$ symbols -v
symbols version:                        @(#)PROGRAM:symbols  PROJECT:SamplingTools-64490.33
CoreSymbolicationDT.framework version:  64490.26

Configuration:

$ uname -a
Darwin tmm1-imac.lan 18.2.0 Darwin Kernel Version 18.2.0: Thu Dec 20 20:46:53 PST 2018; root:xnu-4903.241.1~1/RELEASE_X86_64 x86_64

Comments

go.o.broken was generated by a buggy version of golang. When running symbols on this object, the command exits with status 0 (success) instead of 1 (error), but prints an error message to stderr saying the file was not found:

$ symbols go.o.broken Unable to find file, pid, task or signature matching: go.o.broken WARNING: You currently do not have task_for_pid() privileges.

This object is invalid as far as symbols is concerned, but valid when fed into other tools such as size, nm, objdump, dwarfdump, etc.


go.o.nodwarf was built with a version of golang containing this patch: https://golang.org/cl/170377 and using golang's -ldflags=-w which omits DWARF data. You can see that the generated object has no DWARF data:

$ size -l -m -x go.o.nodwarf Segment : 0x1a4000 (vmaddr 0x0 fileoff 4096) Section (TEXT, text): 0x9da7e (addr 0x0 offset 4096) Section (DATA, rodata): 0x52b73 (addr 0x9da80 offset 649856) Section (DATA, typelink): 0xcf0 (addr 0xf0600 offset 988672) Section (DATA, itablink): 0x88 (addr 0xf12f0 offset 991984) Section (DATA, gosymtab): 0x0 (addr 0xf1378 offset 992120) Section (DATA, gopclntab): 0x80b08 (addr 0xf1380 offset 992128) Section (LLVM, asm): 0x1 (addr 0x172000 offset 1519616) Section (DATA, noptrdata): 0xd13c (addr 0x172020 offset 1519648) Section (DATA, mod_init_func): 0x8 (addr 0x17f160 offset 1573216) Section (DATA, data): 0x6ad0 (addr 0x17f180 offset 1573248) Section (DATA, bss): 0x1b8b0 (addr 0x185c60 offset 0) Section (DATA, noptrbss): 0x2598 (addr 0x1a1520 offset 0) total 0x1a38ce total 0x1a4000

$ dwarfdump go.o.nodwarf go.o.nodwarf: file format Mach-O 64-bit x86-64

.debug_info contents:

Since no dwarf data is present, the symbols program uses other basic symbol information from the TEXT section:

$ symbols go.o.nodwarf go.o.nodwarf [x86_64, 0.000917 seconds]: null-uuid go.o.nodwarf [OBJECT, FaultedFromDisk]
0x0000000000000000 (0x1a4000) SEGMENT 0x0000000000000000 ( 0x9da7e) TEXT text 0x0000000000000000 ( 0x70) go.buildid [FUNC, NameNList, MangledNameNList, Merged, NList] 0x0000000000000070 ( 0x140) sync/atomic.(*Value).Store [FUNC, NameNList, MangledNameNList, NList] 0x00000000000001b0 ( 0x10) sync/atomic.CompareAndSwapUintptr [FUNC, NameNList, MangledNameNList, NList] 0x00000000000001c0 ( 0x10) sync/atomic.StoreUint32 [FUNC, NameNList, MangledNameNList, NList] 0x00000000000001d0 ( 0x10) sync/atomic.StoreUintptr [FUNC, NameNList, MangledNameNList, NList]


go.o.dwarf was built with the above patch and DWARF data enabled (the default). You can see via size that the object contains DWARF sections:

$ size -l -m -x go.o.dwarf Segment : 0x1a4000 (vmaddr 0x0 fileoff 4096) Section (TEXT, text): 0x9da7e (addr 0x0 offset 4096) Section (DATA, rodata): 0x52b73 (addr 0x9da80 offset 649856) Section (DATA, typelink): 0xcf0 (addr 0xf0600 offset 988672) Section (DATA, itablink): 0x88 (addr 0xf12f0 offset 991984) Section (DATA, gosymtab): 0x0 (addr 0xf1378 offset 992120) Section (DATA, gopclntab): 0x80b08 (addr 0xf1380 offset 992128) Section (LLVM, asm): 0x1 (addr 0x172000 offset 1519616) Section (DATA, noptrdata): 0xd13c (addr 0x172020 offset 1519648) Section (DATA, mod_init_func): 0x8 (addr 0x17f160 offset 1573216) Section (DATA, data): 0x6ad0 (addr 0x17f180 offset 1573248) Section (DATA, bss): 0x1b8b0 (addr 0x185c60 offset 0) Section (DATA, noptrbss): 0x2598 (addr 0x1a1520 offset 0) total 0x1a38ce total 0x1a4000

However, when using symbols on this object no symbol information can be found:

$ symbols go.o.dwarf go.o.dwarf [x86_64, 0.023684 seconds]: null-uuid go.o.dwarf [OBJECT, Empty]
0x0000000000000000 (0x3332de) SEGMENT

I would like to figure out why symbols cannot parse the DWARF data from this object. Other tools like dwarfdump which are also provided by the Xcode SDK are able to read the DWARF data without issue:

$ dwarfdump go.o.dwarf go.o.dwarf: file format Mach-O 64-bit x86-64

.debug_info contents: 0x00000000: Compile Unit: length = 0x0000017d version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000181)

0x0000000b: DW_TAG_compile_unit DW_AT_name ("sync/atomic") DW_AT_language (DW_LANG_Go) DW_AT_stmt_list (0x00000000) DW_AT_low_pc (0x0000000000000070) DW_AT_ranges (0x00000000
[0x0000000000000070, 0x00000000000001d5)) DW_AT_comp_dir (".") DW_AT_producer ("Go cmd/compile devel +990504ddd2 Tue Apr 2 05:09:09 2019 -0700") ....


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!