From: Kevin Buettner <kevinb@redhat.com>
To: gdb-patches@sourceware.org
Cc: Kevin Buettner <kevinb@redhat.com>
Subject: [PATCH 2/4] dwarf2-frame.c: Fix FDE processing bug involving non-contiguous ranges
Date: Sat, 08 Jun 2019 19:55:00 -0000 [thread overview]
Message-ID: <20190608195434.26512-3-kevinb@redhat.com> (raw)
In-Reply-To: <20190608195434.26512-1-kevinb@redhat.com>
In the course of revising the test case for
gdb.dwarf2/dw2-ranges-func.exp, I added a new .c file which would
cause the "cold" range to be at a higher address than the rest of the
function. In these tests, the range in question isn't really cold in
the sense that a compiler has determined that it'll be executed less
frequently. Instead, it's simply the range that does not include the
entry pc. These tests are intended to mimic the output of such a
compiler, so I'll continue to refer to this range as "cold" in the
following discussion.
The original test case had only tested a cold range placed
at lower addresses than the rest of the function. During testing of the
new code where the cold range was placed at higher addresses, I found
that I could produce the following backtrace:
(gdb) bt
#0 0x0000000000401138 in baz ()
at dw2-ranges-func-hi-cold.c:72
#1 0x0000000000401131 in foo_cold ()
at dw2-ranges-func-hi-cold.c:64
#2 0x000000000040111e in foo ()
at dw2-ranges-func-hi-cold.c:50
#3 0x0000000000401144 in main ()
at dw2-ranges-func-hi-cold.c:78
This is correct, except that we'd like to see foo() listed instead
of foo_cold(). (I handle that problem in another patch.)
Now look at what happens for a similar backtrace where the cold range
is at a lower address than the foo's entry pc:
(gdb) bt
#0 0x000000000040110a in baz ()
at dw2-ranges-func-lo-cold.c:48
#1 0x0000000000401116 in foo ()
at dw2-ranges-func-lo-cold.c:54
#2 0x00007fffffffd4c0 in ?? ()
#3 0x0000000000401138 in foo ()
at dw2-ranges-func-lo-cold.c:70
Note that the backtrace doesn't go all the way back to main(). Moreover,
frame #2 is messed up.
I had seen this behavior when I had worked on the non-contiguous
address problem last year. At the time I convinced myself that the
mangled backtrace was "okay" since we're doing strange things with
the DWARF assembler. We're taking a function called foo_cold (though
it was originally called foo_low - my recent changes to the test case
changed the name) and via the magic of the DWARF assembler, we're
combining it into a separate (non-contiguous) range for foo. Thus,
it was a surprise to me when I got a good and complete backtrace when
the cold symbol is placed at an address that's greater than entry pc.
The function dwarf2_frame_cache (in dwarf2-frame.c) is making this
call:
if (get_frame_func_if_available (this_frame, &entry_pc)) ...
If that call succeeds (returns a true value), the FDE is then
processed up to the entry pc. It doesn't make sense to do this,
however, when the FDE in question does not contain the entry pc. This
can happen when the function in question is comprised of more than one
(non-contiguous) address range.
My fix is to add some comparisons to the test above to ensure that
ENTRY_PC is within the address range covered by the FDE.
gdb/ChangeLog:
* dwarf2-frame.c (dwarf2_frame_cache): Don't decode FDE instructions
for entry pc when entry pc is out of range for that FDE.
---
gdb/dwarf2-frame.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 0f2502b4c6..c98e2f232f 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -1023,7 +1023,13 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
/* Save the initialized register set. */
fs.initial = fs.regs;
- if (get_frame_func_if_available (this_frame, &entry_pc))
+ /* Fetching the entry pc for THIS_FRAME won't necessarily result
+ in an address that's within the range of FDE locations. This
+ is due to the possibility of the function occupying non-contiguous
+ ranges. */
+ if (get_frame_func_if_available (this_frame, &entry_pc)
+ && fde->initial_location <= entry_pc
+ && entry_pc < fde->initial_location + fde->address_range)
{
/* Decode the insns in the FDE up to the entry PC. */
instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch,
--
2.21.0
next prev parent reply other threads:[~2019-06-08 19:55 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-08 19:55 [PATCH 0/4] Non-contiguous address range bug fixes / improvements Kevin Buettner
2019-06-08 19:55 ` Kevin Buettner [this message]
2019-06-21 14:34 ` [PATCH 2/4] dwarf2-frame.c: Fix FDE processing bug involving non-contiguous ranges Pedro Alves
2019-06-08 19:55 ` [PATCH 1/4] Prefer symtab symbol over minsym for function names in non-contiguous blocks Kevin Buettner
2019-06-21 14:26 ` Pedro Alves
2019-06-26 17:30 ` Tom Tromey
2019-07-03 23:16 ` Kevin Buettner
2019-06-08 19:55 ` [PATCH 3/4] Allow display of negative offsets in print_address_symbolic() Kevin Buettner
2019-06-21 14:45 ` Pedro Alves
2019-07-03 23:09 ` Kevin Buettner
2019-07-04 1:06 ` Kevin Buettner
2019-06-08 19:55 ` [PATCH 4/4] Improve test gdb.dwarf2/dw2-ranges-func.exp Kevin Buettner
2019-06-26 17:24 ` [PATCH 0/4] Non-contiguous address range bug fixes / improvements Tom Tromey
2019-07-03 20:10 ` Kevin Buettner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190608195434.26512-3-kevinb@redhat.com \
--to=kevinb@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox