解决XCode lldb的问题

2,187 阅读1分钟

问题: Xcode lldb 调试 po时报错

error: type for self cannot be reconstructed: type for typename "\*\*\*" was not found (cached)

error: Couldn't realize Swift AST type of self. Hint: using v to directly inspect variables and fields may still work.

image.png

解决步骤:

执行 (lldb) swift-healthcheck

image.png

image.png

查看log文件,可以发现是由于项目中使用的静态库 Swift module 没有找到。需要通过 -add_ast_path 命令注册,然后搜索关键词,找到了 Xcode13LLDBBug, 里面有 add_ast_path的使用方式,需要把所有的Swift module 添加到 OTHER_LDFLAGS 中。

方式一

1、 runscript 脚本,编译时获得查找所有Swift module,输出到文档中,

#!/bin/bash

# YES时执行
RUN_MY_SCRIPT="YESNO"

if [ "$RUN_MY_SCRIPT" != "YES" ]; then
    echo "Skipping script as RUN_MY_SCRIPT is not YES."
    exit 0
fi
  
# 记录开始时间(浮点时间戳,秒+纳秒)
start_time=$(date +%s.%N)
  
# 设置目标目录
TARGET_DIR=$TARGET_BUILD_DIR

# 打印目标目录(可选的调试输出)
echo "test->>>> $TARGET_DIR"

LDFLAGS_FILE="$PROJECT_DIR/other_ldflags.txt"

# 删除旧的 other_ldflags.txt 文件
if [ -f "$LDFLAGS_FILE" ]; then
    echo "删除旧的 $LDFLAGS_FILE 文件..."
    rm "$LDFLAGS_FILE"
fi

# 遍历 TARGET_DIR 的子文件夹
for dir in "$TARGET_DIR"/*; do
    if [ -d "$dir" ]; then
        # 获取子文件夹的名字
        folder_name="$(basename "$dir")"
        # 拼接目标文件路径
        target_folder="$TARGET_DIR/$folder_name/$folder_name.framework/Modules/$folder_name.swiftmodule/arm64-apple-ios.swiftmodule"
       # 检查目标路径是否存在
        if [ -f "$target_folder" ]; then
            # 如果文件存在,输出路径
            echo "-Wl,-add_ast_path,$target_folder" >> "$PROJECT_DIR/other_ldflags.txt"
        fi
    fi
done

# 确保文件存在
if [ ! -f "$LDFLAGS_FILE" ]; then
    echo "没有找到任何 LDFLAGS 文件,跳过更新 OTHER_LDFLAGS..."
    exit 0
fi

# 记录结束时间
end_time=$(date +%s.%N)
# 计算耗时(浮点运算)
elapsed_time=$(echo "$end_time - $start_time" | bc)
# 转换为毫秒
elapsed_time_ms=$(echo "$elapsed_time * 1000" | bc)
# 打印结果
printf "Script executed in %.3f milliseconds.\n" "$elapsed_time_ms"

脚本整体耗时在 1000ms,【当然根据项目规模有关】

2、 将 other_ldflags.txt 文件中的 copy 到 OTHER_LDFLAGS中。

image.png

image.png

image.png 后续感觉可以优化为脚本自动修改,但是一直没找到合适的方式。哈哈。

方法二 (推荐)

Xcode13LLDBBug 中的一样,采用 pod的方式,将 -Wl,-add_ast_path,/Users/ yourname/Library/Developer/Xcode/DerivedData/product-bpbsrqzpomigcjgngmgmuemqhous/Build/Products/Debug-iphoneos/Alamofire/Alamofire.framework/Modules/Alamofire.swiftmodule/arm64-apple-ios.swiftmodule 等路径添加到 YourProject/Pods/Target Support Files/Pods-XXXX/Pods-XXXX.debug.xcconfig 中的 OTHER_LDFLAGS 字段中。

不过这里需要把需要的子库也是一个一个添加进去。pod还可以再进一步优化,把方法一种需要添加的库,写成数组放到podfile 文件中,遍历添加。

可以将方法1种需要调试的库,遍历出来,放到方法二中的 modules 中,也可以按需添加调试的库。

Podfile文件

post_integrate do |installer|

  #需要调试的pod 模块
  modules = ['AFNetworking1', 'AFNetworking2']
  # XXXX替换为你的 xcodeproj 名

  xcconfig_path = File.join(

    installer.sandbox.target_support_files_root.to_s,

    'Pods-XXXX/Pods-XXXX.debug.xcconfig'

  )


  xcconfig_content = File.read(xcconfig_path)
  

  match = xcconfig_content.match(/OTHER_LDFLAGS = ([^\n]+)\n/);

  xcconfig_original_ld_flags = match ? match[1] : '';

  

  additional_ld_flags = modules.map do |module_name|

    "-Wl,-add_ast_path,$(TARGET_BUILD_DIR)/#{module_name}/#{module_name}.framework/Modules/#{module_name}.swiftmodule/$(NATIVE_ARCH_ACTUAL)-apple-$(SHALLOW_BUNDLE_TRIPLE).swiftmodule"

  end.join(" ")

  additional_ld_flags = "OTHER_LDFLAGS = #{xcconfig_original_ld_flags} #{additional_ld_flags} \n"

  

  xcconfig_content.gsub!(/OTHER_LDFLAGS = ([^\n]+)\n/, additional_ld_flags)

  

  File.open(xcconfig_path, 'w') do |f|

    f.puts xcconfig_content

  end

end

总结

经过测试 方法一目前不太好用,而且项目较大的话会首次断点会卡,增量编译后也不好用。 还是推荐方法二 修改podfile的方式。

参考文档

Debug Swift debugging with LLDB

Xcode13LLDBBug