我是从 main 函数开始分析的

tinyinst-converage.cpp 中的 面函数

int main(int argc, char **argv)
{
  instrumentation = new LiteCov();
  instrumentation->Init(argc, argv);

  int target_opt_ind = 0;
  for (int i = 1; i < argc; i++) {
    if (strcmp(argv[i], "--") == 0) {
      target_opt_ind = i + 1;
      break;
    }
  }

  int target_argc = (target_opt_ind) ? argc - target_opt_ind : 0;
  char **target_argv = (target_opt_ind) ? argv + target_opt_ind : NULL;

  unsigned int pid = GetIntOption("-pid", argc, argv, 0);
  persist = GetBinaryOption("-persist", argc, argv, false);
  num_iterations = GetIntOption("-iterations", argc, argv, 1);
  char *outfile = GetOption("-coverage_file", argc, argv);

  if (!target_argc && !pid) {
    printf("Usage:\n");
    printf("%s <options> -- <target command line>\n", argv[0]);
    printf("Or:\n");
    printf("%s <options> -pid <pid to attach to>\n", argv[0]);
    return 0;
  }

  Coverage coverage, newcoverage;

  for (int i = 0; i < num_iterations; i++) {
    RunTarget(target_argc, target_argv, pid, 0xFFFFFFFF);

    Coverage newcoverage;

    instrumentation->GetCoverage(newcoverage, true);

    for (auto iter = newcoverage.begin(); iter != newcoverage.end(); iter++) {
      printf("Found %zd new offsets in %s\n", iter->offsets.size(), iter->module_name.c_str());
    }

    instrumentation->IgnoreCoverage(newcoverage);

    MergeCoverage(coverage, newcoverage);
  }
 
  if (outfile) WriteCoverage(coverage, outfile);

  instrumentation->Kill();

  return 0;
}
  1. 首先创建一个 ListCov 对象

  2. 然后进行初始化 instrumentation->Init(argc, argv)

    2.1 这里先初始化 父类 TinyInst::Init

    void LiteCov::Init(int argc, char **argv) {
      TinyInst::Init(argc, argv);
    
      coverage_type = COVTYPE_BB;
      char *option = GetOption("-covtype", argc, argv);
      if (option) {
        if (strcmp(option, "bb") == 0)
          coverage_type = COVTYPE_BB;
        else if (strcmp(option, "edge") == 0)
          coverage_type = COVTYPE_EDGE;
        else
          FATAL("Unknown coverage type");
      }
    
      compare_coverage = GetBinaryOption("-cmp_coverage", argc, argv, false);
    
      for (auto iter = instrumented_modules.begin();
           iter != instrumented_modules.end(); iter++) {
        ModuleInfo *module = *iter;
        module->client_data = new ModuleCovData();
      }
    }
    

    2.1.1 其中父类 TinyInst 的初始化 主要就是我们的根据我们的命令行参数进行一个对应的 参数初始化

    // initializes instrumentation from command line options
    void TinyInst::Init(int argc, char **argv) {
      // init the debugger first
      Debugger::Init(argc, argv);
    
    #ifdef ARM64
    #else
      assembler_ = new X86Assembler(*this);
    #endif
      assembler_->Init();
    
      instrumentation_disabled = false;
    
      instrument_modules_on_load = GetBinaryOption("-instrument_modules_on_load", argc, argv, false);
      patch_return_addresses = GetBinaryOption("-patch_return_addresses", argc, argv, false);
      instrument_cross_module_calls = GetBinaryOption("-instrument_cross_module_calls", argc, argv, true);
      persist_instrumentation_data = GetBinaryOption("-persist_instrumentation_data", argc, argv, true);
    
      trace_basic_blocks = GetBinaryOption("-trace_basic_blocks", argc, argv, false);
      trace_module_entries = GetBinaryOption("-trace_module_entries", argc, argv, false);
    
      sp_offset = GetIntOption("-stack_offset", argc, argv, 0);
    
      list <char *> module_names;
      GetOptionAll("-instrument_module", argc, argv, &module_names);
      for (auto iter = module_names.begin(); iter != module_names.end(); iter++) {
        ModuleInfo *new_module = new ModuleInfo();
        new_module->module_name = *iter;
        instrumented_modules.push_back(new_module);
      }
    
      char *option;
    
      indirect_instrumentation_mode = II_AUTO;
      option = GetOption("-indirect_instrumentation", argc, argv);
      if (option) {
        if (strcmp(option, "none") == 0)
          indirect_instrumentation_mode = II_NONE;
        else if (strcmp(option, "local") == 0)
          indirect_instrumentation_mode = II_LOCAL;
        else if (strcmp(option, "global") == 0)
          indirect_instrumentation_mode = II_GLOBAL;
        else if (strcmp(option, "auto") == 0)
          indirect_instrumentation_mode = II_AUTO;
        else
          FATAL("Unknown indirect instrumentation mode");
      }
    
      generate_unwind = GetBinaryOption("-generate_unwind", argc, argv, false);
      if (!generate_unwind) {
        unwind_generator = new UnwindGenerator(*this);
      } else {
      #ifdef __APPLE__
        unwind_generator = new UnwindGeneratorMacOS(*this);
      #else
        WARN("Unwind generator not implemented for the current platform");
        unwind_generator = new UnwindGenerator(*this);
      #endif
      }
    }
    

    其中初始化 了 Debugger类 根据逻辑 这个类是最先被初始化的

    然后其中还初始化了 每个模块,且把每个 模块加入到了 instrumented_modules 中。

    2.1接着回到 LiteCov 的初始化。

    这里初始化 覆盖的 类型 coverage_type 默认是基本快覆盖率。

    coverage_type = COVTYPE_BB;
      char *option = GetOption("-covtype", argc, argv);
      if (option) {
        if (strcmp(option, "bb") == 0)
          coverage_type = COVTYPE_BB;
        else if (strcmp(option, "edge") == 0)
          coverage_type = COVTYPE_EDGE;
        else
          FATAL("Unknown coverage type");
      }
    

    然后每个 模块的 client_data 初始化为 ModuleCovData类 记录覆盖率相关的内容

  3. 然后获取对应的 参数 格式的定义和 其他参数的初始化

    
    int target_opt_ind = 0;
      for (int i = 1; i < argc; i++) {54
        if (strcmp(argv[i], "--") == 0) {
          target_opt_ind = i + 1;
          break;
        }
      }
    
      int target_argc = (target_opt_ind) ? argc - target_opt_ind : 0;
      char **target_argv = (target_opt_ind) ? argv + target_opt_ind : NULL;
    
      unsigned int pid = GetIntOption("-pid", argc, argv, 0);
      persist = GetBinaryOption("-persist", argc, argv, false);
      num_iterations = GetIntOption("-iterations", argc, argv, 1);
      char *outfile = GetOption("-coverage_file", argc, argv);
    
      if (!target_argc && !pid) {
        printf("Usage:\n");
        printf("%s <options> -- <target command line>\n", argv[0]);
        printf("Or:\n");
        printf("%s <options> -pid <pid to attach to>\n", argv[0]);
        return 0;
      }