27

Ok, so I'm trying to automatically upload dSYMs. I'm following instructions from this official documentation: https://firebase.google.com/docs/crashlytics/get-deobfuscated-reports

I'm stuck at "Run the upload symbols script manually" section. There are 3 ways to upload dSYMs. I'm trying to follow the first one - including the following line in your build process: find ${DWARF_DSYM_FOLDER_PATH} -name "*.dSYM" | xargs -I \{\} ${PODS_ROOT}/Fabric/upload-symbols -gsp MyProjectFolder/GoogleService-Info.plist -p ios \{\}

For now I've tried the following:

  1. I go to Project->Scheme->Edit Scheme.
  2. I click on Build->Post actions
  3. I start small - I only want to show "echo" in build process: dSYMs
  4. I run Product->Build
  5. I go to View->Navigators->Show Report Navigator
  6. There's not indication that echo was run.

Where to put this script?

How to find if it is being run or not?

user3554626
  • 425
  • 1
  • 5
  • 9

3 Answers3

49

TL;DR: dSYMS generated at build time has little value in the "bitcode enabled" era, you need to download dSYMs from Apple and upload them to your 3rd party crash reporter service as a post-build step after Apple has processed your upload.

Background

Symptom

Missing dSYMs / failed symbolication in 3rd party crash reporting console. I thought despite following Crashlytics install instructions the script was failing.

Bitcode - the fundamental issue

Turns out the 3rd party crash-reporting systems (like Crashlytics, or New Relic) have a fundamental problem with the current best practice for app distribution, which is bitcode-enabled apps. Historically these 3rd party crash report systems relied on build-time steps to upload build-time generated dSYMs. But since bitcode-enabling means the app store recompiles your apps, your build-time generated dSYMs, that you are trying to upload, are effectively useless.

As background, bitcode-enabled apps are "thinned" and thus re-compiled by Apple such that each device only gets the download bits it needs. You want to enable bitcode. It is a good thing. But, bitcode-enabled distribution messes up symbolication. No matter what dSYMs you generate at build time, the dSYMs won't actually correlate to crashes from App Store or TestFlight installed builds, as your crashes will be from App-store recompiled versions of your apps with new corresponding dSYMs.

So don't worry about the upload script working or not at build time. In fact, that step could be removed from your build process as it is just wasting your time and bandwidth.

The only case it might be useful is if you want to symbolicate crashes from locally-installed release versions instead of debugging them directly in Xcode.

Solutions

The solution is to wait "some time" (reportedly several minutes, via NewRelic documentation, in my experience a sleep of 120 seconds after fastlane upload but before I ran fastlane's download_dsyms action failed sometimes, a sleep of 300 seconds works reliably) after uploading your app (likely the duration of time the App Store says your build is "Processing"), then download the dSYMs from there and use your 3rd party crash reporters command-line upload script

Manual download / upload

The current recommended solutions from the 3rd party crash reporters (both NewRelic and Crashlytics documentation at least) is to either go to the App Store Connect page for the build and download dSYMs then upload, or using XCode's Organizer for the archive hit the "Download Debug Symbols" button, then upload them.

This does work, with manual dSYM downloads pushed out to your crash reporting vendor you will get symbolicated reports. It is a manual process though using either the Xcode GUI or the App Store Connect interface.

Fastlane automation

You may automate the process with Fastlane though, which is I believe the proper solution.

https://docs.fastlane.tools/actions/download_dsyms/#download_dsyms

https://docs.fastlane.tools/actions/upload_symbols_to_crashlytics/

Mike Hardy
  • 2,274
  • 3
  • 25
  • 57
  • 1
    True indeed. I mentioned that in the TLDR and in the intro that it is a best practice (because it is) implying that it only applies to that. I even explained what it meant, and I thought that made it clear? – Mike Hardy Jan 01 '20 at 14:20
  • No problem, it just read out to me as symbols not uploading due to bitcode only. – CyberMew Jan 02 '20 at 00:41
  • Thanks for this great answer! I have a question about the "wait some time" part. I am using fastlanes download_dsyms with the flag wait_for_dsym_processing and even set the wait_timout to 10 minutes but always get the errors `ITC.response.error.BUILD_NOT_FOUND` and `Error accessing dSYM file for build`. I guess this is because the build is still processing, right? So I was thinking about running the dsym refresh on a daily routine, since I don't want to let the CI wait for too long, but does this actually make sense? When is a new dsym generated? Once a new build is processed or more often? – Mitemmetim Apr 09 '20 at 15:56
  • @Mitemmetim that's a good question and unfortunately the answer is I don't know? As mentioned I wait 300 seconds personally and it has been working for me, but that's experience, and is waiting for a system out of my control so maybe my app is different (so your experience is different) or they changed the system? A daily run of "refresh latest dsyms" (or latest NN dsyms) seems like a valid workaround. Can't hurt to try? – Mike Hardy Apr 10 '20 at 16:33
  • Does it mean that DSYM should updated each time, when there is new build uploaded to App Store? – Lucky_girl Jun 16 '20 at 10:03
  • 1
    Hi @Lucky_girl - every time you create a new build, you will need the corresponding dSYMs to decode crashes. It follows that if you send a new build out for release, your crash reporting services will need those matching dSYMs, so yes, every build you upload matching dSYMs. For that reason I recommend using fastlane (or similar) as part of an automated process. Doing it manually is viable only for initial setup testing in my opinion – Mike Hardy Jun 16 '20 at 16:49
  • @MikeHardy would Firebase still show reports for old builds if new Dsym would be uploaded for new build? – Lucky_girl Jun 16 '20 at 21:00
  • 1
    @Lucky_girl yes - I wish my app was perfect, but sadly it crashes, and of course it is always the old versions (my new versions are perfect!), and I still get decoded crash reports (using the previous uploaded dSYMs) just fine. Judging by the code (https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb) the dSYMs zip must contain enough information for crashlytics (or sentry, etc) to figure it out. It always works. – Mike Hardy Jun 17 '20 at 01:03
  • Is this still possible in 2022 ? I fell that Fastlane is not showing any dSYMs files recently, not the app store. I've been stuck for a while finding a new solution. – Kruupös Apr 14 '22 at 06:12
  • 1
    @Kruupös I just did a TestFlight build today, and with current version of fastlane (2.205.1) it worked just fine to sleep 300 after waiting for the build to show up, followed by downloading the dsyms then calling the crashlytics upload script. I think everything's working great – Mike Hardy Apr 15 '22 at 02:59
  • 1
    @MikeHardy thank you for your answer. I had `Enable Bitcode` set to `No` for my recents builds (I did it for no real reasons, while updating a react-native version). After switching back to `Yes` everything seems to work. – Kruupös Apr 19 '22 at 09:03
  • 1
    New flash: Xcode 14 (almost released...) deprecates bitcode, disables it by default, will warn you if you try to set it to true manually, strips it prior to upload, and App Store will reject apps with bitcode. So this whole thing may change style soon, back to a state where build-time dSYM upload is best. https://stackoverflow.com/questions/72543728/xcode-14-deprecates-bitcode-but-why/72552590 – Mike Hardy Jun 30 '22 at 17:03
4

Try the following steps:

Step 1: Select your application's Xcode project, then your application target, then select "Build Phases".

Step 2: In Xcode menu, select "Editor", then select "Add Build Phase", and then click on "Add Run Script Build Phase".

Step 3: You should now see a Run Script section in your Build Phase options.

Step 4: Paste in the script inside the body of the Run Script Build Phase.

Keep in mind to set the right file-path(s) in your script(s).

C. Kontos
  • 1,198
  • 12
  • 21
  • question form this new command from Firebase https://firebase.google.com/docs/crashlytics/get-deobfuscated-reports-new-sdk#upload-dsyms do I need to change the PATH to absolute? thanks – Eggy Mar 24 '20 at 19:35
2

You need to requred update in Project Target-> Build setting -> debug information (Debug and release both) -> DWARF with dSYM file

enter image description here

AtulParmar
  • 4,358
  • 1
  • 24
  • 45
  • 3
    This is on the documentation guide page I linked. It doesn't work for me and that's why I'm trying to make the next step work - upload dSYMs with a script. – user3554626 Feb 13 '19 at 11:39
  • You want the fastlane actions I linked in the bottom of my answer then. They work great for me - I have it download/upload "latest" dsyms after builds, which sometimes works (it's a timing thing), I have a lane just for "latest" dsyms which I can run on demand (in case the timing issue where Apple wasn't done processing yet happens during the build), and I have a full refresh_dsyms lane - all just built with one-liners on those linked actions. Huge time-saver – Mike Hardy May 03 '19 at 02:50