Re: The 'cold' function attribute and GDB

Simon Marchi
2019-05-01T20:17:09Z

On 2019-05-01 2:58 p.m., Eli Zaretskii wrote:
> If some functions in your program are declared with
> __attribute__((cold)), GCC generates local symbols of the form
> FOO.cold, where FOO is a function that has a code path which
> eventually calls one of the 'cold' functions. When GDB needs to show
> a backtrace or a stack frame inside one of these code paths, it shows
> FOO.cold as the name of the function. Here's a real-life example:
>
> Thread 1 received signal SIGTRAP, Trace/breakpoint trap.
> 0x76a63227 in KERNELBASE!DebugBreak () from C:\Windows\syswow64\KernelBase.dll
> (gdb) thread 1
> [Switching to thread 1 (Thread 7552.0x172c)]
> #0 0x76a63227 in KERNELBASE!DebugBreak ()
> from C:\Windows\syswow64\KernelBase.dll
> (gdb) up
> #1 0x012e7b89 in emacs_abort () at w32fns.c:10768
> 10768 DebugBreak ();
> (gdb)
> #2 0x012e1f3b in print_vectorlike.cold () at print.c:1824 <<<<<<<<<<<<<<<<
> 1824 emacs_abort ();
> (gdb) bt
> #0 0x76a63227 in KERNELBASE!DebugBreak ()
> from C:\Windows\syswow64\KernelBase.dll
> #1 0x012e7b89 in emacs_abort () at w32fns.c:10768
> #2 0x012e1f3b in print_vectorlike.cold () at print.c:1824 <<<<<<<<<<<<<<<<
> #3 0x011d2dec in print_object (obj=<optimized out>, printcharfun=XIL(0),
> escapeflag=true) at print.c:2150

The way this is written:

print_vectorlike.cold ()

makes me thing that GDB didn't find a full symbol (DWARF symbol) for this address, so
fell back on the nearest preceding minimal symbol (ELF symbol). I say this because it
lacks the arguments here, but it does accept some parameter in the code. If GDB had
found the full symbol, it should show the arguments, and the function name, print_vectorlike.

So I would inspect the DWARF info generated by gcc for the print_vectorlike function to
see what GDB is working with, it will be easier to know where to search.

In particular, how does the DWARF info describe the address range or ranges taken by
the print_vectorlike function? In an ideal world, if gcc generates two separate ranges
of instruction for this function (the hot path and the cold path), it should describe
it as two ranges in the entry for print_vectorlike. If so, it should be described with
a DW_AT_ranges attribute.

If you are not sure what to look for, try to find the debug info entry for print_vectorlike
and paste it here.

Also, which commit of GDB is this with? I recall some patches related to non-contiguous
address ranges not too long ago.

> There's a print_vectorlike function in Emacs, and it calls
> emacs_abort, which is declared 'cold' (because it is called in case of
> fatal errors and doesn't return).
>
> Since the 'cold' functions tend to be those that are called in case of
> some calamity, and since GDB is likely to be used to debug such
> calamities, and the user is likely to put breakpoint in such 'cold'
> functions precisely to catch these calamities, the above is not such a
> rare use case as far as real-life use of GDB goes.
>
> I think this display is confusing, but is there any reasonable way for
> GDB not to expose these symbols to the user?

I guess that it would be possible to handle specially minimal symbols named something.cold,
but it should not be necessary if we have good debug info and use it correctly, so I would
prefer not to go that route.

Simon