diff options
author | Hannes Domani <ssbssa@yahoo.de> | 2024-01-29 15:31:44 +0100 |
---|---|---|
committer | Hannes Domani <ssbssa@yahoo.de> | 2024-01-29 15:33:01 +0100 |
commit | 633680620bb85ed6f80b22371ef49610faec8d03 (patch) | |
tree | a95295f2cd52f692496343d0c1cccd506ee6b85a | |
parent | fff48b7cb03489a8cd87990cbad18c7d6cdfe29a (diff) | |
download | gdb-633680620bb85ed6f80b22371ef49610faec8d03.zip gdb-633680620bb85ed6f80b22371ef49610faec8d03.tar.gz gdb-633680620bb85ed6f80b22371ef49610faec8d03.tar.bz2 |
Fix backtrace limit stopping on inline frame
If you have set up a backtrace limit, and the backtrace stops
because of this in an inline frame with arguments, you get an
assertion failure:
```
(gdb) bt
(gdb) set backtrace limit 2
(gdb) bt
C:/src/repos/binutils-gdb.git/gdb/frame.c:3346: internal-error: reinflate: Assertion `m_cached_level >= -1' failed.
```
And if this one is fixed, there is another one as well:
```
(gdb) bt
C:/src/repos/binutils-gdb.git/gdb/dwarf2/loc.c:1160: internal-error: dwarf_expr_reg_to_entry_parameter: Assertion `frame != NULL' failed.
```
The reason for both of them is this kind of loop:
```
while (get_frame_type (frame) == INLINE_FRAME)
frame = get_prev_frame (frame);
```
Since get_prev_frame respects the backtrace limit, it will return
NULL, and from there on you can't continue.
This changes these loops to use get_prev_frame_always instead, so
you always get a non-inline frame in the end.
With this backtrace works:
```
(gdb) bt
(gdb)
```
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29865
Approved-By: Andrew Burgess <aburgess@redhat.com>
-rw-r--r-- | gdb/dwarf2/frame.c | 2 | ||||
-rw-r--r-- | gdb/dwarf2/loc.c | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.opt/inline-bt.c | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.opt/inline-bt.exp | 1 |
4 files changed, 7 insertions, 6 deletions
diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c index bc86932..fc6704f 100644 --- a/gdb/dwarf2/frame.c +++ b/gdb/dwarf2/frame.c @@ -1423,7 +1423,7 @@ dwarf2_frame_cfa (frame_info_ptr this_frame) _("cfa not available for record btrace target")); while (get_frame_type (this_frame) == INLINE_FRAME) - this_frame = get_prev_frame (this_frame); + this_frame = get_prev_frame_always (this_frame); if (get_frame_unwind_stop_reason (this_frame) == UNWIND_UNAVAILABLE) throw_error (NOT_AVAILABLE_ERROR, _("can't compute CFA for this frame: " diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index 72197d8..0f0d14f 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -1155,7 +1155,7 @@ dwarf_expr_reg_to_entry_parameter (frame_info_ptr frame, while (get_frame_type (frame) == INLINE_FRAME) { - frame = get_prev_frame (frame); + frame = get_prev_frame_always (frame); gdb_assert (frame != NULL); } diff --git a/gdb/testsuite/gdb.opt/inline-bt.c b/gdb/testsuite/gdb.opt/inline-bt.c index 8da359f..3999104 100644 --- a/gdb/testsuite/gdb.opt/inline-bt.c +++ b/gdb/testsuite/gdb.opt/inline-bt.c @@ -28,15 +28,15 @@ volatile int result; void bar(void); -inline ATTR int func1(void) +inline ATTR int func1(int s) { bar (); - return x * y; + return x * y + s; } inline ATTR int func2(void) { - return x * func1 (); + return x * func1 (1); } int main (void) @@ -47,7 +47,7 @@ int main (void) y = 8; bar (); - val = func1 (); + val = func1 (2); result = val; val = func2 (); diff --git a/gdb/testsuite/gdb.opt/inline-bt.exp b/gdb/testsuite/gdb.opt/inline-bt.exp index 1439e08..7220ec7 100644 --- a/gdb/testsuite/gdb.opt/inline-bt.exp +++ b/gdb/testsuite/gdb.opt/inline-bt.exp @@ -65,3 +65,4 @@ gdb_test "up" "#1 .*func1.*" "up from bar (4)" gdb_test "info frame" ".*in func1.*" "info frame still works" # Verify the user visible limit works as expected. gdb_test "up" "Initial frame selected; you cannot go up." "up hits limit" +gdb_test "backtrace" "#0 bar.*#1 .*func1.*" "backtrace hits limit" |