c++ - gcc - 如何自动检测每个基本 block

标签 c++ c gcc instrumentation

GCC 有一个 auto-instrument options for function entry/exit.

-finstrument-functions Generate instrumentation calls for entry and exit to functions. Just after function entry and just before function exit, the following profiling functions will be called with the address of the current function and its call site. (On some platforms, __builtin_return_address does not work beyond the current function, so the call site information may not be available to the profiling functions otherwise.) void __cyg_profile_func_enter (void *this_fn, void *call_site); void __cyg_profile_func_exit (void *this_fn, void *call_site);

我希望每个 "basic block" 都有这样的东西这样我就可以动态地记录每个分支的执行情况。

我该怎么做?

最佳答案

有一个名为 American Fuzzy Lop 的模糊器,它解决了非常相似的问题,即检测基本 block 之间的跳跃以收集边缘覆盖:如果基本 block 是顶点,则在执行过程中遇到了哪些跳跃(边缘)。可能值得查看其来源。它具有三种方法:

  • afl-gcc 是 gcc 的包装器,它通过包装器根据基本 block 标签和跳转指令重写汇编代码来替换 as
  • Clang 编译器插件
  • 用于检测已编译代码的 QEMU 补丁

另一个可能是最简单的选择可能是使用 DynamoRIO动态仪表系统。与 QEMU 不同,它是专门为实现自定义检测而设计的(要么是手动重写机器代码,要么是简单地插入调用,如果我得到正确的文档,在某些情况下甚至可以自动内联)。如果您认为动态检测非常困难,请查看他们的示例——它们只有大约 100-200 行(但您仍然需要至少阅读他们的文档 here 以及使用过的函数,因为它可能包含要点:对于例如 DR constructs dynamic basic blocks, which are distinct from a compiler's classic basic blocks )。使用动态检测,您甚至可以检测使用过的系统库。如果这不是您想要的,您可以使用类似的东西

static module_data_t *traced_module;

// in dr_client_main
traced_module = dr_get_main_module();

// in basic block event handler
void *app_pc = dr_fragment_app_pc(tag);
if (!dr_module_contains_addr(traced_module, app_pc)) {
    return DR_EMIT_DEFAULT;
}

关于c++ - gcc - 如何自动检测每个基本 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44011376/

相关文章:

正在编译 GCC NOP

c++ - MSVS 2010 和 C++ 标准的构建问题

C : Cannot access memory error, 递归查找 AVL 树高度时

c - 为什么 ld 在将可执行文件与 a 链接时需要 -rpath-link 以便需要另一个 so ?

在c中找不到内存泄漏

c - realloc() C语言改变int数组中的值

c - 如何丑化或缩小 C 代码

C++:索引超出范围

c++ - CMFCPopupMenu - 右键单击​​上下文菜单快捷键由于某种原因消失

c++ - 在 Gmock 的 EXPECT_CALL 之前使用 ON_CALL 时的奇怪行为