49

I am working on an iOS app and I have noticed a bug that is only reproducible when the app is built in release mode. The only way I have found to run a release mode app that I have built is by building an archive, signing it with my debug profile, and doing an ad-hoc deployment to my device. Using this method however I can't attach with a debugger, and I'm not even sure if I could attach it if it would work well after the release build had run the optimizer on the code.

Does anyone know of a good way to debug an issue that is only reproducible when an app is build in release mode?

lehn0058
  • 19,977
  • 15
  • 69
  • 109
  • Hopefully others have better suggestions, but I'd be inclined write my own logging method that wrote messages to a text file, that I could then examine after a crash. Kind of like `NSLog` but to a file and for release versions. Not nearly as efficient as LLDB, but all I can think of. And, by the way, I generally have multiple schemes, one for debugging, one for release. That way I can test release performance without needing to go through that other process. – Rob Jan 22 '13 at 14:03
  • 1
    Just turn up the optimisation level to -O2 or -O3 in the debug build - that should be enough to make your bugs show up. – Paul R Jan 22 '13 at 14:04
  • @Paul R, how do I do that? And what are the differences between the two? It seems strange to have different levels of optimisation... – lehn0058 Jan 22 '13 at 14:19
  • 3
    Normally debug builds have no optimisation enabled (-O0) to make debugging easier, whereas release builds have optimisation enabled (-O3 or -Os), which makes the code run much faster but also makes debugging harder (but not impossible). You can just go into the build settings on Xcode in the Debug configuration and temporarily turn up the optimisation level - this will keep all the other debug goodies (symbols etc) but hopefully also flush out the release mode bug. – Paul R Jan 22 '13 at 14:22
  • 1
    @Paul R, Turning up the optimization on the debug config did it. I was not able to get the build to run in release mode like your post below mentioned. If you post an answer for the debug optimization settings, I will mark it as answered. – lehn0058 Jan 22 '13 at 23:44
  • @lehn008: great - glad you managed to flush out (and hopefully fix!) the bug - I've converted my comments above to an answer as suggested. – Paul R Jan 23 '13 at 05:59

5 Answers5

50

Normally Debug builds have optimisation disabled (-O0) to make debugging easier, whereas Release builds have optimisation enabled (-O3 or -Os), which makes the code run much faster, but also makes debugging harder (but not impossible). You can just go into the build settings in Xcode in the Debug configuration and temporarily turn up the optimisation level - this will keep all the other debug goodies (symbols etc) but hopefully also flush out the Release mode bug. (Don't forget to reset the optimisation level to -O0 in the Debug configuration when you're done!)

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 3
    Thank you, this helped to flush out the real issue. Once fixed, I was able to turn optimizations back on. – Mike Taverne Sep 02 '15 at 15:11
  • @Paul R : Is it advisable to use this in normal debugging given the fact the `release` mode also has the same optimisation levels – Abhishek Bedi Sep 22 '15 at 08:01
  • 1
    @AbhishekBedi: the OP needs debug symbols and other relevant settings for debugging, but the app only crashes in release mode - it's easier to just (temporarily) turn up optimisation in the debug build than it is to try and enable debug symbols etc in the release build. – Paul R Sep 22 '15 at 08:17
  • @PaulR:Thanks Paul ! But can I assume that changing this setting and this setting along will make DEBUG and RELEASE same (i.e. no difference) ? If yes ?, I would appreciate if you can mention some reliable source to confirm the same. :) – Abhishek Bedi Sep 22 '15 at 09:02
  • 1
    @AbhishekBedi: no, there are plenty of other differences between Debug and Release configurations - I explained all that above in my previous comment. Sometimes bugs only show up in Release builds, and the easiest way to debug them then is to turn up the optimisation level in the Debug configuration temporarily - this will *usually* cause the bug to show up in the Debug build. – Paul R Sep 22 '15 at 09:47
  • 2
    There is a second optimization level setting for swift. – zeiteisen Jan 22 '16 at 10:50
  • 1
    @zeiteisen: the question dates from Jan 2013 - Swift was not even announced until June 2014. – Paul R Jan 22 '16 at 11:35
17
  1. Go to "Project" command in an Xcode application menu and chose "Edit Scheme"(Shortcut: ⌘< )
  2. Select "Run Project name" in left pane
  3. In right pane, under "Info" tab change "Build Configuration" to "Release"
Marcus Leon
  • 55,199
  • 118
  • 297
  • 429
Rahul Wakade
  • 4,765
  • 2
  • 23
  • 25
  • 3
    I was not able to run the project this way. However, turning up the optimization in the debug config did help me find my issue. Apparently arc is not as instantly automatic when the code is not fully optimized... – lehn0058 Jan 22 '13 at 23:43
  • Do you mean, ARC releases object quickly when reference count becomes 0 in Release mode than in Debug mode? – Rahul Wakade Jan 23 '13 at 04:15
  • Yes. In my case, arc did not release an object immediately when their was 0 remaining references. I was removing a weakly referenced view from my storyboard and re-adding it on the very next line. In debug mode this worked, possibly because arc is not as aggressive when the assembly is not optimized. When I turned the optimization level up, the object was released immediately. – lehn0058 Jan 23 '13 at 12:59
  • 1
    You can also enable *Address Sanitizer* to debug weird crashes – Abhishek Bedi Apr 05 '17 at 08:55
  • Works nicely as expected. The claims about ARC are incorrect, and there is absolutely no difference in release timing of zero-referenced objects. Since ARC - this happens always, immediately, and synchronously as the reference count drops to 0. – Motti Shneor May 14 '19 at 10:51
  • However, with "Release" compiler optimizations - it might occur that compiler will decide to lower reference count of an object earlier than in Debug (because of inlining, loop-unrolling, dead-code removal and other logic optimizations). Still - if you want to debug a "Release build" you DO WANT these changes, so to debug and verify the real thing as it will be with your client. – Motti Shneor May 14 '19 at 10:58
  • This helped me in testing which server URL is being used by my app from my user-defined setting. – Ammar Mujeeb Jul 06 '20 at 13:03
11

You can not run an app in release mode while have having debugging turned on. That is not intended.

When running an app in release mode you have to find a different way to observe the behaviour of your app (e.g. using alerts).

Uncheck <code>Debug executable</code> do run your app in release mode

Additionally you will have to trust the distribution profile on your device. Xcode will notify and guide you with an alert message on the first run.

ehrpaulhardt
  • 1,607
  • 12
  • 19
1

To debug an iOS application in release mode modify the settings: Build Settings -> Deployment -> Deployment Post Processing -> Release -> set value as "NO"

Set 'Deployment Post Processing: Release' value as 'No'

0

I had to briefly turn on automatic signing in order to accomplish this. You aren't able to build directly on device with an iOS Distribution certificate (you need an iOS Development certificate) and you can't release to the App Store with an iOS Development certificate (you need an iOS Distribution certificate).

My debug mode was configured to use an iOS Development certificate to build directly on device. My release mode was configured to use an iOS Distribution certificate to allow the app to be installed on all devices. In order to run in release mode on device I switched to automatic code signing briefly to test. Once I was done testing, I used git to revert to the previous Xcode configuration.

Not the most elegant way, but it got the job done.

Eric Wiener
  • 4,929
  • 4
  • 31
  • 40