The 'cold' function attribute and GDB

Kevin Buettner kevinb@redhat.com
Thu May 2 23:30:00 GMT 2019


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

> > What I (think I) actually want to see is "x/i 0x012e1f36".  
> 
>   (gdb) x/i 0x012e1f36
>      0x12e1f36 <print_vectorlike.cold.65+593>:    call   0x12e7b40 <emacs_abort>

Eli provided me with a windows executable.  Using an x86_64 GDB built
with --enable-targets=all, I'm able to reproduce the behavior quoted above:

Reading symbols from bootstrap-emacs.exe...
(gdb) info target
Symbols from "/mesquite2/sourceware-git/f30-ranges/tst/bootstrap-emacs.exe".
Local exec file:
	`/mesquite2/sourceware-git/f30-ranges/tst/bootstrap-emacs.exe', 
        file type pei-i386.
	Entry point: 0x127b5c9
	0x01001000 - 0x012eb984 is .text
	0x012ec000 - 0x0160e240 is .data
	0x0160f000 - 0x01619580 is .subrs
	0x0161a000 - 0x0165a950 is .rdata
	0x0165b000 - 0x016b5d1c is .eh_frame
	0x016b6000 - 0x017389a0 is .bss
	0x01739000 - 0x0173d574 is .idata
	0x0173e000 - 0x0173e018 is .CRT
	0x0173f000 - 0x0173f020 is .tls
	0x01740000 - 0x0179b388 is .rsrc
(gdb) x/i 0x12e1f36
   0x12e1f36 <print_vectorlike.cold.65+593>:	call   0x12e7b40 <emacs_abort>

For those who haven't been following along, we might prefer to see
print_vectorlike+SomeConstant instead of the symbol
print_vectorlike.cold.65.  It might not be that objectionable in this
context; I think it's more confusing in a backtrace, where it's shown
as a function which doesn't exist in the user's code.  E.g. this is
the frame from Eli's first message in this thread:

  #2  0x012e1f3b in print_vectorlike.cold () at print.c:1824 

This behavior is, apparently, intentional.  The function
build_address_symbolic in printcmd.c contains the following
statements; in particular note the second comment:

  if (msymbol.minsym != NULL)
    {
      if (BMSYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL)
	{
	  /* If this is a function (i.e. a code address), strip out any
	     non-address bits.  For instance, display a pointer to the
	     first instruction of a Thumb function as <function>; the
	     second instruction will be <function+2>, even though the
	     pointer is <function+3>.  This matches the ISA behavior.  */
	  if (MSYMBOL_TYPE (msymbol.minsym) == mst_text
	      || MSYMBOL_TYPE (msymbol.minsym) == mst_text_gnu_ifunc
	      || MSYMBOL_TYPE (msymbol.minsym) == mst_file_text
	      || MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline)
	    addr = gdbarch_addr_bits_remove (gdbarch, addr);

	  /* The msymbol is closer to the address than the symbol;
	     use the msymbol instead.  */
	  symbol = 0;
	  name_location = BMSYMBOL_VALUE_ADDRESS (msymbol);
	  if (do_demangle || asm_demangle)
	    name_temp = MSYMBOL_PRINT_NAME (msymbol.minsym);
	  else
	    name_temp = MSYMBOL_LINKAGE_NAME (msymbol.minsym);
	}
    }

When I traced it, prior to getting to the outer if statement,
name_location contained the address of 'print_vectorlike' and
name_temp was set to "print_vectorlike".  So, if we were to
*not* execute this code, we wouldn't use the minimal symbol.

To test this, I disabled the code above via #if 0 ... #endif.  Here's
what I see when I do this:

(gdb) x/i 0x12e1f36
   0x12e1f36 <print_vectorlike+1096213>:	call   0x12e7b40 <emacs_abort>

I didn't see this behavior on my Linux build of emacs due to the fact
that the .cold symbol was placed at an address that's lower than that
of the non-cold symbol.

With all of that said, I don't think it actually helps with the
backtrace problem.  It appears that build_address_symbolic is only
used for disassembly.  After poking around, however, I think the
equivalent bit of code may be found in find_frame_funname in stack.c.
The hunk of code which you'll want to disable is:

      if (msymbol.minsym != NULL
	  && (BMSYMBOL_VALUE_ADDRESS (msymbol)
	      > BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func))))
	{
	  /* We also don't know anything about the function besides
	     its address and name.  */
	  func = 0;
	  funname.reset (xstrdup (MSYMBOL_PRINT_NAME (msymbol.minsym)));
	  *funlang = MSYMBOL_LANGUAGE (msymbol.minsym);
	}

Doing this sort of thing - preferring the minimal symbol over the
the symbol might make sense for displaying assembly addresses - but
I'm not convinced that it makes sense for printing frame functions.

It would be possible to disable that code only when the frame pc
is in a block which is in discontiguous block.  If someone thinks
this is a good idea, I can provide a patch, but someone else will
need to test it.

Kevin



More information about the Gdb-patches mailing list