使用 pin、perf 和 valgrind 计算二进制文件执行的指令数

标签 c assembly valgrind x86-64 perf

我不熟悉用于动态二进制检测的pin 工具。我试图使用 pin 工具 API 编写一些简单的客户端程序。一个这样简单的客户端正在计算二进制文件的执行指令数,该二进制文件作为 pin 的示例之一给出。
我用 C 写了一个非常基础的程序,

int main(){return 0;}

并使用 gcc 编译器编译。当我使用 pin 工具计算用于上述 C 程序的二进制的指令时,它给了我答案 96072
当我使用 valgrind 执行相同的任务时,它给了我 97487 的答案,这几乎与前一个相同。但是当我使用 perf 时,答案是 421,256 各种工具之间存在这种差异的原因是什么?
为了找到更多细节,我将 C 程序编译成一个 x86 程序集,它包含大约 20-30 行汇编指令,但是当我使用 objdump 反汇编二进制文件时,结果是 200-300汇编指令行。我也无法弄清楚造成这种差异的原因。 我正在运行 64 位 Ubuntu 12.04,Linux 内核版本为 3.8.0-39。提前致谢。

最佳答案

When I used valgrind to do the same task it gave me the answer of 97487 which is nearly equal to the previous one. But when I used perf the answer is 421,256. What would be the reason for this discrepancy among various tools?

我的猜测是 perf 为您提供用户 内核模式指令(这是默认设置)。请尝试

    perf stat -e instructions:u your_executable

应该只计算在用户模式下执行的指令。更多详细信息,请参阅 perf tutorial .

To find more details I have compiled the C program into a x86 assembly and it consists about 20-30 lines of assembly instructions, But when I used objdump to disassemble the binary it was result in a 200-300 lines of assembly instructions. I was not able to figure out the reason for this difference too.

在第一种情况下,您只能获得专用于您的代码的汇编指令。在第二种情况下,您将获得可执行文件中包含的所有指令。请编译

    int main() { }

并运行 objdump -d name_of_the_executable。正如您将看到的,在执行 main() 之前会发生许多事情;在 main() 完成后,执行清理。

Linux x86 Program Start Up or - How the heck do we get to main()?似乎是一个不错的教程。

关于使用 pin、perf 和 valgrind 计算二进制文件执行的指令数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23289713/

相关文章:

c - 数组缓冲区和 winapi

c - 为什么不可能用指针表示法取消引用特定的数组索引

c - xv6源码中cga_init()中的0xa55a是什么意思?

c - FSM 中的函数指针

c - 如何在 C 中编写高级概念(即对象类和泛型)

c - 在递归函数中使用 libpcre

c++ - 与 Valgrind 一起运行时,malloc 返回 null

assembly - 我的汇编程序中的段错误?但那是不可能的! :O

c - 汇编中没有换行符的 Printf

c - 如何跟踪特定值的 "fate"?