gdb: support frames inlined into the outer frame
authorScott Linder <scott@scottlinder.com>
Mon, 31 Aug 2020 17:24:20 +0000 (13:24 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Mon, 31 Aug 2020 17:25:05 +0000 (13:25 -0400)
commit22b9b4b05bfad806eb3d16535dcd4dbedb028c40
tree5c066a02a1f0ad1446fc1cc96ac94d74e85d7701
parent84154d166a1a4592c70e2a8296d5df0ad7f89be9
gdb: support frames inlined into the outer frame

Remove the restriction (gdb_assert) that prevents creating frames
inlined in the outer frame.  Like for frames inlined in a standard frame
(FID_STACK_VALID), a frame inlined into the outer frame will have:

 - artificial_depth greater than 0
 - code_addr equal to the first executed instruction in the block
   corresponding to the inlined function

It will however have its stack_status set to FID_STACK_OUTER, like the
outer frame.

This is not typically seen on your everyday system (e.g. a Linux /
x86-64 process), because the outer frame would be for instance the
_start function, probably written in assembly and very unlikely to have
anything inlined in it.  However this could happen in more "bare-metal"
scenarios.  In particular, this was seen in ROCm GDB [1], where the
compiler does inline functions in the top-level kernel functions (kernel
in the sense of compute kernel, not userspace vs kernel).

I however wrote a test that replicates the issue on x86-64 and a few
other arches I had access to.  Since we need to control precisely the
emitted DWARF CFI, I didn't find another way than to write it in
assembly.  The DWARF is generated using the testsuite's DWARF assembler,
except the unwind information, which is written using CFI directives
(and therefore generated by the actual assembler).  I think the test is
adequately commented, but if anything is unclear, just ask and I'll add
more info.

[1] https://github.com/ROCm-Developer-Tools/ROCgdb/

gdb/ChangeLog:

YYYY-MM-DD  Scott Linder  <scott@scottlinder.com>
YYYY-MM-DD  Simon Marchi  <simon.marchi@efficios.com>

* inline-frame.c (inline_frame_this_id): Remove assert that prevents
inline frame ids in outer frame.

gdb/testsuite/ChangeLog:

* gdb.dwarf2/frame-inlined-in-outer-frame.exp: New file.
* gdb.dwarf2/frame-inlined-in-outer-frame.S: New file.

Change-Id: I8aa129c667dccc31590ffdf426586418493a6ebe
gdb/ChangeLog
gdb/inline-frame.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.S [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.exp [new file with mode: 0644]