]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Fix backtrace limit stopping on inline frame
authorHannes Domani <ssbssa@yahoo.de>
Mon, 29 Jan 2024 14:31:44 +0000 (15:31 +0100)
committerHannes Domani <ssbssa@yahoo.de>
Mon, 29 Jan 2024 14:33:01 +0000 (15:33 +0100)
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>
gdb/dwarf2/frame.c
gdb/dwarf2/loc.c
gdb/testsuite/gdb.opt/inline-bt.c
gdb/testsuite/gdb.opt/inline-bt.exp

index bc86932ed13187e5a438aac02c3d0dfede5eea7a..fc6704f434ee5f805ce05927ebf6c3d4ccf7d342 100644 (file)
@@ -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: "
index 72197d8d5a589c095bd08e18c3d4592a25379ff3..0f0d14fad3ff100e9f5e5d758d4a8a71170f9b61 100644 (file)
@@ -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);
     }
 
index 8da359f4f8b2cfc513b9f4d91d7ca10b57674635..3999104dfeb2eb9be4fcf2720c26ad8d5a6563bd 100644 (file)
@@ -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 ();
index 1439e08ff006cb5ff9bf77964e411ccbff76b86c..7220ec784444196d91c5824aa0bcac59c435757c 100644 (file)
@@ -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"