Re: The 'cold' function attribute and GDB

Kevin Buettner
2019-05-02T18:25:21Z

On Thu, 02 May 2019 18:23:20 +0300
Eli Zaretskii <eliz@gnu.org> wrote:

> > Date: Thu, 2 May 2019 00:38:49 -0700
> > From: Kevin Buettner <kevinb@redhat.com>
> > Cc: gdb-patches@sourceware.org, Simon Marchi <simark@simark.ca>
> >
> > Can you show me what is printed for the following commands?
> >
> > disassemble print_vectorlike
> > x/3i print_vectorlike
> > b print_vectorlike
> >
> > For the disassemble command, I expect both ranges to be displayed.
> > The x and b commands should print insns / set a breakpoint on the entry
> > pc (which should NOT be the cold address) of the function. If one or more
> > of these things aren't happening, then something is going wrong
> > somewhere.
>
> Here:
>
> (gdb) disassemble /m print_vectorlike
> Dump of assembler code for function print_vectorlike:
> Address range 0x11d6521 to 0x11d81d6:
> 1367 {
> 0x011d6521 <+0>: push %ebp
> 0x011d6522 <+1>: mov %esp,%ebp
> 0x011d6524 <+3>: push %edi
> 0x011d6525 <+4>: push %esi
> 0x011d6526 <+5>: push %ebx
> 0x011d6527 <+6>: sub $0x7c,%esp
> [...]
> Address range 0x12e1ce5 to 0x12e1f3b:
> 1824 emacs_abort ();
> 0x012e1f36 <+593>: call 0x12e7b40 <emacs_abort>
>
> End of assembler dump.
>
> (gdb) x/3i print_vectorlike
> 0x11d6521 <print_vectorlike>: push %ebp
> 0x11d6522 <print_vectorlike+1>: mov %esp,%ebp
> 0x11d6524 <print_vectorlike+3>: push %edi
> (gdb) break print_vectorlike
> Breakpoint 1 at 0x11d6521: file print.c, line 1367.
>
> Seems to be according to your expectations.
>
> Btw, if I use a source line number whose code is in the 'cold' area,
> then I see this:
>
> (gdb) break print.c:1824
> Breakpoint 1 at 0x12e1f36: file print.c, line 1824.
> (gdb) info line print.c:1824
> Line 1824 of "print.c"
> starts at address 0x12e1f36 <print_vectorlike.cold.65+593>
> and ends at 0x12e1f3b <print_vectorlike.cold.65+598>.

I have built emacs on Fedora 29 (GCC 8.3.1) and Fedora 30 (GCC 9.0.1).
So far, the output of the commands that I've tried has been largely
the same between these versions. So, in the output below, I'll only
show the Fedora 30 / GCC 9.0.1 output.

This is what I see for disassemble. There are indeed two address
ranges. It looks reasonable to me.

(gdb) disassemble print_vectorlike
Dump of assembler code for function print_vectorlike:
Address range 0x58cab0 to 0x58d88b:
0x000000000058cab0 <+0>: movabs $0x4000000000000000,%rax
0x000000000058caba <+10>: push %rbp
0x000000000058cabb <+11>: mov %rsp,%rbp
0x000000000058cabe <+14>: push %r15
0x000000000058cac0 <+16>: mov %rdi,%r15
0x000000000058cac3 <+19>: push %r14
0x000000000058cac5 <+21>: mov %rcx,%r14
0x000000000058cac8 <+24>: push %r13
0x000000000058caca <+26>: mov %edx,%r13d
0x000000000058cacd <+29>: push %r12
0x000000000058cacf <+31>: mov %rsi,%r12
0x000000000058cad2 <+34>: push %rbx
0x000000000058cad3 <+35>: sub $0x28,%rsp
0x000000000058cad7 <+39>: mov -0x5(%rdi),%rbx
0x000000000058cadb <+43>: and %rbx,%rax
[...]
0x000000000058d452 <+3522>: callq 0x5878d0 <printchar>
0x000000000058d457 <+3527>: jmpq 0x58c736 <print_vectorlike+166>
Address range 0x41f3e9 to 0x41f3ee:
0x000000000041f3e9 <+-1495719>: callq 0x41c744 <emacs_abort>
End of assembler dump.

I also tried disassemble /m. It produces a lot of output, so much
output in fact, that I found it to be extremely unhelpful. I think
it's related to the fact that it's picking up inline expansions from
lisp.h. However, in addition to printing too much source code, it
also seemed to print too much disassembly. I think that once it got
started disassembling code from lisp.h, it continued to the end of
the file.

Here's the x/3i command:

(gdb) x/3i print_vectorlike
0x58cab0 <print_vectorlike>: movabs $0x4000000000000000,%rax
0x58caba <print_vectorlike+10>: push %rbp
0x58cabb <print_vectorlike+11>: mov %rsp,%rbp

This looks fine to me.

Here's the breakpoint command:

(gdb) b print_vectorlike
Breakpoint 3 at 0x58cab0: file /ironwood1/emacs-git/f30/bld/../../emacs/src/lisp.h, line 1666.

This looks odd to me too. Most users, myself included, would expect to see
the breakpoint set in print.c at line 1367 or 1368.

Let's see what "info line" says about the start address:

(gdb) info line *0x58cab0
Line 1666 of "/ironwood1/emacs-git/f30/bld/../../emacs/src/lisp.h"
starts at address 0x58cab0 <print_vectorlike>
and ends at 0x58cadb <print_vectorlike+43>.

It appears to me that the compiler has moved one of the instructions
for PSEUDOVECTOR_TYPE, an inline function defined in lisp.h, ahead of
the prologue instructions for print_vectorlike.

.debug_line contains information about both lines and addresses for both
files; the file name table for this hunk shows print.c at entry 1 and
lisp.h at entry 2:

[0x002a97eb] Set File Name to entry 1 in the File Name Table
[...]
[0x002a980c] Set is_stmt to 1
[0x002a980d] Advance Line by -821 to 1367
[0x002a9810] Special opcode 117: advance Address by 8 to 0x58cab0 and Line by 0 to 1367
[0x002a9811] Set column to 3
[0x002a9813] Special opcode 6: advance Address by 0 to 0x58cab0 and Line by 1 to 1368 (view 1)
[0x002a9814] Set File Name to entry 2 in the File Name Table
[0x002a9816] Advance Line by 262 to 1630
[0x002a9819] Copy (view 2)
[0x002a981a] Special opcode 6: advance Address by 0 to 0x58cab0 and Line by 1 to 1631 (view 3)
[0x002a981b] Advance Line by -890 to 741
[0x002a981e] Copy (view 4)
[0x002a981f] Set column to 1
[0x002a9821] Advance Line by 923 to 1664
[0x002a9824] Copy (view 5)
[0x002a9825] Set column to 3
[0x002a9827] Special opcode 7: advance Address by 0 to 0x58cab0 and Line by 2 to 1666 (view 6)
[0x002a9828] Set column to 16
[0x002a982a] Set is_stmt to 0
[0x002a982b] Special opcode 6: advance Address by 0 to 0x58cab0 and Line by 1 to 1667 (view 7)
[0x002a982c] Set File Name to entry 1 in the File Name Table
[0x002a982e] Set column to 1
[0x002a9830] Advance Line by -300 to 1367
[0x002a9833] Special opcode 145: advance Address by 10 to 0x58caba and Line by 0 to 1367
[0x002a9834] Set File Name to entry 2 in the File Name Table

I haven't yet checked to see what GDB is doing with this info. However, if
the addresses/lines associated with print.c are still available, it makes
(more) sense to use them here in this context.

I also did some operations on the address in the second range:

(gdb) x/i 0x000000000041fed1
0x41fed1 <print_vectorlike+4293473313>: callq 0x41cca5 <emacs_abort>
(gdb) b *0x41fed1
Breakpoint 6 at 0x41fed1: file /ironwood1/emacs-git/f30/bld/../../emacs/src/print.c, line 1824.
(gdb) info line *0x41fed1
Line 1824 of "/ironwood1/emacs-git/f30/bld/../../emacs/src/print.c"
starts at address 0x41fed1 <print_vectorlike+4293473313>
and ends at 0x5873b0 <print_unwind>.

These look okay to me too. On Linux, I think we're lacking the minimal
symbol which Eli is seeing on Windows.

(During my first try at this, I thought I was seeing an incorrect result
when setting the breakpoint. But I don't have enough scrollback to be
able to reexamine what happened. I'll play with it a bit more because
what I saw definitely felt like a bug, though not the problem that Eli is
seeing.)

Kevin