Carthage strips symbols from dSYM files

Created on 6 Dec 2017  ·  20Comments  ·  Source: Carthage/Carthage

  • carthage version: 0.26.2
  • xcodebuild -version: Xcode 9.1 Build version 9B55
  • Are you using --no-build? No
  • Are you using --no-use-binaries? No
  • Are you using --use-submodules? No
  • Are you using --cache-builds? No

Cartfile
N/A

Since Xcode 9, (this is my guess, I can't really tell exactly when this started happen) when I build a framework with Carthage for macOS, dSYM file gets empty even tho Xcode builds it correctly.

Here's what's happening in my log:

  • Xcode create dSYM file using dsymutil (Default value of DEBUG_INFORMATION_FORMAT for release build is DWARF with dSYM file
  • Xcode then strip symbol (Default value of STRIP_INSTALLED_PRODUCT for release build is Yes)
  • Then Carthage tries to create a dSYM file from the stripped framework, which generates empty dSYM file. (inside of createDebugInformation function??)

However, iOS version of framework has a correct dSYM file even the framework itself is stripped.

I haven't changed any related settings when I updated my project to Xcode 9, but I did change Xcode's recommended changes which might effect something here.

To avoid this, I have to disable STRIP_INSTALLED_PRODUCT to create correct dSYM file, then strip the symbol with a separate script.

Most helpful comment

I got the same issue, and after a bit of debug, my suspect is:

  • since v26 Carthage, the way build framework is change from "xcodebuild build" -> "xcodebuild archive"
  • The binary build by "xcodebuild archive" will stripped debug symbols in binary file
  • Then when create universal binary using "lipo -create" the universal binary will missing debug symbols for armv7, arm64
  • Using "dsymutil" to generate dSYM from universal binary. This final dSYM only contains symbols for i386, x86_64.
  • Archiving the app for submitting app store, carthage copy_framework will strip architecture i386, x86_64 for dSYM. Now the dSYM is empty.

All 20 comments

+1, I am seeing what appears to be the same issue.

When I use Carthage to build frameworks for Mac, I do get a dSYM file but it's very small and doesn't seem to allow for debugging. I can't step into sources, and in Xcode, Debug -> Debug Workflow -> Shared Libraries shows "Debug Symbols" as "no" for any framework built by Carthage.

I reverted to Carthage 0.25 and the problem went away.

I strongly suspect this is caused by the changes from PR #2158 which switched to using "archive" instead of "build" to build frameworks. The "archive" command seems to strip the debug symbols before the dSYM can be created, as described by OP.

Unfortunately, I just convinced my team that breaking up our code into frameworks is the way to go, and now we can't debug anything because of this issue. So there is a minor torches and pitchforks situation. So any help would be greatly appreciated! :-)

2295 may also be a dup of this?

I got the same issue, and after a bit of debug, my suspect is:

  • since v26 Carthage, the way build framework is change from "xcodebuild build" -> "xcodebuild archive"
  • The binary build by "xcodebuild archive" will stripped debug symbols in binary file
  • Then when create universal binary using "lipo -create" the universal binary will missing debug symbols for armv7, arm64
  • Using "dsymutil" to generate dSYM from universal binary. This final dSYM only contains symbols for i386, x86_64.
  • Archiving the app for submitting app store, carthage copy_framework will strip architecture i386, x86_64 for dSYM. Now the dSYM is empty.

👍 This affects my organization also

Pull requests welcome. ☺️

There seems to be some discrepancies here as to which platforms are affected.

The original report by @naan states this affects MacOS only.

My report confirms it affects MacOS and I made no statement on iOS.

However, @horse304 and @huy-le both claim this affects iOS, and @horse304's comment seem to even imply this does NOT affect MacOS.

Before anyone tries to tackle a fix, we should clarify the report first, since what it affects will likely influence the solution.

Can everyone please double-check and clarify their reports? I will do my own testing on iOS as well.

OK, I did some extensive testing, and it appears the issue does affect both MacOS and iOS.

However, for iOS, it only affects the slice of the dSYM for device builds (arm7/arm64). Simulator dSYMs (i386/x86_64) still contain valid debug info. For this reason, a cursory inspection of the "fat" iOS dSYM generated appears to have valid debug information, making it seem like this issue only affects MacOS (as seen by @naan). However, if you thin the dSYM with lipo, you will see that for arm7/arm64 there is no debug info (which, with the benefit of further understanding, is exactly what @horse304 was saying).

Hopefully this resolves the confusion in which platform this affects.

Moving on from the confusion, it makes sense that the simulator is not affected because that slice is not built with xcodebuild archive but rather with xcodebuild build. iOS device builds and all MacOS builds, on the other hand, do use archive and are affected.

As theorized by multiple people above, the archive command strips symbols when build does not. As far as I can understand, most projects have STRIP_INSTALLED_PRODUCT as true, but do not have DEPLOYMENT_POSTPROCESSING set to true, so a build operation does not strip. However, DEPLOYMENT_POSTPROCESSING seems to be magically true when you use archive, leading to stripping.

With that understanding, I came to an additional realization: with the archive change, the frameworks that Carthage builds are now stripped of symbols. Previously, it seems they were not and were expected to be stripped during the copy frameworks process of the consuming application. So I think a fundamental question is, is this something we want?

The above question is important because I think there are two reasonable ways to fix this issue.

One option is to go in the direction of attempting to disable the stripping process of the archive operation, probably by passing additional flags to xcodebuild. If we did this, then the produced framework would unstripped, and the dSYM generation would succeed.

The second option is to simply use the dSYM generated by the archive operation, rather than having Carthage create one itself post-build. This is nice because it's one less thing for Carthage to do, but it leaves the produced framework stripped, which is a change from how things used to be.

If we can determine a strategy, I'd be happy to attempt a pull request.

@mdiep, @ikesyo, et al, thoughts?

I'm not sure how to fix this off the top of my head. If someone who is affected could find an approach that works and open a PR, that'd be ✨.

@mdiep As I said above, I believe either of my approaches would solve this problem, and I'd happily work on a PR for either one. But I'd like to know which one would be preferred. I guess if you don't have a preference, I'll flip a coin.

Thanks, @abrindam for your commitment. I personally would vote for your option #1. Merely because I need the produced framework unstripped and the DSYM as it was.

Glad you said that, because option 1 is way easier to implement!

I've opened PR #2334.

Thanks, https://github.com/Carthage/Carthage/pull/2361 fixes this for me. For others, you'll need to build from source until a new release is published

Fixed in 0.29.0

Still occurring in 0.29.0

@sp0cket can you elaborate?

carthage build --no-skip-current --no-use-binaries should not be striping anything, I just verified with Alamofire.

How to verify:

  • dSYM is there
  • run: nm -a -arch arm64 Alamofire.framework/Alamofire | swift demangle > unstripped-app.txt ; cat unstripped-app.txt | grep Alamo

Hi @blender, I just executed this command carthage build --no-skip-current --platform ioswith Cartfile.resloved:

github "Alamofire/Alamofire" "4.7.0"
github "Moya/Moya" "10.0.1"
github "SnapKit/SnapKit" "4.0.0"
github "realm/realm-cocoa" "v3.3.0"
github "ReactiveX/RxSwift" "4.1.2"
...

And Run an app that use frameworks in Xcode. Open Debug>Debug Worlkflow>Shared Libraries

Name | Debug Symbols
-|-
Alamofire | Yes
Moya | Yes
SnapKit | Yes
Realm | No
RealmSwift | No
RxCocoa | No
RxSwift | No

@sp0cket did you use --no-use-binaries ? If the dSYMs are not included in the archive carthage is downloading then you won't have them

dSYMs are there for me:

$ carthage bootstrap --platform iOS --no-use-binaries
*** Checking out RxSwift at "4.1.2"
*** xcodebuild output can be found in /var/folders/pn/14183n6j2bz0s2_qlcqtg5_00000gn/T/carthage-xcodebuild.LMDEgU.log
*** Building scheme "RxBlocking-iOS" in Rx.xcworkspace
*** Building scheme "RxCocoa-iOS" in Rx.xcworkspace
*** Building scheme "RxSwift-iOS" in Rx.xcworkspace
*** Building scheme "RxTests-iOS" in Rx.xcworkspace
$ ls Carthage/Build/iOS/
total 4384
-rw-r--r--@ 1 blender  staff   6.0K Mar 21 18:27 .DS_Store
-rw-------  1 blender  staff   546K Mar 21 18:26 221D20FC-D0D5-395D-BAB2-2FA15BCCAF04.bcsymbolmap
-rw-------  1 blender  staff    28K Mar 21 18:24 5C01AB6F-7E8C-351F-839A-837D85CBFC51.bcsymbolmap
-rw-------  1 blender  staff    31K Mar 21 18:24 6F901AAB-D8B3-3C27-8F22-80614D1CD64B.bcsymbolmap
-rw-------  1 blender  staff   552K Mar 21 18:26 77E85A70-55D5-320D-8114-39B543A8A9C3.bcsymbolmap
-rw-------  1 blender  staff   511K Mar 21 18:26 8F2AB12E-D2CF-3D2B-9587-2779485FE6D9.bcsymbolmap
-rw-------  1 blender  staff   506K Mar 21 18:26 F4173D01-BFA5-3BFA-A3A3-1F9584D2631B.bcsymbolmap
drwxr-xr-x  6 blender  staff   204B Mar 21 18:25 RxBlocking.framework
drwxr-xr-x  3 blender  staff   102B Mar 21 18:25 RxBlocking.framework.dSYM
drwxr-xr-x  6 blender  staff   204B Mar 21 18:26 RxCocoa.framework
drwxr-xr-x  3 blender  staff   102B Mar 21 18:26 RxCocoa.framework.dSYM
drwxr-xr-x  6 blender  staff   204B Mar 21 18:26 RxSwift.framework
drwxr-xr-x  3 blender  staff   102B Mar 21 18:26 RxSwift.framework.dSYM
drwxr-xr-x  6 blender  staff   204B Mar 21 18:27 RxTest.framework
drwxr-xr-x  3 blender  staff   102B Mar 21 18:27 RxTest.framework.dSYM

@blender It works fine, Sorry

Was this page helpful?
0 / 5 - 0 ratings