4

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 in gdb?
  • why did gdb say Breakpoint 1 was at 0x4003e0 and then stopped at a different function?

1 Answer 1

10

To arrive to your _init function just continue execution. This will stop once again in the intended place.

    gdb -q test.out
    Reading symbols from test.out...done.
    (gdb) b _init
    Breakpoint 1 at 0x4003e0
    (gdb) run
    Starting program: /home/[censored]/stk/test.out 

    Breakpoint 1, _init (argc=1, argv=0x7fffffffe008, envp=0x7fffffffe018) at ../csu/init-first.c:52
    52  ../csu/init-first.c: No such file or directory.
    (gdb) bt
    #0  _init (argc=1, argv=0x7fffffffe008, envp=0x7fffffffe018) at ../csu/init-first.c:52
    #1  0x00007ffff7dea0fd in call_init (l=0x7ffff7ff74c0, argc=argc@entry=1, argv=argv@entry=0x7fffffffe008, env=env@entry=0x7fffffffe018) at dl-init.c:64
    #2  0x00007ffff7dea223 in call_init (env=<optimized out>, argv=<optimized out>, argc=<optimized out>, l=<optimized out>) at dl-init.c:36
    #3  _dl_init (main_map=0x7ffff7ffe1c8, argc=1, argv=0x7fffffffe008, env=0x7fffffffe018) at dl-init.c:126
    #4  0x00007ffff7ddb30a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
    #5  0x0000000000000001 in ?? ()
    #6  0x00007fffffffe364 in ?? ()
    #7  0x0000000000000000 in ?? ()
    (gdb) c
    Continuing.

    Breakpoint 1, 0x00000000004003e0 in _init ()
    (gdb) bt
    #0  0x00000000004003e0 in _init ()
    #1  0x0000000000400593 in __libc_csu_init ()
    #2  0x00007ffff7a36e55 in __libc_start_main (main=0x40052d <main>, argc=1, argv=0x7fffffffe008, init=0x400560 <__libc_csu_init>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdff8)
        at libc-start.c:246
    #3  0x0000000000400469 in _start ()
    (gdb) info shared
    From                To                  Syms Read   Shared Object Library
    0x00007ffff7ddaae0  0x00007ffff7df54e0  Yes         /lib64/ld-linux-x86-64.so.2
    0x00007ffff7a344a0  0x00007ffff7b79583  Yes         /lib/x86_64-linux-gnu/libc.so.6
    (gdb) x/10i $pc
=> 0x4003e0 <_init>:    sub    $0x8,%rsp
   0x4003e4 <_init+4>:  mov    0x200c0d(%rip),%rax        # 0x600ff8
   0x4003eb <_init+11>: test   %rax,%rax
   0x4003ee <_init+14>: je     0x4003f5 <_init+21>
   0x4003f0 <_init+16>: callq  0x400430 <__gmon_start__@plt>
   0x4003f5 <_init+21>: add    $0x8,%rsp
   0x4003f9 <_init+25>: retq 
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>         
    breakpoint already hit 2 times
1.1                         y     0x00000000004003e0 <_init>
1.2                         y     0x00007ffff7a36c20 in _init at ../csu/init-first.c:52

According to information about shared libraries, it stopped first time in address area of libc.so, which looks like also has _init function, which caused gdb to set this breakpoint there too (see breakpoint definition at the end of the listing).

If you want to set a breakpoint in your specific address, you can use

 b *address

notation. If you want to set a breakpoint on a specific function from specific source file you can use something like

(gdb) break test.c:call1

The same thing is discussed a bit deeper here .

Good luck.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.