Xcode 9 - 框架断点

Xcode 9 - Framework breakpoints

在 Xcode 7 和 8 中,我已经能够调试我一直在开发的框架 运行 xcworkspace 中的包含应用程序也包含框架项目。如果我在框架中设置断点,它们将在运行时被触发。

在Xcode 9 beta 6中,情况不再如此。到目前为止,在模拟器上调试时,执行仅在框架断点处停止。当我在物理设备上调试时,框架断点不会停止执行,而且它们似乎被完全忽略了。

如何让框架断点正常工作,以便在 iOS 11 in Xcode 9 上调试我的框架?

FWIW:xcworkspace 是由 运行 pod install 在框架根目录中创建的。然后我将示例应用程序的 xcodeproj 添加到 xcworkspace。在 Xcode 9 beta 6.

上进行测试之前,此功能一直有效

编辑:确认此行为仍然发生在 Xcode 9.0 的 GM 种子上。

我的场景是:

我的框架在其他路径。通常我在构建它时得到 .framework 。然后我将该框架(MyFramework.framework)文件添加到我的项目中。

我的建议是:

  1. 在框架调用之前添加一个新的断点。像这样

  1. 当程序执行到断点时,按下这个Step Into按钮。

现在执行将进入您的框架源区域,此时您必须在框架中的任意位置添加新断点

这是 Xcode 9 和 iOS 11 中的有效解决方案。希望对您有所帮助。祝你好运。

TL;DR - 我需要更改存档脚本在调试或准备发布时从中读取的目录。现在在调试时,如果我希望断点在运行时正常工作,我需要确保将我的框架方案的存档配置设置为 "Debug"。我只在准备生产就绪的 .framework 时使用 "Release"。

我通过错误报告联系了 Apple 开发人员支持。我将在下面粘贴回复。当他提到 "lipo" 时,他指的是我在 post-archive 脚本中进行的调用,该脚本从模拟器和物理设备构建中创建了一个通用框架。

Xcode has to match up the binary that's running with the debug symbols that are still on your machine. Xcode should do that automatically, but it sounds like some stuff is moved around behind Xcode's back. 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.

Does your framework have parenthesis around the address? That's a sure sign that lldb can't find your symbols.

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. We’re not sure if lipo might do that, which I see in your script but definitely check. Not much can be done if the debug-info no longer exists.

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

Additionally, Xcode uses Spotlight to find symbols on your machine. To avoid constantly re-indexing while building, the Intermediates/ directory containing .o files and other place where debug information is stored was blacklisted. This happened fairly late in Xcode 9.0 so may be the reason your stuff was working before.

当我在运行时 运行 (lldb) image list 时,我发现我的框架的 UUID 与 dwarfdump/Mac/path/to/Build/Products/Debug-iphoneos 报告的 UUID 不匹配。

我最终修改了我的 post-archive 脚本,以更改它在创建框架时从中读取的构建目录。当我将存档配置设置为 "Debug" 时,它现在将从 Debug-iphoneos 读取。当我将它设置为 "Release" 时,它从 ${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}"

如果路径混乱,我不怪你。本质上,工作区看起来像:

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