Our project has about 1k clang modules, and about 600 swift modules. We experience severe delay when attaching to process with lldb: after emptying
~/Library/Developer/Xcode/DerivedData/ModuleCache.noindex it takes about 20 minutes to hit breakpoint set in application start. I've used profiler to find out that this time is required to re-populate module cache to build module in context of which lldb console expressions are built, which is expected.
However, what was not expected is the following line in the lldb log:
Extra clang arguments : (28814 items)
It turned out that lldb collects all clang arguments from all Swift modules that are passed to linker through
-add_ast_path flag and concatenates them, ignoring the fact that vast majority of them can be deduplicated. To check my hypothesis if this could affect module cache population time, I did the following:
- I made a fake Swift module that consisted of single swift source file in which were enumerated imports for all known clang modules used, and paths to clang modulemaps were passed via -fmodule-map-file flag;
- I passed only this Swift module from #1 through
-add_ast_pathlinker arg, and did not pass any other modules;
- I didn't link this Swift module into final executable.
After this manipulations debugging in Swift code worked just fine (no issues with lldb expressions in Swift), first breakpoint time after cleaning module cache dropped very significantly from about 20 minutes to about 6 minutes, and in lldb log I found this:
Extra clang arguments : (962 items)
This facts raise two questions:
- Why did reducing number of extra clang arguments while keeping same amount of clang modules affect module cache population time so significantly? Does clang rebuild module for each
- Can be this fix with arguments deduplication embedded in lldb?