Can I debug iOS app installed from IPA archive?
Asked Answered
C

3

15

I m having some problem with my app which reproduces only when i install it ad hoc, but doesn't reproduce if i just run the app from Xcode. I would like to debug this problem, but so far i m not having any luck. I m using Xcode 5.1.1. Here is what i did:

1) Go to Product->Scheme->Edit Scheme->Archive and set build configuration to Debug.

2) Code signing identity is set to iPhone Developer.

3) Generate Debug Symbols is set to Yes.

4) Go to Product->Archive and after it is archived, click "Distribute", then choose "Save for Enterprise or Ad Hoc Deployment".

5) My development provisioning profile is selected.

6) Click "Export" and export the .ipa file.

7) Use iPhone configuration Utility to install the app onto the device.

8) Run the app on the device.

9) In Xcode, go to Debug->Attach To Process->By PID or Name, enter the app name. Xcode attaches successfully and says running the app on iPad.

10) However, i cannot hit any breakpoints which should be hit when i do certain actions in my app (if i install and run the app from Xcode instead, all breakpoints are hit).

Am i missing something?

Comely answered 11/11, 2014 at 9:14 Comment(0)
C
9

Jim Ingham, thanks for your answers.

I found the reason why i was unable to debug into static libraries. In each Xcode project, there is a setting called "Strip Linked Product" under "Deployment" section. In all my projects this setting was set to "Yes".

In order to debug into static libraries for an app built by archiving, i set this setting to "No" in each dependent library project (as well as the main project). This can also be set differently for Debug/Release modes. After this, i see the library symbols built during archiving and i m able to debug into library code. I hope this helps someone.

Unfortunately (or maybe fortunately) the bug i was trying to debug no longer reproduces when the library symbols are not stripped. Maybe something happens when the symbols are stripped, i will need to investigate further.

Comely answered 17/11, 2014 at 8:19 Comment(2)
Make sure the version of your app that you are building with the symbols still in it is built with the same optimization as the one you first saw the bug in. Stripping or not stripping symbols really shouldn't cause a program to behave differently, whereas optimization can change a program's behavior and reveal subtle bugs that -O0 hid.Sawdust
Ironically the problem was with stripping of symbols. At some point the program calls dlopen() and dlsym(). I then saw that for "Strip Linked Product" setting for the app had a "Strip Style" setting set to "All Symbols". This caused dlsym() to fail, since it could not find any symbols, hence the bug. Once i changed "Strip Style" to "Only Non-global symbols" the problem went away.Comely
S
11

You don't have any debug information for the app at this point, and since most apps are pretty thoroughly stripped, there won't even be symbols for lldb to hook on to. So we're not going to be able to successfully set breakpoints.

When you built the app, Xcode produced a dSYM file (MyApp.app.dSYM) which has the debug info in it, so all is not lost. Problem is when you attach to some - to Xcode - random app on the device, Xcode has no way to know where to find its debug info.

You can add the debug info into your debug session in lldb by using the command:

(lldb) add-dsym <PathTo.dSYM>

You have to do this after you have attached.

lldb also uses SpotLight to find dSYM's so if you put the dSYM somewhere that SpotLight knows to search (like your Desktop or a folder under your User directory) then lldb should pick it up automatically.

You can tell whether lldb has successfully read in the dSYM by doing:

(lldb) image list <AppName>

If lldb found the dSYM, it will list the path to it on a separate line after listing the path to the AppName binary.

Sawdust answered 13/11, 2014 at 21:12 Comment(6)
Thank you for the response. Should i use .dSYM file built as part of the archiving process (inside of .xcarchive directory) or the one built separately? I tried to use the one in .xcarchive and followed the above steps, however still cannot hit any breakpoints, even though "image list" command shows the dSYM file listed. However if i try to use dSYM built separately, i get "UUID mismatch error" when trying add-dsym. Do you have any further suggestions?Comely
You should use the one in the archive. You might try building the app with optimization off, as well as with the development provisioning profile and see if that fixes setting breakpoints. Optimization can make code behave in unexpected (to anybody but the optimizer) ways. If that doesn't work, it's probably best to file a bug with Apple.Sawdust
I think i know what the problem is. My app is linked with a static library. The breakpoints that i need are actually in static library code. The problem is that dSYM file generated during archiving does not contain any symbols from my static library, only symbols from the app itself. On the other hand if i build from Xcode instead of archiving, the resulting dSYM has all the symbols, but i can't use that dSYM because of UUID mismatch error. I need to figure out how to get it to include static library symbols during archiving.Comely
I found the following way to debug it: in the created archive folder, replace both dSYM and myapp.app with the ones from regular Xcode build. After that follow the same steps as before to create .ipa. Then i can install ipa on the device, run and attach to it and can actually hit my breakpoints. Note that replacing only dSYM in the archive did not work for me, i had to replace myapp.app as well. So it's fine, i can debug it, but now that i replaced .app, the original bug that i wanted to debug no longer reproduces. Somehow those 2 .app are different...Comely
@JimIngham You say You have to do this after you have attached., but it's unclear how/what you're attaching the debugger to. An .ipa built from the .xcarchive? With that I'm getting Could not attach to pid : “123” unable to attach... do dsyms need to be added before this step?Vest
Install the IPA and finger-launch your app, then go to Xcode, and use Debug->Attach To Process and your app should show up in the list of processes to attach to. Select it and you should be able to start debugging. You also need to build the Debug version since by default the Release build does not add the "I am willing to be debugged" entitlement, so the debugger won't be allowed to attach to it.Sawdust
C
9

Jim Ingham, thanks for your answers.

I found the reason why i was unable to debug into static libraries. In each Xcode project, there is a setting called "Strip Linked Product" under "Deployment" section. In all my projects this setting was set to "Yes".

In order to debug into static libraries for an app built by archiving, i set this setting to "No" in each dependent library project (as well as the main project). This can also be set differently for Debug/Release modes. After this, i see the library symbols built during archiving and i m able to debug into library code. I hope this helps someone.

Unfortunately (or maybe fortunately) the bug i was trying to debug no longer reproduces when the library symbols are not stripped. Maybe something happens when the symbols are stripped, i will need to investigate further.

Comely answered 17/11, 2014 at 8:19 Comment(2)
Make sure the version of your app that you are building with the symbols still in it is built with the same optimization as the one you first saw the bug in. Stripping or not stripping symbols really shouldn't cause a program to behave differently, whereas optimization can change a program's behavior and reveal subtle bugs that -O0 hid.Sawdust
Ironically the problem was with stripping of symbols. At some point the program calls dlopen() and dlsym(). I then saw that for "Strip Linked Product" setting for the app had a "Strip Style" setting set to "All Symbols". This caused dlsym() to fail, since it could not find any symbols, hence the bug. Once i changed "Strip Style" to "Only Non-global symbols" the problem went away.Comely
G
7

I was struggling with the same problem, and just launching my app from Xcode was not an option - I had to build the IPA, sideload it on an iOS device, and then debug. Eventually I was able to make that work with the following steps:

1) Set the scheme archive target to Debug

2) Change the following settings for the Debug builds

  • Keep Private External Symbols (KEEP_PRIVATE_EXTERNS) : YES
  • Enable Bitcode (ENABLE_BITCODE) : NO
  • Strip Linked Product (STRIP_INSTALLED_PRODUCT) : NO

3) Rebuild, archive, and deploy the resulting IPA file to your iOS device.

4) Launch the app, and in Xcode, select Debug/Attach to Process/YourAppName(id)

5) Break into the debugger - you should be able to see the code, put and use breakpoints, etc.

If you want to debug your code from the very beginning, just put a loop that sleeps for a second or two and then checks a flag at the top of your main function - when you break into the debugger, just change the flag to let it escape the loop.

Galliot answered 9/3, 2016 at 15:49 Comment(3)
Please can you elaborate on where/how to do steps 2,3? I have an exported IPA file from my archives...how do I access it's build settings?Corked
@CasparWylie search for the CAPS_HINTS above in your project's Build Settings.Proletariat
Unfortunately I got error: attach by pid '69234' failed -- attach failed (Not allowed to attach to process. Look in the console messages (Console.app), near the debugserver entries when the attached failed. The subsystem that denied the attach permission will likely have logged an informative message about why it was denied.) but there is no further information in the console.Proletariat

© 2022 - 2024 — McMap. All rights reserved.