gdb: add prepare_reinflate/reinflate around print_frame_args in info_frame_command_core
authorSimon Marchi <simon.marchi@polymtl.ca>
Mon, 7 Nov 2022 14:55:23 +0000 (09:55 -0500)
committerSimon Marchi <simon.marchi@polymtl.ca>
Thu, 10 Nov 2022 16:33:02 +0000 (11:33 -0500)
I noticed this crash:

    $ ./gdb --data-directory=data-directory -nx -q \
          testsuite/outputs/gdb.python/pretty-print-call-by-hand/pretty-print-call-by-hand \
  -x testsuite/outputs/gdb.python/pretty-print-call-by-hand/pretty-print-call-by-hand.py \
  -ex "b g" -ex r
    (gdb) info frame
    Stack level 0, frame at 0x7fffffffdd80:
     rip = 0x555555555160 in g
        (/home/simark/src/binutils-gdb/gdb/testsuite/gdb.python/pretty-print-call-by-hand.c:41); saved rip = 0x5555555551a3
     called by frame at 0x7fffffffdda0
     source language c.
     Arglist at 0x7fffffffdd70, args: mt=mytype is 0x555555556004 "hello world",
        depth=10

    Fatal signal: Segmentation fault

This is another case of frame_info being invalidated under a function's
feet.  The stack trace when the frame_info get invalidated looks like:

    ... many frames to pretty print the arg, that eventually invalidate the frame_infos ...
    #35 0x00005568d0a8ab24 in print_frame_arg (fp_opts=..., arg=0x7ffc3216bcb0) at /home/simark/src/binutils-gdb/gdb/stack.c:489
    #36 0x00005568d0a8cc75 in print_frame_args (fp_opts=..., func=0x621000233210, frame=..., num=-1, stream=0x60b000000300)
        at /home/simark/src/binutils-gdb/gdb/stack.c:898
    #37 0x00005568d0a9536d in info_frame_command_core (fi=..., selected_frame_p=true) at /home/simark/src/binutils-gdb/gdb/stack.c:1682

print_frame_args knows that print_frame_arg can invalidate frame_info
objects, and therefore calls prepare_reinflate/reinflate.  However,
info_frame_command_core has a separate frame_info_ptr instance (it is
passed by value / copy).  So info_frame_command_core needs to know that
print_frame_args can invalidate frame_info objects, and therefore needs
to prepare_reinflate/reinflate as well.  Add those calls, and enhance
the gdb.python/pretty-print-call-by-hand.exp test to test that command.

Reviewed-By: Bruno Larsen <blarsen@redhat.com>
Change-Id: I9edaae06d62e97ffdb30938d364437737238a960

gdb/stack.c
gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp

index 653251c200b48319114a38271824f8a32cf03a0b..4e2342c2a8d907e79443425a5175b090166058b1 100644 (file)
@@ -1679,8 +1679,12 @@ info_frame_command_core (frame_info_ptr fi, bool selected_frame_p)
            else
              gdb_printf (" %d args: ", numargs);
          }
+
+       fi.prepare_reinflate ();
        print_frame_args (user_frame_print_options,
                          func, fi, numargs, gdb_stdout);
+       fi.reinflate ();
+
        gdb_puts ("\n");
       }
   }
index 0aeb2218f9114d1f7d43d1f9fa177aa86e350227..eb3fc9e35faf3c470da9e068616067c3abbdafe7 100644 (file)
@@ -98,6 +98,14 @@ with_test_prefix "frame print" {
        "backtrace test"
     }
 }
+
+# Test the "info frame" command
+with_test_prefix "info frame" {
+    if { [start_test "TAG: first frame"] == 0 } {
+       gdb_test "info frame" "mytype is $hex \"hello world\".*"
+    }
+}
+
 # Testing the down command.
 with_test_prefix "frame movement down" {
     if { [start_test "TAG: first frame"] == 0 } {