binutils-gdb modified for the FreeChainXenon project
Find a file
Simon Marchi 19f988359a gdb: give sentinel for user frames distinct IDs, register sentinel frames to the frame cache
The test gdb.base/frame-view.exp fails like this on AArch64:

    frame^M
    #0  baz (z1=hahaha, /home/simark/src/binutils-gdb/gdb/value.c:4056: internal-error: value_fetch_lazy_register: Assertion `next_frame != NULL' failed.^M
    A problem internal to GDB has been detected,^M
    further debugging may prove unreliable.^M
    FAIL: gdb.base/frame-view.exp: with_pretty_printer=true: frame (GDB internal error)

The sequence of events leading to this is the following:

 - When we create the user frame (the "select-frame view" command), we
   create a sentinel frame just for our user-created frame, in
   create_new_frame.  This sentinel frame has the same id as the regular
   sentinel frame.

 - When printing the frame, after doing the "select-frame view" command,
   the argument's pretty printer is invoked, which does an inferior
   function call (this is the point of the test).  This clears the frame
   cache, including the "real" sentinel frame, which sets the
   sentinel_frame global to nullptr.

 - Later in the frame-printing process (when printing the second
   argument), the auto-reinflation mechanism re-creates the user frame
   by calling create_new_frame again, creating its own special sentinel
   frame again.  However, note that the "real" sentinel frame, the
   sentinel_frame global, is still nullptr.  If the selected frame had
   been a regular frame, we would have called get_current_frame at some
   point during the reinflation, which would have re-created the "real"
   sentinel frame.  But it's not the case when reinflating a user frame.

 - Deep down the stack, something wants to fill in the unwind stop
   reason for frame 0, which requires trying to unwind frame 1.  This
   leads us to trying to unwind the PC of frame 1:

     #0  gdbarch_unwind_pc (gdbarch=0xffff8d010080, next_frame=...) at /home/simark/src/binutils-gdb/gdb/gdbarch.c:2955
     #1  0x000000000134569c in dwarf2_tailcall_sniffer_first (this_frame=..., tailcall_cachep=0xffff773fcae0, entry_cfa_sp_offsetp=0xfffff7f7d450)
         at /home/simark/src/binutils-gdb/gdb/dwarf2/frame-tailcall.c:390
     #2  0x0000000001355d84 in dwarf2_frame_cache (this_frame=..., this_cache=0xffff773fc928) at /home/simark/src/binutils-gdb/gdb/dwarf2/frame.c:1089
     #3  0x00000000013562b0 in dwarf2_frame_unwind_stop_reason (this_frame=..., this_cache=0xffff773fc928) at /home/simark/src/binutils-gdb/gdb/dwarf2/frame.c:1101
     #4  0x0000000001990f64 in get_prev_frame_always_1 (this_frame=...) at /home/simark/src/binutils-gdb/gdb/frame.c:2281
     #5  0x0000000001993034 in get_prev_frame_always (this_frame=...) at /home/simark/src/binutils-gdb/gdb/frame.c:2376
     #6  0x000000000199b814 in get_frame_unwind_stop_reason (frame=...) at /home/simark/src/binutils-gdb/gdb/frame.c:3051
     #7  0x0000000001359cd8 in dwarf2_frame_cfa (this_frame=...) at /home/simark/src/binutils-gdb/gdb/dwarf2/frame.c:1356
     #8  0x000000000132122c in dwarf_expr_context::execute_stack_op (this=0xfffff7f80170, op_ptr=0xffff8d8883ee "\217\002", op_end=0xffff8d8883ee "\217\002")
         at /home/simark/src/binutils-gdb/gdb/dwarf2/expr.c:2110
     #9  0x0000000001317b30 in dwarf_expr_context::eval (this=0xfffff7f80170, addr=0xffff8d8883ed "\234\217\002", len=1) at /home/simark/src/binutils-gdb/gdb/dwarf2/expr.c:1239
     #10 0x000000000131d68c in dwarf_expr_context::execute_stack_op (this=0xfffff7f80170, op_ptr=0xffff8d88840e "", op_end=0xffff8d88840e "") at /home/simark/src/binutils-gdb/gdb/dwarf2/expr.c:1811
     #11 0x0000000001317b30 in dwarf_expr_context::eval (this=0xfffff7f80170, addr=0xffff8d88840c "\221p", len=2) at /home/simark/src/binutils-gdb/gdb/dwarf2/expr.c:1239
     #12 0x0000000001314c3c in dwarf_expr_context::evaluate (this=0xfffff7f80170, addr=0xffff8d88840c "\221p", len=2, as_lval=true, per_cu=0xffff90b03700, frame=..., addr_info=0x0,
         type=0xffff8f6c8400, subobj_type=0xffff8f6c8400, subobj_offset=0) at /home/simark/src/binutils-gdb/gdb/dwarf2/expr.c:1078
     #13 0x000000000149f9e0 in dwarf2_evaluate_loc_desc_full (type=0xffff8f6c8400, frame=..., data=0xffff8d88840c "\221p", size=2, per_cu=0xffff90b03700, per_objfile=0xffff9070b980,
         subobj_type=0xffff8f6c8400, subobj_byte_offset=0, as_lval=true) at /home/simark/src/binutils-gdb/gdb/dwarf2/loc.c:1513
     #14 0x00000000014a0100 in dwarf2_evaluate_loc_desc (type=0xffff8f6c8400, frame=..., data=0xffff8d88840c "\221p", size=2, per_cu=0xffff90b03700, per_objfile=0xffff9070b980, as_lval=true)
         at /home/simark/src/binutils-gdb/gdb/dwarf2/loc.c:1557
     #15 0x00000000014aa584 in locexpr_read_variable (symbol=0xffff8f6cd770, frame=...) at /home/simark/src/binutils-gdb/gdb/dwarf2/loc.c:3052

 - AArch64 defines a special "prev register" function,
   aarch64_dwarf2_prev_register, to handle unwinding the PC.  This
   function does

     frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM);

 - frame_unwind_register_unsigned ultimately creates a lazy register
   value, saving the frame id of this_frame->next.  this_frame is the
   user-created frame, to this_frame->next is the special sentinel frame
   we created for it.  So the saved ID is the sentinel frame ID.

 - When time comes to un-lazify the value, value_fetch_lazy_register
   calls frame_find_by_id, to find the frame with the ID we saved.

 - frame_find_by_id sees it's the sentinel frame ID, so returns the
   sentinel_frame global, which is, if you remember, nullptr.

 - We hit the `gdb_assert (next_frame != NULL)` assertion in
   value_fetch_lazy_register.

The issues I see here are:

 - The ID of the sentinel frame created for the user-created frame is
   not distinguishable from the ID of the regular sentinel frame.  So
   there's no way frame_find_by_id could find the right frame, in
   value_fetch_lazy_register.
 - Even if they had distinguishable IDs, sentinel frames created for
   user frames are not registered anywhere, so there's no easy way
   frame_find_by_id could find it.

This patch addresses these two issues:

 - Give sentinel frames created for user frames their own distinct IDs
 - Register sentinel frames in the frame cache, so they can be found
   with frame_find_by_id.

I initially had this split in two patches, but I then found that it was
easier to explain as a single patch.

Rergarding the first part of the change: with this patch, the sentinel
frames created for user frames (in create_new_frame) still have
stack_status == FID_STACK_SENTINEL, but their code_addr and stack_addr
fields are now filled with the addresses used to create the user frame.
This ensures this sentinel frame ID is different from the "target"
sentinel frame ID, as well as any other "user" sentinel frame ID.  If
the user tries to create the same frame, with the same addresses,
multiple times, create_sentinel_frame just reuses the existing frame.
So we won't end up with multiple user sentinels with the same ID.

Regular "target" sentinel frames remain with code_addr and stack_addr
unset.

The concrete changes for that part are:

 - Remove the sentinel_frame_id constant, since there isn't one
   "sentinel frame ID" now.  Add the frame_id_build_sentinel function
   for building sentinel frame IDs and a is_sentinel_frame_id function
   to check if a frame id represents a sentinel frame.
 - Replace the sentinel_frame_id check in frame_find_by_id with a
   comparison to `frame_id_build_sentinel (0, 0)`.  The sentinel_frame
   global is meant to contain a reference to the "target" sentinel, so
   the one with addresses (0, 0).
 - Add stack and code address parameters to create_sentinel_frame, to be
   able to create the various types of sentinel frames.
 - Adjust get_current_frame to create the regular "target" sentinel.
 - Adjust create_new_frame to create a sentinel with the ID specific to
   the created user frame.
 - Adjust sentinel_frame_prev_register to get the sentinel frame ID from
   the frame_info object, since there isn't a single "sentinel frame ID"
   now.
 - Change get_next_frame_sentinel_okay to check for a
   sentinel-frame-id-like frame ID, rather than for sentinel_frame
   specifically, since this function could be called with another
   sentinel frame (and we would want the assert to catch it).

The rest of the change is about registering the sentinel frame in the
frame cache:

 - Change frame_stash_add's assertion to allow sentinel frame levels
   (-1).
 - Make create_sentinel_frame add the frame to the frame cache.
 - Change the "sentinel_frame != NULL" check in reinit_frame_cache for a
   check that the frame stash is not empty.  The idea is that if we only
   have some user-created frames in the cache when reinit_frame_cache is
   called, we probably want to emit the frames invalid annotation.  The
   goal of that check is to avoid unnecessary repeated annotations, I
   suppose, so the "frame cache not empty" check should achieve that.

After this change, I think we could theoritically get rid of the
sentienl_frame global.  That sentinel frame could always be found by
looking up `frame_id_build_sentinel (0, 0)` in the frame cache.
However, I left the global there to avoid slowing the typical case down
for nothing.  I however, noted in its comment that it is an
optimization.

With this fix applied, the gdb.base/frame-view.exp now passes for me on
AArch64.  value_of_register_lazy now saves the special sentinel frame ID
in the value, and value_fetch_lazy_register is able to find that
sentinel frame after the frame cache reinit and after the user-created
frame was reinflated.

Tested-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
Tested-By: Luis Machado <luis.machado@arm.com>
Change-Id: I8b77b3448822c8aab3e1c3dda76ec434eb62704f
2023-02-08 16:38:59 -05:00
bfd Re: Resetting section vma after _bfd_dwarf2_find_nearest_line 2023-02-08 11:17:00 +10:30
binutils Fix documentation of the 'n' symbol type displayed by nm. 2023-02-07 11:41:28 +00:00
config Merge config/picflag.m4 from gcc 2023-01-04 13:23:54 +10:30
contrib
cpu bpf: fix error conversion from long unsigned int to unsigned int [-Werror=overflow] 2023-02-03 11:18:50 -06:00
elfcpp Update year range in copyright notice of binutils files 2023-01-01 21:50:11 +10:30
etc Update year range in gprofng copyright notices 2023-01-01 23:26:30 +10:30
gas x86: drop LOCK from XCHG when optimizing 2023-02-03 08:23:05 +01:00
gdb gdb: give sentinel for user frames distinct IDs, register sentinel frames to the frame cache 2023-02-08 16:38:59 -05:00
gdbserver gdbserver: Add PID parameter to linux_get_auxv and linux_get_hwcap 2023-02-01 20:42:50 +00:00
gdbsupport gdbsupport: add type definitions for pid, lwp and tid 2023-02-02 10:02:34 -05:00
gnulib Update copyright year range in header of all files managed by GDB 2023-01-01 17:01:16 +04:00
gold Use __func__ rather than __FUNCTION__ 2023-01-12 17:20:21 +10:30
gprof Updated transaltions for the gprof and binutils sub-directories 2023-01-09 10:24:13 +00:00
gprofng gprofng: fix SIGSEGV when processing unusual dwarf 2023-02-07 21:26:21 -08:00
include ppc32 and "LOAD segment with RWX permissions" 2023-02-06 23:06:44 +10:30
intl egrep in binutils 2022-09-28 13:37:31 +09:30
ld ppc32 and "LOAD segment with RWX permissions" 2023-02-06 23:06:44 +10:30
libbacktrace Ensure that libbacktrace/allocfail.sh is not deleted when creating release tarballs. 2023-01-12 13:39:03 +00:00
libctf libctf: update regexp to allow makeinfo to build document 2023-01-16 23:18:38 +08:00
libdecnumber Merge config/ changes from GCC, to enable DFP on AArch64 2022-05-24 10:47:29 +01:00
libiberty Merge config/picflag.m4 from gcc 2023-01-04 13:23:54 +10:30
libsframe libsframe/doc: use "stack trace" instead of "unwind" for SFrame 2023-02-02 00:47:22 -08:00
opcodes bpf: fix error conversion from long unsigned int to unsigned int [-Werror=overflow] 2023-02-03 11:18:50 -06:00
readline gdb/readline: fix extra 'quit' message problem 2022-05-07 10:49:27 +01:00
sim sim: info: convert verbose field to a bool 2023-01-18 20:47:55 -05:00
texinfo
zlib Regenerate with automake-1.15.1 2022-07-09 20:10:47 +09:30
.cvsignore
.editorconfig Add top-level .editorconfig file 2022-01-28 08:25:42 -05:00
.gitattributes binutils-gdb/git: highlight whitespace errors in source files 2022-07-25 14:35:41 +01:00
.gitignore
ar-lib
ChangeLog Add markers for 2.40 branch 2022-12-31 12:05:28 +00:00
compile
config-ml.in
config.guess Update the config.guess and config.sub files from the master repository and regenerate files. 2022-01-17 16:21:22 +00:00
config.rpath
config.sub Update the config.guess and config.sub files from the master repository and regenerate files. 2022-01-17 16:21:22 +00:00
configure configure: remove dependencies on gmp and mpfr when gdb is disabled 2023-01-06 09:32:07 +01:00
configure.ac configure: remove dependencies on gmp and mpfr when gdb is disabled 2023-01-06 09:32:07 +01:00
COPYING
COPYING.LIB
COPYING.LIBGLOSS
COPYING.NEWLIB
COPYING3
COPYING3.LIB
depcomp
djunpack.bat
install-sh
libtool.m4 libtool.m4: fix the NM="/nm/over/here -B/option/with/path" case 2022-03-25 12:02:35 +00:00
ltgcc.m4
ltmain.sh
ltoptions.m4
ltsugar.m4
ltversion.m4
lt~obsolete.m4
MAINTAINERS MAINTAINERS: Update path to readline config.{sub,guess} files 2021-05-24 18:11:49 +02:00
Makefile.def toplevel: Makefile.def: add install-strip dependency on libsframe 2023-01-18 23:17:49 -08:00
Makefile.in toplevel: Makefile.def: add install-strip dependency on libsframe 2023-01-18 23:17:49 -08:00
Makefile.tpl Pass PKG_CONFIG_PATH down from top-level Makefile 2022-04-08 10:56:41 -04:00
makefile.vms
missing
mkdep
mkinstalldirs
move-if-change
multilib.am
README
README-maintainer-mode Note that at least dejagnu version 1.5.3 is required in order to be ale to run the testsuites. 2022-10-04 10:54:19 +01:00
setup.com
src-release.sh src-release.sh: Fix gdb source tarball build failure due to libsframe 2022-11-30 07:32:58 +04:00
symlink-tree
test-driver
ylwrap

		   README for GNU development tools

This directory contains various GNU compilers, assemblers, linkers, 
debuggers, etc., plus their support routines, definitions, and documentation.

If you are receiving this as part of a GDB release, see the file gdb/README.
If with a binutils release, see binutils/README;  if with a libg++ release,
see libg++/README, etc.  That'll give you info about this
package -- supported targets, how to use it, how to report bugs, etc.

It is now possible to automatically configure and build a variety of
tools with one command.  To build all of the tools contained herein,
run the ``configure'' script here, e.g.:

	./configure 
	make

To install them (by default in /usr/local/bin, /usr/local/lib, etc),
then do:
	make install

(If the configure script can't determine your type of computer, give it
the name as an argument, for instance ``./configure sun4''.  You can
use the script ``config.sub'' to test whether a name is recognized; if
it is, config.sub translates it to a triplet specifying CPU, vendor,
and OS.)

If you have more than one compiler on your system, it is often best to
explicitly set CC in the environment before running configure, and to
also set CC when running make.  For example (assuming sh/bash/ksh):

	CC=gcc ./configure
	make

A similar example using csh:

	setenv CC gcc
	./configure
	make

Much of the code and documentation enclosed is copyright by
the Free Software Foundation, Inc.  See the file COPYING or
COPYING.LIB in the various directories, for a description of the
GNU General Public License terms under which you can copy the files.

REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info
on where and how to report problems.