Clang principle
Clang document clang.llvm.org/docs/Saniti…
A code Tracing feature provided by Apple, Tracing PCs
Add -fsanitize-coverage=func,trace-pc-guard to xcode
Note the func here, which stands for intercepting methods only.
2. An error is reported at runtime because two methods are undefined
__sanitizer_cov_trace_pc_guard_init
__sanitizer_cov_trace_pc_guard
Copy the code
This is a callback that needs to be defined in the project as required by the documentation.
Command to view memory: x 0x100000
Methods, blocks, functions, and so on are collectively referred to as methods.
__sanitizer_cov_trace_pc_guard_init
You can get the number of all methods.
__sanitizer_cov_trace_pc_guard
Hook all methods and get the order in which they are called.
You add a line of code to the implementation of each method, and by calling the method, you modify the binary.
This method is also the principle of Clang piling.
Gets the symbol and stores it
Print all symbols as follows:
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
void *PC = __builtin_return_address(0);
Dl_info info;
dladdr(PC,&info);
printf(@"%s\n",info.dli_sname);
}
Copy the code
The above callback method is multithreaded, that is, the function in the child thread is executed in the child thread.
So you need to store symbols in a thread-safe way, in a thread-safe atomic queue.
#include <stdint.h>
#include <stdio.h>
#include <sanitizer/coverage_interface.h>
#import <dlfcn.h>
#import <libkern/OSAtomic.h>
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
void *PC = __builtin_return_address(0);
Dl_info info;
dladdr(PC,&info);
printf(@"%s\n",info.dli_sname);
// Create a structure
SYNode * node = malloc(sizeof(SYNode));
*node = (SYNode){PC,NULL};
// The structure is pushed
OSAtomicEnqueue(&symbolList, node, offsetof(SYNode, next));
}
// Generate order file!!- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// Define an array
NSMutableArray<NSString *> * symbleNames = [NSMutableArray array];
while (YES) {// Circulating body! Intercept!!
SYNode * node = OSAtomicDequeue(&symbolList, offsetof(SYNode,next));
if (node == NULL) {
break;
}
Dl_info info;
dladdr(node->pc, &info);
NSString * name = @(info.dli_sname);// Turn to string
// Add _ to the function name
BOOL isObjc = [name hasPrefix:@ "+ ["] || [name hasPrefix:@"-["];
NSString * symbolName = isObjc ? name : [@ "_" stringByAppendingString:name];
[symbleNames addObject:symbolName];
}
// Reverse traverse the number group
// symbleNames = (NSMutableArray
*)[[symbleNames reverseObjectEnumerator] allObjects];
// NSLog(@"%@",symbleNames);
NSEnumerator * em = [symbleNames reverseObjectEnumerator];
NSMutableArray * funcs = [NSMutableArray arrayWithCapacity:symbleNames.count];
NSString * name;
/ / to heavy
while (name = [em nextObject]) {
if (![funcs containsObject:name]) {
[funcs addObject:name];
}
}
// Remove yourself! touchesBegan
[funcs removeObject:[NSString stringWithFormat:@"%s",__func__]];
// Write to the file
//1. Programming string
NSString * funcStr = [funcs componentsJoinedByString:@"\n"];
NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"dd.order"];
NSData * file = [funcStr dataUsingEncoding:NSUTF8StringEncoding];
[[NSFileManager defaultManager] createFileAtPath:filePath contents:file attributes:nil];
NSLog(@ "% @",funcStr);
}
Copy the code
Swift symbol coverage
1. Create a swift file
2. Add Other Swift Flags
And so the Swift method is added.