https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84550
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Pedro Alves from comment #6)
> I see the same thing with your reduced testcase:
>
> ~~~
> infrun: TARGET_WAITKIND_STOPPED
> infrun: stop_pc = 0x400580
> infrun: stepped into subroutine
> infrun: inserting step-resume breakpoint at 0x400410
> infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current
> thread [process 13966] at 0x400580
> ~~~
>
> 0x400410 is never hit.
>
> With:
>
> (gdb) disassemble /s qux
> Dump of assembler code for function qux(C*):
> t.c:
> 33 if (!p->c) __builtin_abort ();
> 0x0000000000400410 <+0>: callq 0x400400 <abort@plt>
> 0x0000000000400415: nopw %cs:0x0(%rax,%rax,1)
> 0x000000000040041f: nop
> ...
> 0x0000000000400578 <+16>: nopl 0x0(%rax,%rax,1)
>
> 9 return false;
> 0x0000000000400580 <+0>: xor %eax,%eax
> 0x0000000000400582 <+2>: retq
> 0x0000000000400583: nopl (%rax)
> 0x0000000000400586: nopw %cs:0x0(%rax,%rax,1)
> ---Type <return> to continue, or q <return> to quit---
>
> ... we see that "foo" is sharing the tail end of qux?
No, they don't share anything, seems disassemble /s is also confused about it.
qux is only:
33 if (!p->c) __builtin_abort ();
0x0000000000400430 <+0>: callq 0x400420 <abort@plt>
(_Z3quxP1C.cold.0 in .symtab, the cold part of the function) and
26 __attribute__((noipa)) void
27 qux (struct C *p)
28 {
29 struct A *a;
30 bool b;
31 int c;
32
33 if (!p->c) __builtin_abort ();
=> 0x0000000000400590 <+0>: push %rbp
0x0000000000400591 <+1>: push %rbx
0x0000000000400592 <+2>: sub $0x8,%rsp
0x0000000000400596 <+6>: mov (%rdi),%rax
0x0000000000400599 <+9>: test %rax,%rax
0x000000000040059c <+12>: je 0x400430 <qux(C*)>
34 a = p->c->b;
0x00000000004005a2 <+18>: mov (%rax),%rbp
35
36 b = (a->a == 4)
0x00000000004005a5 <+21>: xor %ebx,%ebx
0x00000000004005a7 <+23>: cmpl $0x4,0x0(%rbp)
0x00000000004005ab <+27>: je 0x4005c0 <_Z3quxP1C+48>
37 && (foo (a)
38 || bar (a, 0));
39
40 c = baz (0);
0x00000000004005ad <+29>: xor %edi,%edi
0x00000000004005af <+31>: callq 0x400580 <baz(int)>
41 baz (b);
0x00000000004005b4 <+36>: add $0x8,%rsp
0x00000000004005b8 <+40>: mov %ebx,%edi
0x00000000004005ba <+42>: pop %rbx
0x00000000004005bb <+43>: pop %rbp
0x00000000004005bc <+44>: jmp 0x400580 <baz(int)>
0x00000000004005be <+46>: xchg %ax,%ax
0x00000000004005c0 <+48>: mov %rbp,%rdi
0x00000000004005c3 <+51>: mov $0x1,%ebx
0x00000000004005c8 <+56>: callq 0x400560 <foo(A*)>
0x00000000004005cd <+61>: test %al,%al
0x00000000004005cf <+63>: jne 0x4005ad <_Z3quxP1C+29>
0x00000000004005d1 <+65>: xor %esi,%esi
0x00000000004005d3 <+67>: mov %rbp,%rdi
0x00000000004005d6 <+70>: callq 0x400570 <bar(A*, void*)>
0x00000000004005db <+75>: movzbl %al,%ebx
0x00000000004005de <+78>: jmp 0x4005ad <_Z3quxP1C+29>
which is the actual hot part of the function, _Z3quxP1C symbol in .symtab.
We have:
<1><df>: Abbrev Number: 10 (DW_TAG_subprogram)
<e0> DW_AT_external : 1
<e0> DW_AT_name : qux
<e4> DW_AT_decl_file : 1
<e5> DW_AT_decl_line : 27
<e6> DW_AT_decl_column : 1
<e7> DW_AT_linkage_name: (indirect string, offset: 0x8): _Z3quxP1C
<eb> DW_AT_ranges : 0x0
<ef> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<f1> DW_AT_GNU_all_call_sites: 1
<f1> DW_AT_sibling : <0x18c>
so there is no DW_AT_entry_pc nor DW_AT_low_pc attribute, so the base address
and entry address of the function are the lowest address of the first range in
DW_AT_ranges, which is:
Offset Begin End
00000000 0000000000400590 00000000004005e0
00000000 0000000000400430 0000000000400435
00000000 <End of list>
and that is how GDB should be treating this (both for disassemble/s, as two
separate ranges to print, first the 400590 ... 4005e0 and then 400430 ...
400435, with entry address being 400590.