我能否调试从IPA存档文件安装的iOS应用?

15

我的应用程序只有在安装ad hoc版本时才会出现问题,但如果我只是从Xcode运行应用程序,它就不会出现这个问题。我想调试这个问题,但到目前为止还没有什么收获。我正在使用Xcode 5.1.1。以下是我所做的:

 

1)转到Product-> Scheme-> Edit Scheme-> Archive并将构建配置设置为Debug。

    

2)代码签名标识设置为iPhone Developer。

    

3)生成调试符号设置为Yes。

    

4)转到Product-> Archive,并在归档后单击“Distribute”,然后选择“Save for Enterprise or Ad Hoc Deployment”。

    

5)选择我的开发配置文件。

    

6)单击“导出”并导出.ipa文件。

    

7)使用iPhone配置实用程序将应用程序安装到设备上。

    

8)在设备上运行应用程序。

    

9)在Xcode中,转到Debug-> Attach To Process-> By PID或名称,输入应用程序名称。 Xcode成功附加并显示在iPad上运行应用程序。

    

10)然而,当我执行应用程序中某些操作时,无法触发任何断点(如果我安装并从Xcode运行应用程序,则会触发所有断点)。

我漏掉了什么吗?

3个回答

11

此时您的应用程序没有任何调试信息,由于大多数应用程序都经过了深度剥离,因此甚至不会有符号让lldb钩住。 因此,我们将无法成功设置断点。

在构建应用程序时,Xcode生成了一个dSYM文件(MyApp.app.dSYM),其中包含调试信息,所以并非一无所有。 问题是,当您连接到设备上的某个应用程序时,Xcode无法知道在哪里找到其调试信息。

您可以使用以下命令将调试信息添加到lldb中的调试会话中:

(lldb) add-dsym <PathTo.dSYM>

连接设备后,您需要执行此操作。

lldb还使用SpotLight来查找dSYM,因此如果您将dSYM放在SpotLight知道搜索的位置(例如桌面或用户目录下的文件夹),那么lldb应该会自动捕捉到它。

您可以通过执行以下操作来确定lldb是否成功读取了dSYM:

(lldb) image list <AppName>
如果lldb找到了dSYM,它会在列出AppName二进制文件的路径后,在单独的一行上列出其路径。

谢谢您的回复。我应该使用作为归档过程的一部分构建的.dSYM文件(在.xcarchive目录中)还是单独构建的文件?我尝试使用.xcarchive中的文件并按照上述步骤操作,但仍然无法命中任何断点,即使“image list”命令显示dSYM文件已列出。但是,如果我尝试使用单独构建的dSYM,则在尝试添加-dsym时会出现“UUID不匹配错误”。您有任何进一步的建议吗? - Yevgeniy P
你应该使用存档中的那个。你可以尝试关闭优化功能,同时使用开发配置文件来构建应用程序,看看是否能解决设置断点的问题。优化可能会使代码表现出意料之外的行为(除了优化器之外的任何人都无法预料)。如果这样还不起作用,最好向苹果报告一个错误。 - Jim Ingham
我认为我知道问题出在哪里了。我的应用程序与静态库链接。我需要的断点实际上在静态库代码中。问题是在归档期间生成的dSYM文件不包含任何来自我的静态库的符号,只有来自应用程序本身的符号。另一方面,如果我从Xcode构建而不是进行归档,则生成的dSYM具有所有符号,但由于UUID不匹配错误,我无法使用该dSYM。我需要找出如何在归档期间包含静态库符号。 - Yevgeniy P
我找到了以下调试方法:在创建的归档文件夹中,用常规Xcode构建中的dSYM和myapp.app替换两者。之后按照之前的步骤创建.ipa。然后我可以安装ipa到设备上,运行并附加到它上面,实际上可以触发我的断点。请注意,仅替换归档中的dSYM对我没有起作用,我还必须替换myapp.app。所以没关系,我可以调试它,但是现在我替换了.app之后,我想要调试的原始错误不再重现。不知何故这两个.app是不同的... - Yevgeniy P
@JimIngham,您说“在附加后必须执行此操作”,但不清楚您是如何/将调试器附加到哪里的。从.xcarchive构建的.ipa文件?我得到了“无法附加到pid:“123”无法附加”的错误...在此步骤之前需要添加dsym吗? - pkamb
安装IPA并启动您的应用程序,然后转到Xcode,并使用Debug-> Attach To Process,您的应用程序应该显示在要附加到的进程列表中。选择它,您应该能够开始调试。您还需要构建Debug版本,因为默认情况下Release构建不会添加“我愿意被调试”的授权,因此调试器将无法附加到它上面。 - Jim Ingham

9

Jim Ingham,感谢您的回答。

我找到了无法调试静态库的原因。在每个Xcode项目中,都有一个称为“Strip Linked Product”的设置,位于“Deployment”部分下。在我所有的项目中,此设置都设置为“Yes”。

为了能够调试通过存档构建的应用程序的静态库,我在每个依赖库项目(以及主项目)中将此设置设置为“No”。这也可以针对Debug/Release模式进行不同设置。之后,我可以看到在存档期间构建的库符号,并且我能够调试库代码。希望这对某人有所帮助。

不幸的是(或者可能很幸运),当库符号未被剥离时,我试图调试的错误不再重现。也许当符号被剥离时会发生一些事情,我需要进一步调查。


确保您正在构建的带有符号的应用程序版本与您首次发现错误时使用的优化相同。剥离或不剥离符号通常不会导致程序行为不同,而优化可能会改变程序的行为并揭示-O0隐藏的微妙错误。 - Jim Ingham
1
具有讽刺意味的是问题出在符号剥离上。程序在某个时候调用了dlopen()和dlsym()。我发现应用程序的“剥离链接产品”设置中有一个“剥离样式”设置为“所有符号”。这导致dlsym()失败,因为它找不到任何符号,从而引起了错误。一旦我将“剥离样式”更改为“仅限非全局符号”,问题就解决了。 - Yevgeniy P

7
我曾经遇到过同样的问题,但是在Xcode中启动我的应用程序并不可行 - 我必须构建IPA文件,将其侧载到iOS设备上,然后进行调试。 最终,我通过以下步骤成功解决了这个问题:
1)将方案存档目标设置为Debug
2)更改Debug版本的以下设置
- 保留私有外部符号(KEEP_PRIVATE_EXTERNS):YES - 启用Bitcode(ENABLE_BITCODE):NO - 剥离链接产品(STRIP_INSTALLED_PRODUCT):NO
3)重新构建、归档和部署生成的IPA文件到您的iOS设备。
4)启动应用程序,并在Xcode中选择Debug/Attach to Process/YourAppName(id)
5)进入调试器 - 您应该能够看到代码,设置断点等等。
如果您想从一开始就调试代码,只需将一个睡眠一两秒钟然后检查主函数顶部的标志的循环放置在其中-当您进入调试器时,只需更改标志以让它逃脱循环即可。

1
请问您能详细说明第2步和第3步在哪里/如何进行吗?我有一个来自我的存档的导出IPA文件...我该如何访问它的构建设置? - Caspar Wylie
@CasparWylie 在你的项目构建设置中搜索 CAPS_HINTS。 - user1300214
很不幸,我得到了错误:附加到pid'69234'失败--附加失败(不允许附加到进程。在调试器条目(Console.app)附近查看控制台消息时,附加失败。拒绝附加权限的子系统可能已经记录了有关为什么被拒绝的信息。)但是在控制台中没有更多的信息。 - user1300214

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接