I was debugging slow expression evaluation in lldb in my project and noticed that most of the time is spent on calling the functions SymbolFileDWARF::FindTypes
and SymbolFileDWARF::FindFunctions
. And a lot of these calls are made on my module's objects, but trying to search foreign symbols, like swift_release
, swift_retain
, $ss4VoidaD
, $ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
, and so on.
Looks like this search is performed for each type/function resolution request in every module.
I made a small example reproducing this behavior and took logs with
log enable -T -f ~/lldb_dwarf_map.log dwarf all
Examples:
$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
<...>/F1.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F2.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F3.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F4.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F5.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F6.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F7.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/main1.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/Foo.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F1.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F2.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F3.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F4.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F5.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F6.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/F7.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/main1.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
<...>/Foo.o: SymbolFileDWARF::FindFunctions (name="$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ", name_type_mask=0x4, sc_list)
swift_release/swift_retain
<...>/F1.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F2.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F3.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F4.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F5.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F6.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F7.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/main1.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/Foo.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F1.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F2.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F3.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F4.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F5.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F6.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F7.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/main1.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/Foo.o: SymbolFileDWARF::FindFunctions (name="swift_release", name_type_mask=0x4, sc_list)
<...>/F1.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F2.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F3.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F4.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F5.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F6.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F7.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/main1.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/Foo.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F1.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F2.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F3.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F4.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F5.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F6.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/F7.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/main1.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
<...>/Foo.o: SymbolFileDWARF::FindFunctions (name="swift_retain", name_type_mask=0x4, sc_list)
$ss4VoidaD
<...>/F1.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/Foundation-2RKMKGO99ROHJ.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/CoreFoundation-20CBG5TV841E9.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/Darwin-14D19EDNU7P9P.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/_Builtin_stddef_max_align_t-3RYDM0OTC9EKN.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/Dispatch-3K0ABAQN0ZCKQ.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/ObjectiveC-2PMW55H95VPI1.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/MachO-2CX7LH15EXF2A.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/os_object-14D19EDNU7P9P.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/os_workgroup-14D19EDNU7P9P.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/ptrauth-3RYDM0OTC9EKN.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/CoreServices-1DCIL6EKJYUI6.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/CFNetwork-1B1SSEQKOUJ8N.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/DiskArbitration-28NQO1BH2IX70.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/IOKit-1ZFD1OOS6JM4F.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/libkern-14D19EDNU7P9P.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/Security-2CATWL7YJDERF.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/XPC-2I05NQT8SVVQ4.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/launch-XFFOGOXUT3UJ.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/libDER-2DT2GFW0ST9L6.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/_SwiftConcurrencyShims-QCY7C47RPWD1.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<...>/F2.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<...>/F3.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<...>/F4.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<...>/F5.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<...>/F6.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<...>/F7.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<...>/main1.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<...>/Foo.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<...>/F1.o: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/Foundation-2RKMKGO99ROHJ.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/CoreFoundation-20CBG5TV841E9.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/Darwin-14D19EDNU7P9P.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/_Builtin_stddef_max_align_t-3RYDM0OTC9EKN.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/Dispatch-3K0ABAQN0ZCKQ.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/ObjectiveC-2PMW55H95VPI1.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/MachO-2CX7LH15EXF2A.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/os_object-14D19EDNU7P9P.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/os_workgroup-14D19EDNU7P9P.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/ptrauth-3RYDM0OTC9EKN.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/CoreServices-1DCIL6EKJYUI6.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/CFNetwork-1B1SSEQKOUJ8N.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/DiskArbitration-28NQO1BH2IX70.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/IOKit-1ZFD1OOS6JM4F.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/libkern-14D19EDNU7P9P.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/Security-2CATWL7YJDERF.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/XPC-2I05NQT8SVVQ4.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/launch-XFFOGOXUT3UJ.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/libDER-2DT2GFW0ST9L6.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
<mcp>/JHGINULXXWPJ/_SwiftConcurrencyShims-QCY7C47RPWD1.pcm: SymbolFileDWARF::FindTypes (sc, name="$ss4VoidaD", parent_decl_ctx = NULL, max_matches=4294967295, type_list)
...2000+ more $ss4VoidaD lookups...
In my small sample project, it performs quite fast. However, in my main project, we have approximately 24,000 .o
and .pcm
files in a target, and these lookups take a noticeable amount of time, often tens of seconds.
I would like to discuss how we can improve the debugging experience:
- In the case of Swift symbols, we often have a good guess about where the symbol is located by looking at the module name in the unmangled symbol. Can we leverage this?
- It appears there is no cache for these lookups. Can we add one?
- Are there any other possible improvements?