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.