This is the mail archive of the
mailing list for the GDB project.
Re: [PATCH 2/4] dwarf2-frame.c: Fix FDE processing bug involving non-contiguous ranges
On 6/8/19 8:54 PM, Kevin Buettner wrote:
> 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
> 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.