I have this code:
#include <stdio.h>
int main()
{
printf("a=%d; b=%d; c=%d", 1, 2, 3);
return 0;
};
I compile it with gcc -g 3arg.cpp
. Disassemble with objdump -d -M intel a.out
. In the output there is exactly one function named _init
and it is disassembled like this:
00000000004003e0 <_init>:
4003e0: 48 83 ec 08 sub rsp,0x8
4003e4: 48 8b 05 0d 0c 20 00 mov rax,QWORD PTR [rip+0x200c0d] # 600ff8 <_DYNAMIC+0x1d0>
4003eb: 48 85 c0 test rax,rax
4003ee: 74 05 je 4003f5 <_init+0x15>
4003f0: e8 3b 00 00 00 call 400430 <__gmon_start__@plt>
4003f5: 48 83 c4 08 add rsp,0x8
4003f9: c3 ret
This is gdb
output:
$ gdb -q a.out
Reading symbols from a.out...done.
(gdb) disassemble _init
Dump of assembler code for function _init:
0x00000000004003e0 <+0>: sub $0x8,%rsp
0x00000000004003e4 <+4>: mov 0x200c0d(%rip),%rax # 0x600ff8
0x00000000004003eb <+11>: test %rax,%rax
0x00000000004003ee <+14>: je 0x4003f5 <_init+21>
0x00000000004003f0 <+16>: callq 0x400430 <__gmon_start__@plt>
0x00000000004003f5 <+21>: add $0x8,%rsp
0x00000000004003f9 <+25>: retq
End of assembler dump.
(gdb) break _init
Breakpoint 1 at 0x4003e0
(gdb) run
Starting program: [redacted]/a.out
Breakpoint 1, _init (argc=1, argv=0x7fffffffdf68, envp=0x7fffffffdf78) at ../csu/init-first.c:52
52 ../csu/init-first.c: No such file or directory.
(gdb) disassemble _init
Dump of assembler code for function _init:
=> 0x00007ffff7a36c20 <+0>: push %r13
0x00007ffff7a36c22 <+2>: push %r12
0x00007ffff7a36c24 <+4>: mov %edi,%r12d
0x00007ffff7a36c27 <+7>: push %rbp
0x00007ffff7a36c28 <+8>: mov %rsi,%rbp
0x00007ffff7a36c2b <+11>: push %rbx
[etc.]
Why is the last disassembly different? It's not even the same data disassembled in a different way (As seen when comparing the objdump
output with output of gdb
command x/10b $rip
when the breakpoint has been hit). If it's a different _init
function:
- how can I put a breakpoint at the one that's seen in the
objdump
output and the first disassembly ingdb
? - why did
gdb
say Breakpoint 1 was at0x4003e0
and then stopped at a different function?