Swift debug agent is 32x larger?

I was looking at lldb-server recently and noticed that the target side debugger stub, lldb-server is a whopping 261 MB after stripping (it weighs in at 1.6 GB with debug info). This is a stark contrast to the relatively svelte lldb-server from llvm.org which is ~8 MB after stripping.

What you may ask is the cause for the ~32x size increase? It seems that there were changes to the LLDB fork in Swift which pull in a large portion of the LLVM demangler and the Swift compiler on the server side. These will obviously be needed on the client side to be able to reflect the binary metadata and to evaluate the expressions. However, they should not be needed on the server side.

I tried to track down some of the cause of the bloat, with minimal luck. I did find a way to trim about 1 MB (~10%) on the upstream binary, and have a few patches that I will be trying to get through into the LLVM tree which should help reduce the lldb-server size there, but, that will be largely eclipsed by the rest of the things being dragged into the server in the Swift port. One of the largest contributors to the size here is ValueObject which causes the preservation of CompilerInstance (which in turn pulls in swiftASTContext) and Mangled (which in turn pulls in LLVMDemangle).

This really makes debugging on smaller targets (e.g. android) unnecessarily painful. Unfortunately, I don't see a good way to extricate the additional methods being added to the types in the Swift fork.

CC: @dcci @Adrian_Prantl @Frederic_Riss

Yes, the dependency is historical and possibly fairly hard to break. Out of curiosity, have you tried an LTO build to see how much it's able to shave down?

I doubt that the LTO build will help much here. This is a static link after all. The size here is due to the preservation of the class member functions due to the reference from the vtable which is going to be preserved. Furthermore, I am trying to be even more aggressive about the DCE here (using -ffunction-sections -fdata-sections -fno-common -Xlinker --gc-sections). The size increases are purely due to the fact that we have a number of virtual functions and large classes that preserve things like ValueObject.

A side note for comparison GDB (client) comes in at ~7 MB, which makes the entire debugger than just the debug server in LLDB!

Another interesting point - gdbserver is rather svelte 700KB!

Is there a way to cut out certain parts of this for embedded targets maybe? It would be great to have a clean (and lean) debugging solution for Swift on Android.

I don't think it is so much so as "cut out certain parts" as much as restructure the code. I have been playing with lldb-server from llvm.org. I managed to get that build of lldb-server down to 4.3 MB (some patches committed, some up for review). While still not at the gdbserver level of 700KB, its significantly better than the size from swift.org.

4.3MB sounds fine, great work! So it’s additions in the Swift downstream that are causing the difference, got it. I’m amazed the difference is so big.

I’m out of my depth here (as usual) but wondering whether iOS debugging could benefit from changes here too?