配置環(huán)境變量
Target -> Build Setting -> Custom Complier Flags -> Other C Flags
-fsanitize-coverage=func,trace-pc-guard

image.png
Target -> Build Setting -> Custom Complier Flags -> Other Swift Flags
-sanitize-coverage=func
-sanitize=undefined

image.png
添加代碼
添加到啟動(dòng)最早的那個(gè) ViewController.m 即可。
#import <dlfcn.h>
#import <libkern/OSAtomic.h>
@interface ViewController ()
@end
@implementation ViewController
void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
static uint64_t N; // Counter for the guards.
if (start == stop || *start) return; // Initialize only once.
printf("INIT: %p %p\n", start, stop);
for (uint32_t *x = start; x < stop; x++)
*x = ++N; // Guards should start from 1.
}
// 初始化院子隊(duì)列
static OSQueueHead list = OS_ATOMIC_QUEUE_INIT;
// 定義節(jié)點(diǎn)結(jié)構(gòu)體
typedef struct {
void *pc; // 存下獲取到的PC
void *next; // 指向下一個(gè)節(jié)點(diǎn)
} Node;
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *arr = [NSMutableArray array];
while (1) {
Node *node = OSAtomicDequeue(&list, offsetof(Node, next));
if (node == NULL) { // 退出機(jī)制
break;
}
// 獲取函數(shù)信息
Dl_info info;
dladdr(node->pc, &info);
NSString *sname = [NSString stringWithCString:info.dli_sname encoding:NSUTF8StringEncoding];
// 處理c函數(shù)以及block前綴
BOOL isObjc = [sname hasPrefix:@"+["] || [sname hasPrefix:@"-["];
// c函數(shù)及block需要在開(kāi)頭添加下劃線(xiàn)
sname = isObjc ? sname : [@"_" stringByAppendingString:sname];
// 去重復(fù)
if (![arr containsObject:sname]) {
// 入棧
[arr insertObject:sname atIndex:0];
}
// 打印看看
// printf("%s \n", info.dli_sname);
}
// 去掉touchBegan方法(因?yàn)閱?dòng)時(shí),不會(huì)調(diào)用它)
[arr removeObject:[NSString stringWithFormat:@"%s", __FUNCTION__]];
// 將數(shù)組合成字符串
NSString *funcStr = [arr componentsJoinedByString:@"\n"];
// 寫(xiě)入文件
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"link.order"];
NSLog(@"path: %@", filePath);
NSData *fileContents = [funcStr dataUsingEncoding:NSUTF8StringEncoding];
[[NSFileManager defaultManager] createFileAtPath:filePath contents:fileContents attributes:nil];
}
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
// if (!*guard) return; // guard為0會(huì)直接return,不會(huì)捕獲load
void *PC = __builtin_return_address(0);
// char PcDescr[1024];
// printf("guard: %p %x PC %s\n", guard, *guard, PcDescr);
// Dl_info info;
// dladdr(PC, &info);
//
// printf("fname=%s \n fbase=%p \n sname=%s \n saddr=%p \n",
// info.dli_fname,
// info.dli_fbase,
// info.dli_sname,
// info.dli_saddr);
Node *node = malloc(sizeof(Node));
*node = (Node){PC, NULL};
//offsetOf() 計(jì)算出列尾,OSAtomicEnqueue() 把node加入list尾巴
OSAtomicEnqueue(&list, node, offsetof(Node, next));
}
@end
取出 order file
1.運(yùn)行看控制臺(tái)打印的路徑
2.Finder 前往路徑取出 order file
3.order file放到工程根目錄下

image.png
配置order file
Target -> Build Setting -> Linking -> Order File
$(SRCROOT)/link.order

image.png
重新編譯
1.command+shift+K
2.把上述代碼刪除
3.把Other C Flags 和 Other Swift Flags的環(huán)境變量去掉
3.command+B
4.打包上線(xiàn)
附上
objc-demo
swift-demo
喜歡的老友star星一個(gè),感謝老鐵的666