From: Pepper G. <he...@pe...> - 2024-10-24 11:54:55
|
Hi, I'm having an issue with callgrind, and unfortunately I didn't find any further information in the docs: The instruction count is not what I expect and differs from single stepping the binary. I'm on x86_64-linux-gnu I created a simple hello world example: global _start section .text _start: mov rax, 1 ; write( mov rdi, 1 ; STDOUT_FILENO, mov rsi, msg ; "Hello, world!\n", mov rdx, msglen ; sizeof("Hello, world!\n") syscall ; ); mov rax, 60 ; exit( mov rdi, 0 ; EXIT_SUCCESS syscall ; ); section .rodata msg: db "Hello, world!", 10 msglen: equ $ - msg Which has 8 instructions: $ objdump -d hello hello: file format elf64-x86-64 Disassembly of section .text: 0000000000401000 <_start>: 401000: b8 01 00 00 00 mov $0x1,%eax 401005: bf 01 00 00 00 mov $0x1,%edi 40100a: 48 be 00 20 40 00 00 movabs $0x402000,%rsi 401011: 00 00 00 401014: ba 0e 00 00 00 mov $0xe,%edx 401019: 0f 05 syscall 40101b: b8 3c 00 00 00 mov $0x3c,%eax 401020: bf 00 00 00 00 mov $0x0,%edi 401025: 0f 05 syscall Running "valgrind --tool=callgrind ./hello" gives me only 5 instructions: Hello, world! ==443229== ==443229== Events : Ir ==443229== Collected : 5 ==443229== ==443229== I refs: 5 When I create a dump "valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes ./hello" and check the machie code out using KCachegrind: # Ir Hex Assembly Instructions Source Position 40 1000 █ 20.00 b8 01 00 00 00 mov $0x1, %eax (unknown) 40 1005 █ 20.00 bf 01 00 00 00 mov $0x1, %edi (unknown) 40 100A █ 20.00 48 be 00 20 40 00 00 movabs $0x402000, %rsi (unknown) 40 1011 20.00 00 00 00 40 1014 █ 20.00 ba 0e 00 00 00 mov $0xe, %edx (unknown) 40 1019 █ 20.00 0f 05 syscall (unknown) 40 101B b8 3c 00 00 00 mov $0x3c, %eax 40 1020 bf 00 00 00 00 mov $0x0, %edi So it seems it doesn't capture the last syscall and doesn't count the last two mov instructions. I also checked with c files: #include <stdio.h> int main() { printf("Hello, world!\n"); return 0; } where valgrind gives me 139,482: Hello, world! ==444986== ==444986== Events : Ir ==444986== Collected : 139482 ==444986== ==444986== I refs: 139,482 whilst when I use fork, execv, ptrace(PTRACE_TRACEME, 0, 0, 0) ptrace(PTRACE_SINGLESTEP, pid, 0, 0) to single step the binary, and count the steps, I get 126,042. Am I missing something, or is callgrind counting something else than steps? How can I make these numbers line up? KR Pepper |