summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Domani <ssbssa@yahoo.de>2024-01-29 15:31:44 +0100
committerHannes Domani <ssbssa@yahoo.de>2024-01-29 15:33:01 +0100
commit633680620bb85ed6f80b22371ef49610faec8d03 (patch)
treea95295f2cd52f692496343d0c1cccd506ee6b85a
parentfff48b7cb03489a8cd87990cbad18c7d6cdfe29a (diff)
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.c2
-rw-r--r--gdb/dwarf2/loc.c2
-rw-r--r--gdb/testsuite/gdb.opt/inline-bt.c8
-rw-r--r--gdb/testsuite/gdb.opt/inline-bt.exp1
4 files changed, 7 insertions, 6 deletions
diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index bc86932ed13..fc6704f434e 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 72197d8d5a5..0f0d14fad3f 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 8da359f4f8b..3999104dfeb 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 1439e08ff00..7220ec78444 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"