diff options
author | Craig Blackmore <craig.blackmore@embecosm.com> | 2025-02-13 15:53:34 +0000 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2025-03-27 18:40:36 +0000 |
commit | fbd747b6a406beff96cc1d3767165aa3f5514a60 (patch) | |
tree | ca7fdd1b9dd38548a5ee76433182bc6dd1eae652 /gdb/utils.c | |
parent | a7a38dba7f4fbd9e9c8dd4e739d42ef8a36fb49a (diff) | |
download | gdb-fbd747b6a406beff96cc1d3767165aa3f5514a60.zip gdb-fbd747b6a406beff96cc1d3767165aa3f5514a60.tar.gz gdb-fbd747b6a406beff96cc1d3767165aa3f5514a60.tar.bz2 |
gdb: Fix assertion failure when inline frame #0 is duplicated
Modifying inline-frame-cycle-unwind.exp to use `bt -no-filters` produces
the following incorrect backtrace:
#0 inline_func () at .../gdb/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.c:49
#1 normal_func () at .../gdb/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.c:32
#2 0x000055555555517f in inline_func () at .../gdb/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.c:50
#3 normal_func () at .../gdb/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.c:32
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 1: backtrace when the unwind is broken at frame 1
The expected output, which we get with `bt`, is:
#0 inline_func () at .../gdb/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.c:49
#1 normal_func () at .../gdb/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.c:32
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) PASS: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 1: backtrace when the unwind is broken at frame 1
The cycle checking in `get_prev_frame_maybe_check_cycle` relies on newer
frame ids having already been computed and stashed. Unlike other
frames, frame #0's id does not get computed immediately.
The test passes with `bt` because when applying python frame filters,
the call to `bootstrap_python_frame_filters` happens to compute the id
of frame #0. When `get_prev_frame_maybe_check_cycle` later tries to
stash frame #2's id, the cycle is detected.
The test fails with `bt -no-filters` because frame #0's id has not been
stashed by the time `get_prev_frame_maybe_check_cycle` tries to stash
frame #2's id which succeeds and the cycle is only detected later when
trying to stash frame #4's id. Doing `stepi` after the incorrect
backtrace would then trigger an assertion failure when trying to stash
frame #0's id because it is a duplicate of #2's already stashed id.
In `get_prev_frame_always_1`, if this_frame is inline frame 0, then
compute and stash its frame id before returning the previous frame.
This ensures that the id of inline frame 0 has been stashed before
`get_prev_frame_maybe_check_cycle` is called on older frames.
The test case has been updated to run both `bt` and `bt -no-filters`.
Co-authored-by: Andrew Burgess <aburgess@redhat.com>
Diffstat (limited to 'gdb/utils.c')
0 files changed, 0 insertions, 0 deletions