Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting number of instructions executed by a binary using pin, perf and valgrind

I am new to pin tool which is used for dynamic binary instrumentation. I was trying to write some simple client programs using pin tool API. One such simple client is counting the number of executed instruction of a binary which is given as one of the examples of pin.
I wrote a very basic program in C,

int main(){return 0;}

and compiled using the gcc compiler. when I use the pin tool to count the instructions used for the binary of the above C program it gave me the answer 96072
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?
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. I am running 64 bit Ubuntu 12.04 with the Linux kernel version 3.8.0-39. Thanks in advance.

like image 663
Kirshanthan Sundararajah Avatar asked Apr 25 '14 09:04

Kirshanthan Sundararajah


1 Answers

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?

My guess is that perf gives you both user and kernel mode instructions (this is the default). Please try

    perf stat -e instructions:u your_executable

which is supposed to count only instructions executed in user mode. More details in the 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.

In the first case you only get the assembly instructions exclusively for your code. In the second case you get all the instructions contained in the executable. Please compile

    int main() { }

and run objdump -d name_of_the_executable. As you will see, many things happen before the main() is executed; and after main() has finished, a clean-up is executed.

Linux x86 Program Start Up or - How the heck do we get to main()? seems like a nice tutorial.

like image 56
Ali Avatar answered Oct 15 '22 14:10

Ali