当前位置:网站首页>Clang code coverage detection (pile insertion technology)

Clang code coverage detection (pile insertion technology)

2022-06-24 04:10:00 Hunshao

Clang Code coverage detection ( Pile insertion technology )

Clang The full name is C Language Family Frontend for LLVM, That is, based on LLVM Of C A front-end compiler for a family of languages .iOS Application front-end compilation , Is to adopt Clang Accomplished . This article , We mainly introduce Clang A simple built-in code coverage detection function , about iOS development , This function is used more for Objective-C The method of inserting piles , Support for binary rearrangement , Optimize application startup speed . But the code coverage detection function is not only applicable to binary rearrangement , Its essence is for function level 、 Basic block level or code edge level insert callback , Based on this principle, we can realize the required functions more flexibly .

1. Tracing PCs with guards

Turn on Clang Code coverage check function , Need configuration -fsanitize-coverage Compile parameters , You can create a iOS Testing of formwork works , stay Build Settings->Apple Clang - Custom Complier Flags->Other C Flags The following configuration . Pictured :

trace-pc-guard In mode , All code block headers will be inserted into the following callback function :

void __sanitizer_cov_trace_pc_guard(uint32_t *guard)

This callback function needs to be customized by the developer , besides , You also need to implement the corresponding initialized callback function :

void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop)

In the example project main.m These two callbacks are defined in the file 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);}void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {    static uint64_t N;    if (start == stop || *start) return;    for (uint32_t *x = start; x < stop; x++) {        *x = ++N;    }    printf("INIT Count: %llu \n", N);}

among ,__sanitizer_cov_trace_pc_guard_init To initialize the callback , The number of symbols can be obtained through the parameters ,__sanitizer_cov_trace_pc_guard Is a pile insertion function , When each code block starts calling , Will call this pile insertion function first .

Run the code directly , The console output is as follows :

INIT Count: 14 main -[AppDelegate application:didFinishLaunchingWithOptions:] -[SceneDelegate window] -[SceneDelegate setWindow:] -[SceneDelegate window] -[SceneDelegate window] -[SceneDelegate scene:willConnectToSession:options:] -[SceneDelegate window] -[SceneDelegate window] -[SceneDelegate window] -[ViewController viewDidLoad] -[SceneDelegate sceneWillEnterForeground:] -[SceneDelegate sceneDidBecomeActive:] 

You can see , The output is sorted according to the calling order of the methods in the project . You may see many repeated symbols , This is because trace-pc-guard Set , It will perform a post insertion function callback at the beginning of the execution of any code block in the source code , Include if Judge ,while Cycles and Block Call, etc , For example, you can try in ViewController.m Of documents viewDidLoad Method , as follows :

- (void)viewDidLoad {    [super viewDidLoad];    printf(" Start Block==================\n");    void(^block)(void) = ^{    };    block();    printf(" Start the cycle ==================\n");    int n = 3;    while (n > 0) {        n--;    }    printf(" Start branch judgment ==================\n");    if (n < 10) {        n++;    }}

Run the project , The output effect is as follows :

INIT Count: 18 main -[AppDelegate application:didFinishLaunchingWithOptions:] -[SceneDelegate window] -[SceneDelegate setWindow:] -[SceneDelegate window] -[SceneDelegate window] -[SceneDelegate scene:willConnectToSession:options:] -[SceneDelegate window] -[SceneDelegate window] -[SceneDelegate window] -[ViewController viewDidLoad]  Start Block==================__29-[ViewController viewDidLoad]_block_invoke  Start the cycle ==================-[ViewController viewDidLoad] -[ViewController viewDidLoad] -[ViewController viewDidLoad]  Start branch judgment ==================-[ViewController viewDidLoad] -[SceneDelegate sceneWillEnterForeground:] -[SceneDelegate sceneDidBecomeActive:] 

Sometimes not all code blocks need instrumentation , For example, when doing binary rearrangement , Requires only method and Function Instrumentation , There are also configuration methods , We will introduce later .

2. Inline 8bit-counters

This mode needs to be configured as :

-fsanitize-coverage=inline-8bit-counters

This mode is consistent with trace-pc-guard similar , It just doesn't call back at the beginning of the code block , Instead, simply increase the count of the built-in counter . Again , In this mode , Users need to implement the following custom functions :

void __sanitizer_cov_8bit_counters_init(char *start, char *end) {  // [start,end) is the array of 8-bit counters created for the current DSO.  // Capture this array in order to read/modify the counters.}

This function corresponds to the initialization of the counter .

3. Inline bool-flag

This mode is consistent with inline-8bit-counters Similar model , It needs to be configured as :

-fsanitize-coverage=inline-bool-flag

In this mode , A built-in Boolean value is set to... At the beginning of the code block true, Instead of incrementing the counter . You need to implement the following functions to capture this variable :

void __sanitizer_cov_bool_flag_init(bool *start, bool *end) {  // [start,end) is the array of boolean flags created for the current DSO.  // Capture this array in order to read/modify the flags.}

4. Tracing PCs

This pattern calls back at the beginning of the code block __sanitizer_cov_trace_pc() function , It is also a pile insertion callback , This mode can be configured as :

-fsanitize-coverage=trace-pc

The corresponding implementation of the user-defined pile insertion function is as follows :

void __sanitizer_cov_trace_pc(void*a) {    void *PC = __builtin_return_address(0);    Dl_info info;    dladdr(PC, &info);    printf("%s %p \n",info.dli_sname, info.dli_saddr);    printf("__sanitizer_cov_trace_pc:%p\n",a);}

For this mode , We can configure an additional parameter to distinguish indirect calls , For example, modify ViewController.m The code in the file is as follows :

#import "ViewController.h"@interface ViewController ()@[email protected] ViewController- (void)viewDidLoad {    [super viewDidLoad];    printf(" Start Block==================\n");    void(^block)(void) = ^{    };    block();    printf(" Start the cycle ==================\n");    int n = 3;    while (n > 0) {        n--;    }    printf(" Start branch judgment ==================\n");    if (n < 10) {        n++;    }    [self log];}- (void)log {    }@end

A new definition of log function , And in ViewDidLoad Called in the , Configure the compilation options as follows :

-fsanitize-coverage=trace-pc,indirect-calls

The corresponding instrumentation callbacks for indirect calls are as follows :

void __sanitizer_cov_trace_pc_indir(void *callee) {    printf("__sanitizer_cov_trace_pc_indirect:%p\n",callee);}

Run code , The console output is as follows :

main 0x105f5dee0 __sanitizer_cov_trace_pc:0x1-[AppDelegate application:didFinishLaunchingWithOptions:] 0x105f5dae0 __sanitizer_cov_trace_pc:0x6000019241f0-[SceneDelegate window] 0x105f5e200 __sanitizer_cov_trace_pc:0x600001b1ffc0-[SceneDelegate setWindow:] 0x105f5e240 __sanitizer_cov_trace_pc:0x600001b1ffc0-[SceneDelegate window] 0x105f5e200 __sanitizer_cov_trace_pc:0x600001b1ffc0-[SceneDelegate window] 0x105f5e200 __sanitizer_cov_trace_pc:0x600001b1ffc0-[SceneDelegate scene:willConnectToSession:options:] 0x105f5df80 __sanitizer_cov_trace_pc:0x600001b1ffc0-[SceneDelegate window] 0x105f5e200 __sanitizer_cov_trace_pc:0x600001b1ffc0-[SceneDelegate window] 0x105f5e200 __sanitizer_cov_trace_pc:0x600001b1ffc0-[SceneDelegate window] 0x105f5e200 __sanitizer_cov_trace_pc:0x600001b1ffc0-[ViewController viewDidLoad] 0x105f5d940 __sanitizer_cov_trace_pc:0x7fec54f08490-[ViewController viewDidLoad] 0x105ffa2c8 __sanitizer_cov_trace_pc_indirect:0x7fff20183600 Start Block==================-[ViewController viewDidLoad] 0x105ffa2c8 __sanitizer_cov_trace_pc_indirect:0x105f5da80__29-[ViewController viewDidLoad]_block_invoke 0x105f5da80 __sanitizer_cov_trace_pc:0x105f60040 Start the cycle ==================-[ViewController viewDidLoad] 0x105f5d940 __sanitizer_cov_trace_pc:0x7fff864ab328-[ViewController viewDidLoad] 0x105f5d940 __sanitizer_cov_trace_pc:0x7fff864ab328-[ViewController viewDidLoad] 0x105f5d940 __sanitizer_cov_trace_pc:0x7fff864ab328 Start branch judgment ==================-[ViewController viewDidLoad] 0x105f5d940 __sanitizer_cov_trace_pc:0x7fff864ab328-[ViewController viewDidLoad] 0x105ffa2c8 __sanitizer_cov_trace_pc_indirect:0x7fff201833c0-[ViewController log] 0x105f5dab0 __sanitizer_cov_trace_pc:0x7fec54f08490-[SceneDelegate sceneWillEnterForeground:] 0x105f5e140 __sanitizer_cov_trace_pc:0x600001b1ffc0-[SceneDelegate sceneDidBecomeActive:] 0x105f5e080 __sanitizer_cov_trace_pc:0x600001b1ffc0

5. Different levels of detection

The compilation mode we introduced earlier , Function ,Block And logical code blocks , Sometimes we don't need this fine-grained detection , For example, in binary rearrangement , We just want to test methods and functions , Just want to stake the method function , At this point, the detection level parameters can be configured , There are three supported level parameters :

1. edge: Default level , The highest level of granularity , function ,Block And code blocks will be instrumented .

2. bb: The underlying block level code will be instrumented .

3. func: Only function blocks will be instrumented .

Usually when we do binary rearrangement , More attention is paid to the calling sequence of functions , Use func Grade is enough , The compilation settings are as follows :

-fsanitize-coverage=trace-pc,func

Focus on Technology , love your life , Communication technology , Also be friends .

—— Hunshao QQ:316045346

meanwhile , If you find this article useful , Welcome to share with more friends , Please indicate the source .

原网站

版权声明
本文为[Hunshao]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/175/202206240046046726.html