简体   繁体   English

Xcode 9 - 框架断点

[英]Xcode 9 - Framework breakpoints

In Xcode 7 and 8, I have been able to debug a framework I've been developing by running the containing application within an xcworkspace that also contains the framework project.在 Xcode 7 和 8 中,我已经能够通过在还包含框架项目的 xcworkspace 中运行包含应用程序来调试我一直在开发的框架。 If I set breakpoints in the framework, they would get triggered at runtime.如果我在框架中设置断点,它们会在运行时触发。

In Xcode 9 beta 6, this is no longer the case.在 Xcode 9 beta 6 中,情况不再如此。 So far, execution is only stopping at the framework breakpoints when debugging on simulator.到目前为止,在模拟器上调试时,执行只在框架断点处停止。 When I debug on a physical device, the framework breakpoints do not stop execution and it appears they are completely ignored.当我在物理设备上调试时,框架断点不会停止执行,而且似乎它们被完全忽略了。

How can I get framework breakpoints to work properly in order to debug my framework on iOS 11 in Xcode 9?如何让框架断点正常工作,以便在 Xcode 9 中的 iOS 11 上调试我的框架?

FWIW: The xcworkspace was created by running pod install inside the framework root directory. FWIW:xcworkspace 是通过在框架根目录中运行pod install创建的。 I then added the sample application's xcodeproj to the xcworkspace.然后,我将示例应用程序的 xcodeproj 添加到 xcworkspace。 This has been functional up until testing on Xcode 9 beta 6.在 Xcode 9 beta 6 上进行测试之前,此功能一直有效。

Edit: Confirmed that this behavior still takes place on the GM seed of Xcode 9.0.编辑:确认此行为仍然发生在 Xcode 9.0 的 GM 种子上。

TL;DR - I needed to change which directory my archive script reads from when debugging or when preparing a release. TL; DR - 我需要在调试或准备发布时更改归档脚本从哪个目录读取。 Now when debugging, I need to be sure to set my framework scheme's archive config to "Debug" if I want breakpoints to work properly at runtime. 现在在调试时,如果我希望断点在运行时正常工作,我需要确保将我的框架方案的归档配置设置为“Debug”。 I only use "Release" when preparing a production-ready .framework. 在准备生产就绪的.framework时,我只使用“Release”。

I reached out to Apple developer support via bug report. 我通过错误报告与Apple开发人员支持联系。 I will paste the response below. 我将在下面粘贴回复。 When he mentions "lipo", he is referring to a call I make in a post-archive script that creates a universal framework from the simulator and physical device builds. 当他提到“lipo”时,他指的是我在后归档脚本中进行的调用,该脚本创建了一个来自模拟器和物理设备构建的通用框架。

Xcode has to match up the binary that's running with the debug symbols that are still on your machine. Xcode必须将正在运行的二进制文件与仍在您计算机上的调试符号进行匹配。 Xcode should do that automatically, but it sounds like some stuff is moved around behind Xcode's back. Xcode应该自动完成,但听起来有些东西在Xcode背后移动。 To know whether the debug information matches you can look at the output of (lldb) image list and /Mac/path/to/Build/Products/Debug-iphoneos% dwarfdump --uuid iOS-App.app/iOS-App that will work on dylibs too. 要知道调试信息是否匹配,您可以查看(lldb)图像列表和/ Mac / path /到/ Build / Products / Debug-iphoneos%dwarfdump --uuid iOS-App.app/iOS-App的输出也在研究dylibs。

Does your framework have parenthesis around the address? 您的框架是否在地址周围有括号? That's a sure sign that lldb can't find your symbols. 这是lldb无法找到你的符号的明确信号。

if the UUID in image list doesn't match the dwarfdump, then something has modified the executable before it ran and doesn't match your built products. 如果图像列表中的UUID与dwarfdump不匹配,则某些内容在运行之前修改了可执行文件,并且与您构建的产品不匹配。 We're not sure if lipo might do that, which I see in your script but definitely check. 我们不确定lipo是否会这样做,我在你的剧本中看到但是肯定会检查。 Not much can be done if the debug-info no longer exists. 如果debug-info不再存在,则无法完成。

If you can find the right executable with a matching UUID on your disk, you can simply (lldb) image add /Mac/path/to/DerivedData-asdfasdfadf/Products/Debug-iphoneos/iOS-App.app/Frameworks/Framework 如果您可以在磁盘上找到具有匹配UUID的正确可执行文件,则可以简单地(lldb)图像添加/Mac/path/to/DerivedData-asdfasdfadf/Products/Debug-iphoneos/iOS-App.app/Frameworks/Framework

Additionally, Xcode uses Spotlight to find symbols on your machine. 此外,Xcode使用Spotlight在您的计算机上查找符号。 To avoid constantly re-indexing while building, the Intermediates/ directory containing .o files and other place where debug information is stored was blacklisted. 为避免在构建时不断重新编制索引,包含.o文件的中间件/目录和存储调试信息的其他位置被列入黑名单。 This happened fairly late in Xcode 9.0 so may be the reason your stuff was working before. 这在Xcode 9.0中发生得相当晚,所以可能是你之前工作的原因。

When I ran (lldb) image list at runtime, I saw that the UUID of my framework did not match that which was reported by dwarfdump at /Mac/path/to/Build/Products/Debug-iphoneos . 当我在运行时运行(lldb) image list时,我看到我的框架的UUID与dwarfdump/Mac/path/to/Build/Products/Debug-iphoneos报告的UUID不匹配。

I ended up modifying my post-archive script to change which build directory it reads from when creating the framework. 我最终修改了我的归档后脚本,以便在创建框架时更改它从中读取的构建目录。 When I set my archive config to "Debug", it will read from Debug-iphoneos now. 当我将归档配置设置为“Debug”时,它将立即从Debug-iphoneos读取。 When I set it to "Release" it reads from ${BUILD_DIR}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME} 当我将其设置为“发布”时,它会从${BUILD_DIR}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}读取

# NOTE: This script creates a universal framework (device and simulator). However, *** for this to work: a Simulator target must be built first, and then Archive on the Device ***

BUILD_PRODUCTS="${SYMROOT}/../../../../Products"
SIM_PATH="${BUILD_PRODUCTS}/Debug-iphonesimulator/${TARGET_NAME}.framework"
if [ "${CONFIGURATION}" = "Debug" ]; then
 DEV_PATH="${BUILD_PRODUCTS}/Debug-iphoneos/${TARGET_NAME}.framework"
elif [ "${CONFIGURATION}" = "Release" ]; then
 DEV_PATH="${BUILD_DIR}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/${TARGET_NAME}.framework"
fi
DEST_PATH="${PROJECT_DIR}/../Frameworks/${TARGET_NAME}.framework"

rm -rf "${DEST_PATH}"
mkdir "${DEST_PATH}"
cp -r "${DEV_PATH}/" "${DEST_PATH}/"
rm -f "${DEST_PATH}/${TARGET_NAME}"
cp -Rn "${SIM_PATH}/Modules/" "${DEST_PATH}/Modules/"

lipo -create "${SIM_PATH}/${TARGET_NAME}" "${DEV_PATH}/${TARGET_NAME}" -output "${DEST_PATH}/${TARGET_NAME}"

If the paths are confusing, I don't blame you. 如果路径混乱,我不怪你。 Essentially, workspace looks like: 从本质上讲,工作区看起来像:

RootDirectory
|__SampleApp
   |__SampleApp.xcodeproj
|__Frameworks
   |__MyFramework.framework
   |__AnotherFramework.framework
|__MyFramework
   |__MyFramework.xcworkspace
   |__MyFramework.xcodeproj
   |__Podfile (etc..)

My scenario is: 我的情况是:

I have my framework in other path. 我的框架在其他路径上。 Usually I get .framework when I build it. 通常我在构建它时会得到.framework And then I add that framework(MyFramework.framework) file into my project. 然后我将该框架(MyFramework.framework)文件添加到我的项目中。

My suggestion is: 我的建议是:

  1. Add a new break point before framework call. 在框架调用之前添加新的断点。 like this 像这样

在此输入图像描述

  1. Press this Step Into button, when program execution reaches the breakpoint. 当程序执行到达断点时,按此Step Into按钮。

在此输入图像描述

Now the execution will go into your framework source area, In that point you have to add New Breakpoints where ever you want in your framework. 现在执行将进入您的框架源区域。在这一点上,您必须在框架中随意添加新断点

This is working solution in Xcode 9 and iOS 11. I hope this help you. 这是Xcode 9和iOS 11中的工作解决方案。我希望这对您有所帮助。 Good Luck. 祝好运。

The following steps would work if you have integrated xyz.framework to abc project.如果您已将 xyz.framework 集成到 abc 项目,则以下步骤将起作用。

1)For project abc, add a breakpoints at the places you want.
2)Go to breakpoint list, select all breakpoints, right click and click move breakpoint to user.

Perform above 2 steps for xyz.framework为 xyz.framework 执行上述 2 个步骤

Now run your abc project and framework breakpoints will also work.现在运行您的 abc 项目,框架断点也将起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM