0%

DanceCC 是字节 Mobile Infra 的一套编译工具链的品牌名,基于 Swift.org 的工具链进行了相关定制,包括调试优化,定制 Clang 插件特性,自研 Pass 做包大小和性能优化等等。在先前的文章中均有介绍。

背景

近期,有人发来反馈,他们在接入 DanceCC 的新版本工具链时,在调整了一些库的工具链选择后(即使用 Apple 工具链还是 DanceCC 工具链),重新编译出包,发生启动 Crash,堆栈如下:

1
2
3
"Symbol not found: __ZN5swift34swift50override_conformsToProtocolEPKNS_14TargetMetadataINS_9InProcessEEEPKNS_24TargetProtocolDescriptorIS1_EEPFPKNS_18TargetWitnessTableIS1_EES4_S8_E",
"Referenced from: <42049861-CE9C-3353-ADD2-76C05302E30B> /Volumes/VOLUME/*/App.app/Frameworks/AppStorageCore.framework/AppStorageCore",
"Expected in: <4A119B38-492C-3E7C-B249-E8F49F9D5B99> /Volumes/VOLUME/*/App.app/Frameworks/EEAtomic.framework/EEAtomic"

崩溃的核心原因在于:
__ZN5swift34swift50override_conformsToProtocolEPKNS_14TargetMetadataINS_9InProcessEEEPKNS_24TargetProtocolDescriptorIS1_EEPFPKNS_18TargetWitnessTableIS1_EES4_S8_E 这个符号找不到,引用发生在 AppStorageCore 动态链接库中,加载发生在 EEAtomic 动态链接库中

符号丢失排查

阅读全文 »

声明

此篇文章原作者就是我,版权所有。预计未来会刊登在《字节跳动终端技术》

公众号链接:

背景介绍

在如今,越来越多应用采取分布式构建系统,以及一些云IDE的兴起,在这种场景下,如何保证跨机器的编译产物,能够正常的在另一台机器进行正常的开发调试,是一个常见的问题。

传统的单机编译和链接流程中,编译器会在产物中嵌入当前编译单元的单机的路径,中间产物的路径;链接器在链接时,也会尝试写入链接器输入的所有Object File和Archive File的路径。在随后的调试器工作时,会通过读取MachO Executable的Section中,编码的调试信息和路径,以进行行断点的匹配,源码信息的展示等等能力。自然的,如果编译器或者链接器在处理时全部以当前机器的绝对路径进行编码,则跨机器的产物传输后,就不能正常的实现调试功能。

阅读全文 »

熟悉我的人都知道我其实是一个游戏爱好者,只是很少在博客写非技术文章而已。我在11月左右,因为受不了某日厂的PC独占行为而决定入手Steam Deck,这也是我自从2017年彻底放弃PC阵营之后第一次重回PC游戏领域,因此这里从一个主机玩家的视角整理一下我自己对Steam Deck,SteamOS的一些指南,希望能帮助中文领域的类似玩家快速上手和方便折腾。

断断续续写了几个小时,后续不断把我遇到的一些折腾指南都在这里更新吧,可以借助目录树来查看感兴趣的内容。

Steam Deck购买

主机

Steam Deck官网:https://www.steamdeck.com/zh-cn/

主机的规格主要是:

  1. CPU:AMD APU,4核心Zen2架构
  2. GPU:AMD APU,RDNA2,1.6 teraflops
  3. RAM:16GB LPDDR5,不可选配
  4. 分辨率:1280x800
  5. 电池:40WH
  6. 重量:669克
阅读全文 »

ImageIO是Apple提供的上层框架,用于处理常见图像格式的编解码支持。这篇文章主要讲述了三个子话题:WebP/AVIF的支持进展,IOSurafce和硬件解码优化50%内存开销,以及CGImageSource机制变化导致的线程安全问题

ImageIO的定位是上层的支持框架,其封装了诸多的苹果的底层解码器,开源编解码器,硬件HEVC/ProRes加速器等等底层细节,致力于提供和上层UI框架(如UIKit/CoreGraphics)的可交互性。

在早些年的时候,我写过一系列文章,介绍了其API使用的基本流程(参考:《iOS平台图片编解码入门教程(Image/IO篇)》),以及有关其惰性解码的机制(参考:《主流图片加载库所使用的预解码究竟干了什么》)。

实话说,自从重心从iOS开发,转移到做LLVM工具链相关工作之后,我本以为不会再写这些上层iOS框架的文章了,但是SDWebImage这个开源库依旧没有合我预期的新Maintainer,来作为交接,因此现在还是忍不住先写这一篇吐槽和说明文章。

这篇文章会介绍,自iOS 13时代之后,苹果在ImageIO上做的一系列优化(“机制变化”),以及对开发者生态带来的影响。

WebP/AVIF新兴图像格式支持

阅读全文 »

声明

此篇文章在字节跳动的技术公众号已经刊登:《字节跳动DanceCC工具链系列之Xcode LLDB耗时监控统计方案》

背景介绍

《Swift 调试性能的优化方案 》一文中,我们介绍了如何使用自定义的工具链,来针对性优化调试器的性能,解决大型Swift项目的调试痛点。

在经过内部项目的接入以及一段时间的试用之后,为了精确测量经过优化后的LLDB调试Xcode项目效率提升效果,衡量项目收益,需要开发一套能够同时获取Xcode官方工具链与DanceCC工具链调试耗时的耗时监控方案。

一般来说,LLDB内置的工作耗时,可以通过输入log timers dump来获取粗略的累计耗时,但是这个耗时只包括了源代码中插入了LLDB_SCOPED_TIMER()宏的函数,并不代表完整的真实耗时。并且这个耗时统计需要用户手动触发,如果要单独获取某次操作的耗时还需要先进行reset操作清空之前的耗时记录;对于我们目前的需求而言不够精确也不够自动。

阅读全文 »

声明

此篇文章在字节跳动的技术公众号已经刊登:《字节跳动DanceCC工具链系列之Swift调试性能的优化方案》

原作者是我自己(李卓立 @dreampiggy)而非抄袭,这里在个人博客同时转发一下,去掉了招聘相关文案。不过依旧欢迎大家有兴趣的有志之士加入。

背景

通常来说,大型Swift项目常含有大量混编(Objc/C/C++甚至是Rust)代码,含有超过100个以上的Swift Module,并可能同时包含二进制部分和源码部分。而这种大型项目在目前的Xcode 13体验下非常不好,经常存在类似“断点陷入后变量面板卡顿转菊花”、“显示变量失效”等问题。而且一直存在于多个历史Xcode版本。

图1:Xcode变量区显示卡顿转菊花,测试使用Xcode 13.3和下文提到的复现Demo

阅读全文 »

因为众所周知的原因,苹果的Xcode版本会不断提高自己的最低安装版本,在Xcode 13.0-13.2.1上,这个最低安装版本是macOS 11

而随着Xcode 13.3正式版放出,这个最低部署版本在最后关头被提升到了macOS 12

Why?

一般来说,各位开发者或者众多基建,总有各种各样的原因需要暂时留在老版本的macOS系统上,但是又希望使用新Xcode版本自带的Toolchain进行一些工作开发调试,有些是主观问题,有些是客观限制:

举例子:

  1. macOS 12禁止了sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off绕过GUI配置,导致一些公司采取Apple Device Management管理的电脑,无法正常关闭TCP拦截,会导致一些服务异常
  2. macOS 12加强了Kernel Extension的安全性,导致GitHub Action和Circle CI截止2022年3月底,迟迟无法更新他们的虚拟化集群到macOS 12,只有11.6的最新版本

这些都是闲聊,进入正题。那么有没有办法能够绕开,或者从原理上来讲,是否这个系统绑定的最低部署版本限制是必要的?

阅读全文 »

背景

自己很早之前曾经写过一些CocoaPods管理Resource资源的文章:CocoaPods的资源管理和Asset Catalog优化 ,当时列举了对普通图片类型的管理方式和一些用法,也普及了一下UIImage获取Bundle去加载不在mainBundle图像的方式。

但是苹果早在iOS 9,Xcode 7时代,苹果就已经推出了Data Asset的概念,并在随后的Xcode,尤其是Xcode 10中,为Data Asset提供了App Slicing的能力(即App Store提审包会根据选择的不同设备/内存/分辨率/GPU/CPU,最终下载到唯一匹配的一份文件),这个功能渐渐地开始被一些国内开发者使用。

在NSHipster这里,有一篇专门的文章介绍:《NSDataAsset

不过,这篇文章主要的内容是,最近有同事踩到一个关于Data Asset和最低部署版本的坑,这里单独列举一下以防后人重复踩坑。

Data Asset初见

阅读全文 »