What’s New in LLVM
本文参考自Apple_WWDC18-What’s New in LLVM视频和409_whats_new_in_llvm.pdf
Family of Tools
- Clang
- Static Analyzer
- Sanitizers
- LLDB
- GPU shader compilers
- Swift
Partnership
Agenda
- ARC的更新
- Xcode 10中新的诊断功能
- Clang静态分析器
- 安全性提升
- 新的指令集扩展
ARC的更新
1、C语言结构体中的ARC对象指针
在之前,ARC环境下的结构体中是不支持对象指针的,因为编译器还不支持自动为结构体成员插入retain/release等内存管理代码。
现在,针对栈上的结构体变量,支持自动插入内存管理代码:
如果是堆上的结构体变量,那么需要做些额外的清理动作:
fix上述的问题一的方法:malloc -> calloc
fix上述的问题二的方法:在free之前将对象属性置为nil
2、结构体中的OC对象
【小结】这个新功能在ObjC/C++都能正常工作,但Swift不支持引入带有ARC对象指针成员的结构体。
Xcode 10中新的诊断功能
1、Swift 与 Objective-C 互通性
(1)对于swift闭包:
- 函数参数默认是non-escaping
- 不能在函数返回后调用
(2)NS_NOESCAPE警告
在ObjC引入某个Swift声明的protocol并实现时,函数参数很经常会是闭包类型,而这个默认的闭包参数特性很容易被忘记:
针对该问题,Xcode10新增了相关警告,提示开发者要添加NS_NOESCAPE
注解:
2、使用#pragma pack对结构体成员进行打包
(1)背景:
- 起因:编译器在处理结构体时会进行对齐,目的是加速CPU的访存,但会引发一些空间浪费。
- 解决:在做一些需要节约内存空间或者流量传输的业务场景时,就需要使用
#pragma pack
指示符对结构体成员进行打包。 - 使用:#pragma pack指示符也需要push/pop成对出现。
(2)针对程序员有时候忘记配对使用新增了警告,避免打包效果影响了其它结构体使得CPU处理速度变慢:
#pragma pack(push,1)与#pragma pack(1)的区别
静态分析器
1、 影响GCD性能的反模式
(1)使用dispatch_semaphore做线程同步为例,在GCD中,队列可以有不同的优先级,如果一个高优先级的队列同步等待一个低优先级的队列,导致优先级反转,那么静态分析器针对这种情况会做警告。
解决方式:
2、比自动释放池存“活得更久”的自释放变量
举了关于use-after-free的例子,尤其是一些常用API中隐藏的自动释放池会让人踩坑
错误使用:
例子1:
例子2:
例子3:
正确使用:
Autoreleasing Variables Outliving
目前Xcode是针对out类型参数,如(NSError * __autoreleasing *)error
,要求显式增加__autoreleasing
修饰符,但这不能消除这类bug隐患。
Xcode 10中静态分析器针对性地添加了Write to autoreleasing out parameter inside autorelease pool
警告,提示开发者针对这种情况,先使用一个局部的强引用类型变量来赋值,再传递给out类型
参数。
3、性能和可视化报告的优化
【提要】阐述了优化细节,如:更简洁的错误报告,推荐大家多用静态分析器。
安全性提升
1、栈的工作原理
(1)增加变量
(2)变量为另一函数
2、栈缓冲区溢出及保护措施
(1)现象
开发者在使用一些不那么安全的API时,如strcpy,会引入一些安全隐患,出于安全性考虑——比如修改return address从而实现一些权限提升,对应的就是历史悠久的缓冲区溢出攻击。
(2)解决
针对这种问题,现有的编译器技术加入了一个额外的区域(下图绿色区域),叫Stack Canary / Stack Protector
,对应的编译选项是-fstack-protector / -fno-stack-protector
。
当函数调用结束即将返回时,Canary对应的区域的值会被检查看是否被修改了,如果是则会abort()。
这些手段都是用来增加攻击者的难度,并不能百分百消除风险(比如这里提到的Stack Protector的局限性),类似的还有ASLR等保护措施。
(3)关于Stack Protector
- 检测栈缓存区溢出
- 默认是打开的
3、Stack Clash & Stack Checking
(1)Stack Clash之源:Stack 和 Heap
- Stack 是
从上向下
增长的 - Heap 则是
自下而上
增长的
两者相向扩展而内存又是有限的
(2) Stack Checking
- 基本介绍
检测Stack Clash,Xcode 10默认是打开的 - 工作原理
在 Stack 区域规定合理的分界线(上图红线),在可变长度缓冲区的函数内部对将要分配的缓冲区大小做校验,如果缓冲区超出分界线则调用 abort() 强制退出
新的指令集扩展
【提要】CPU体系架构
1、关于Atomic的简单例子:
2、关于os_unfair_lock
(1)原因:自旋锁已经不在安全
(2)目的:解决了优先级反转问题
系列文章
个人相关系列文章,喜欢的欢迎star下❤
参考书籍
WWDC 2017 What’s new in LLVM
WWDC18《What’s new in LLVM》小记
LLVM每日谈
WWDC18 What’s New in LLVM 个人笔记
本文生成.jpg可供下载: