Revert "X86: reverse-finish fix"
authorCarl Love <cel@us.ibm.com>
Wed, 18 Jan 2023 16:13:17 +0000 (11:13 -0500)
committerCarl Love <cel@us.ibm.com>
Wed, 18 Jan 2023 16:13:17 +0000 (11:13 -0500)
This reverts commit b22548ddb30bfb167708e82d3bb932461c1b703a.

This patch is being reverted since the patch series is causing regressions.

13 files changed:
gdb/gdbthread.h
gdb/infcall.c
gdb/infcmd.c
gdb/infrun.c
gdb/testsuite/gdb.mi/mi-reverse.exp
gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp
gdb/testsuite/gdb.reverse/finish-reverse-next.c [deleted file]
gdb/testsuite/gdb.reverse/finish-reverse-next.exp [deleted file]
gdb/testsuite/gdb.reverse/singlejmp-reverse.exp
gdb/testsuite/gdb.reverse/step-indirect-call-thunk.exp
gdb/testsuite/gdb.reverse/until-precsave.exp
gdb/testsuite/gdb.reverse/until-reverse.exp
gdb/testsuite/lib/gdb.exp

index e4edff2d6218dfd0192032e8d73b83aa5312defb..11d69fceab01ff26fd27ca6362ba8680da157972 100644 (file)
@@ -150,6 +150,10 @@ struct thread_control_state
      the finished single step.  */
   int trap_expected = 0;
 
+  /* Nonzero if the thread is being proceeded for a "finish" command
+     or a similar situation when return value should be printed.  */
+  int proceed_to_finish = 0;
+
   /* Nonzero if the thread is being proceeded for an inferior function
      call.  */
   int in_infcall = 0;
index 116605c43efcbb04494a71484905d9c3cbbca845..e09904f9a35088757d3643c8a2830828994ee80a 100644 (file)
@@ -625,6 +625,9 @@ run_inferior_call (std::unique_ptr<call_thread_fsm> sm,
 
   disable_watchpoints_before_interactive_call_start ();
 
+  /* We want to print return value, please...  */
+  call_thread->control.proceed_to_finish = 1;
+
   try
     {
       /* Infcalls run synchronously, in the foreground.  */
index 5fcd2abd983b53467ee4e48a33087ac6731353bd..7d5ec77ff5713a8e2a309a5bb0552a25a6d14f05 100644 (file)
@@ -1719,10 +1719,19 @@ finish_backward (struct finish_command_fsm *sm)
 
   sal = find_pc_line (func_addr, 0);
 
-  frame_info_ptr frame = get_selected_frame (nullptr);
+  tp->control.proceed_to_finish = 1;
+  /* Special case: if we're sitting at the function entry point,
+     then all we need to do is take a reverse singlestep.  We
+     don't need to set a breakpoint, and indeed it would do us
+     no good to do so.
+
+     Note that this can only happen at frame #0, since there's
+     no way that a function up the stack can have a return address
+     that's equal to its entry point.  */
 
   if (sal.pc != pc)
     {
+      frame_info_ptr frame = get_selected_frame (nullptr);
       struct gdbarch *gdbarch = get_frame_arch (frame);
 
       /* Set a step-resume at the function's entry point.  Once that's
@@ -1732,22 +1741,16 @@ finish_backward (struct finish_command_fsm *sm)
       sr_sal.pspace = get_frame_program_space (frame);
       insert_step_resume_breakpoint_at_sal (gdbarch,
                                            sr_sal, null_frame_id);
+
+      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
   else
     {
-      /* We are exactly at the function entry point.  Note that this
-        can only happen at frame #0.
-
-        When setting a step range, need to call set_step_info
-        to setup the current_line/symtab fields as well.  */
-      set_step_info (tp, frame, find_pc_line (pc, 0));
-
-      /* Return using a step range so we will keep stepping back
-        to the first instruction in the source code line.  */
-      tp->control.step_range_start = sal.pc;
-      tp->control.step_range_end = sal.pc;
+      /* We're almost there -- we just need to back up by one more
+        single-step.  */
+      tp->control.step_range_start = tp->control.step_range_end = 1;
+      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
-  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
 }
 
 /* finish_forward -- helper function for finish_command.  FRAME is the
@@ -1773,6 +1776,9 @@ finish_forward (struct finish_command_fsm *sm, frame_info_ptr frame)
 
   set_longjmp_breakpoint (tp, frame_id);
 
+  /* We want to print return value, please...  */
+  tp->control.proceed_to_finish = 1;
+
   proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
 }
 
index 05b150b1b63c0b9824270459a0e7ad8c30f1e30f..edfb5ab0a91f47b1e4f86814f22eae1abbdc8a1a 100644 (file)
@@ -2748,6 +2748,8 @@ clear_proceed_status_thread (struct thread_info *tp)
 
   tp->control.stop_step = 0;
 
+  tp->control.proceed_to_finish = 0;
+
   tp->control.stepping_command = 0;
 
   /* Discard any remaining commands or status from previous stop.  */
@@ -6735,27 +6737,31 @@ process_event_stop_test (struct execution_control_state *ecs)
 
     case BPSTAT_WHAT_STEP_RESUME:
       infrun_debug_printf ("BPSTAT_WHAT_STEP_RESUME");
-      delete_step_resume_breakpoint (ecs->event_thread);
-      fill_in_stop_func (gdbarch, ecs);
 
-      if (execution_direction == EXEC_REVERSE)
+      delete_step_resume_breakpoint (ecs->event_thread);
+      if (ecs->event_thread->control.proceed_to_finish
+         && execution_direction == EXEC_REVERSE)
        {
          struct thread_info *tp = ecs->event_thread;
-         /* We are finishing a function in reverse or stepping over a function
-            call in reverse, and just hit the step-resume breakpoint at the
-            start address of the function, and we're almost there -- just need
-            to back up to the function call.  */
-
-         stop_pc_sal = find_pc_line (ecs->event_thread->stop_pc (), 0);
-
-         /* When setting a step range, need to call set_step_info
-            to setup the current_line/symtab fields as well.  */
-         set_step_info (tp, frame, stop_pc_sal);
 
-         /* Return using a step range so we will keep stepping back to the
-            first instruction in the source code line.  */
-         tp->control.step_range_start = ecs->stop_func_start;
-         tp->control.step_range_end = ecs->stop_func_start;
+         /* We are finishing a function in reverse, and just hit the
+            step-resume breakpoint at the start address of the
+            function, and we're almost there -- just need to back up
+            by one more single-step, which should take us back to the
+            function call.  */
+         tp->control.step_range_start = tp->control.step_range_end = 1;
+         keep_going (ecs);
+         return;
+       }
+      fill_in_stop_func (gdbarch, ecs);
+      if (ecs->event_thread->stop_pc () == ecs->stop_func_start
+         && execution_direction == EXEC_REVERSE)
+       {
+         /* We are stepping over a function call in reverse, and just
+            hit the step-resume breakpoint at the start address of
+            the function.  Go back to single-stepping, which should
+            take us back to the function call.  */
+         ecs->event_thread->stepping_over_breakpoint = 1;
          keep_going (ecs);
          return;
        }
index 619550add659af1ba7649ad3dfebd09a6bfaf4a3..020b6feb448255936d6ca6a8e37d40f40a8c016d 100644 (file)
@@ -95,10 +95,15 @@ proc test_controlled_execution_reverse {} {
        "basics.c" $line_main_callme_1 "" \
        "reverse finish from callme"
 
-    mi_execute_to "exec-next --reverse" \
+    # Test exec-reverse-next
+    #   It takes two steps to get back to the previous line,
+    #   as the first step moves us to the start of the current line,
+    #   and the one after that moves back to the previous line.
+
+    mi_execute_to "exec-next --reverse 2" \
        "end-stepping-range" "main" "" \
        "basics.c" $line_main_hello "" \
-       "reverse next to get over the call to do_nothing"
+       "reverse next to get over the call to do_nothing"
 
     # Test exec-reverse-step
 
index 0cbabd61d5251ed1ba02af501a21d39486697f2c..dd6e4d2045f300d34cfd0760baddad42bb91b7ca 100644 (file)
@@ -42,5 +42,6 @@ if [supports_process_record] {
 gdb_test "next" {f \(\);} "next to f"
 gdb_test "next" {v = 3;} "next to v = 3"
 
-# Reverse step back into f ().  Puts us at call to g () in function f ().
-gdb_test "reverse-next" {g \(\);}
+# FAIL was:
+# 29        g ();
+gdb_test "reverse-next" {f \(\);}
diff --git a/gdb/testsuite/gdb.reverse/finish-reverse-next.c b/gdb/testsuite/gdb.reverse/finish-reverse-next.c
deleted file mode 100644 (file)
index f90ecbb..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2012-2023 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* The reverse finish command should return from a function and stop on
-   the first instruction of the source line where the function call is made.
-   Specifically, the behavior should match doing a reverse next from the
-   first instruction in the function.  GDB should only require one reverse
-   step or next statement to reach the previous source code line.
-
-   This test verifies the fix for gdb bugzilla:
-
-   https://sourceware.org/bugzilla/show_bug.cgi?id=29927
-*/
-
-int
-function1 (int a, int b)   // FUNCTION1
-{
-  int ret = 0;
-
-  ret = a + b;
-  return ret;
-}
-
-int
-main(int argc, char* argv[])
-{
-  int a, b;
-
-  a = 1;
-  b = 5;
-
-  function1 (a, b);   // CALL FUNCTION
-  return 0;
-}
diff --git a/gdb/testsuite/gdb.reverse/finish-reverse-next.exp b/gdb/testsuite/gdb.reverse/finish-reverse-next.exp
deleted file mode 100644 (file)
index 63305c1..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright 2008-2023 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-# This file is part of the GDB testsuite.  It tests reverse stepping.
-# Lots of code borrowed from "step-test.exp".
-
-# The reverse finish command should return from a function and stop on
-# the first instruction of the source line where the function call is made.
-# Specifically, the behavior should match doing a reverse next from the
-# first instruction in the function.  GDB should only take one reverse step
-# or next statement to reach the previous source code line.
-
-# This testcase verifies the reverse-finish command stops at the first
-# instruction in the source code line where the function was called.  There
-# are two scenarios that must be checked:
-#   1) gdb is at the entry point instruction for the function
-#   2) gdb is in the body of the function.
-
-# This test verifies the fix for gdb bugzilla:
-#   https://sourceware.org/bugzilla/show_bug.cgi?id=29927
-
-if ![supports_reverse] {
-    return
-}
-
-standard_testfile
-
-if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
-    return -1
-}
-
-runto_main
-set target_remote [gdb_is_target_remote]
-
-if [supports_process_record] {
-    # Activate process record/replay.
-    gdb_test_no_output "record" "turn on process record for test1"
-}
-
-
-### TEST 1: reverse finish from the entry point instruction in
-### function1.
-
-# Set breakpoint at call to function1 in main.
-set bp_FUNCTION [gdb_get_line_number "CALL FUNCTION" $srcfile]
-gdb_breakpoint $srcfile:$bp_FUNCTION temporary
-
-# Continue to break point at function1 call in main.
-gdb_continue_to_breakpoint \
-    "stopped at function1 entry point instruction to stepi into function" \
-    ".*$srcfile:$bp_FUNCTION\r\n.*"
-
-# stepi until we see "{" indicating we entered function1
-repeat_cmd_until "stepi" "CALL FUNCTION" "{" "stepi into function1 call"
-
-gdb_test "reverse-finish" ".*function1 \\(a, b\\);   // CALL FUNCTION.*" \
-    "reverse-finish function1 "
-
-# Check to make sure we stopped at the first instruction in the source code
-# line.  It should only take one reverse next command to get to the previous
-# source line.   If GDB stops at the last instruction in the source code line
-# it will take two reverse next instructions to get to the previous source
-# line.
-gdb_test "reverse-next" ".*b = 5;.*" "reverse next at b = 5, call from function"
-
-# Clear the recorded log.
-gdb_test "record stop"  "Process record is stopped.*" \
-    "turn off process record for test1"
-gdb_test_no_output "record" "turn on process record for test2"
-
-
-### TEST 2: reverse finish from the body of function1.
-
-# Set breakpoint at call to function1 in main.
-gdb_breakpoint $srcfile:$bp_FUNCTION temporary
-
-# Continue to break point at function1 call in main.
-gdb_continue_to_breakpoint \
-    "at function1 entry point instruction to step to body of function" \
-    ".*$srcfile:$bp_FUNCTION\r\n.*"
-
-# do a step instruction to get to the body of the function
-gdb_test "step" ".*int ret = 0;.*" "step test 1"
-
-gdb_test "reverse-finish" ".*function1 \\(a, b\\);   // CALL FUNCTION.*" \
-    "reverse-finish function1 call from function body"
-
-# Check to make sure we stopped at the first instruction in the source code
-# line.  It should only take one reverse next command to get to the previous
-# source line.
-gdb_test "reverse-next" ".*b = 5;.*" \
-    "reverse next at b = 5, from function body"
index 3678f2cea81c733fc1bc7e5a0227f211cf2f0f71..bc7e6876bd21b1a3582a8e3af6d1c0f6cbe0c883 100644 (file)
@@ -54,4 +54,7 @@ gdb_test "next" {v = 3;} "next to v = 3"
 # {
 gdb_test "reverse-step" {nodebug \(\);}
 
-gdb_test "reverse-next" {g \(\);}
+# FAIL was:
+# No more reverse-execution history.
+# {
+gdb_test "reverse-next" {f \(\);}
index 4a0e0c245cc7927c9f018675cba0b3f4381b25fc..94292d5eb9bdc80118d505349370f33b53bdc790 100644 (file)
@@ -36,6 +36,39 @@ if { ![runto_main] } {
     return -1
 }
 
+# Do repeated stepping COMMANDs in order to reach TARGET from CURRENT
+#
+#  COMMAND is a stepping command
+#  CURRENT is a string matching the current location
+#  TARGET  is a string matching the target location
+#  TEST    is the test name
+#
+# The function issues repeated COMMANDs as long as the location matches
+# CURRENT up to a maximum of 100 steps.
+#
+# TEST passes if the resulting location matches TARGET and fails
+# otherwise.
+#
+proc step_until { command current target test } {
+    global gdb_prompt
+
+    set count 0
+    gdb_test_multiple "$command" "$test" {
+        -re "$current.*$gdb_prompt $" {
+            incr count
+            if { $count < 100 } {
+                send_gdb "$command\n"
+                exp_continue
+            } else {
+                fail "$test"
+            }
+        }
+        -re "$target.*$gdb_prompt $" {
+            pass "$test"
+        }
+    }
+}
+
 gdb_test_no_output "record"
 gdb_test "next" ".*" "record trace"
 
@@ -55,20 +88,20 @@ gdb_test "reverse-next" "apply\.2.*" \
     "reverse-step through thunks and over inc"
 
 # We can use instruction stepping to step into thunks.
-repeat_cmd_until "stepi" "apply\.2" "indirect_thunk" "stepi into call thunk"
-repeat_cmd_until "stepi" "indirect_thunk" "inc" \
+step_until "stepi" "apply\.2" "indirect_thunk" "stepi into call thunk"
+step_until "stepi" "indirect_thunk" "inc" \
     "stepi out of call thunk into inc"
 set alphanum_re "\[a-zA-Z0-9\]"
 set pic_thunk_re  "__$alphanum_re*\\.get_pc_thunk\\.$alphanum_re* \\(\\)"
-repeat_cmd_until "stepi" "(inc|$pic_thunk_re)" "return_thunk" "stepi into return thunk"
-repeat_cmd_until "stepi" "return_thunk" "apply" \
+step_until "stepi" "(inc|$pic_thunk_re)" "return_thunk" "stepi into return thunk"
+step_until "stepi" "return_thunk" "apply" \
     "stepi out of return thunk back into apply"
 
-repeat_cmd_until "reverse-stepi" "apply" "return_thunk" \
+step_until "reverse-stepi" "apply" "return_thunk" \
     "reverse-stepi into return thunk"
-repeat_cmd_until "reverse-stepi" "return_thunk" "inc" \
+step_until "reverse-stepi" "return_thunk" "inc" \
     "reverse-stepi out of return thunk into inc"
-repeat_cmd_until "reverse-stepi" "(inc|$pic_thunk_re)" "indirect_thunk" \
+step_until "reverse-stepi" "(inc|$pic_thunk_re)" "indirect_thunk" \
     "reverse-stepi into call thunk"
-repeat_cmd_until "reverse-stepi" "indirect_thunk" "apply" \
+step_until "reverse-stepi" "indirect_thunk" "apply" \
     "reverse-stepi out of call thunk into apply"
index 5090510fe59bbbeb180d0f21cc5c761f855427b1..b5b2ba764d399a144cae71d33459b5cf9df7f3eb 100644 (file)
@@ -138,7 +138,7 @@ gdb_test "advance marker2" \
 # Finish out to main scope (backward)
 
 gdb_test "finish" \
-    "main .*$srcfile:$bp_location20.*" \
+    " in main .*$srcfile:$bp_location20.*" \
     "reverse-finish from marker2"
 
 # Advance backward to last line of factorial (outer invocation)
index 325694603c30376bb5ffb0e575c4ac9b016a3647..c9d0c7ec7adf91f93b7246e67de85140e4983d3e 100644 (file)
@@ -111,7 +111,7 @@ gdb_test "advance marker2" \
 # Finish out to main scope (backward)
 
 gdb_test "finish" \
-    "main .*$srcfile:$bp_location20.*" \
+    " in main .*$srcfile:$bp_location20.*" \
     "reverse-finish from marker2"
 
 # Advance backward to last line of factorial (outer invocation)
index a677f84dd38d8171978f75b1f4292e505e83c450..68337bd235cf1f520d7843d2ac14ca91baccfb3f 100644 (file)
@@ -9261,39 +9261,6 @@ proc gdb_step_until { regexp {test_name ""} {max_steps 10} } {
     }
 }
 
-# Do repeated stepping COMMANDs in order to reach TARGET from CURRENT
-#
-#  COMMAND is a stepping command
-#  CURRENT is a string matching the current location
-#  TARGET  is a string matching the target location
-#  TEST    is the test name
-#
-# The function issues repeated COMMANDs as long as the location matches
-# CURRENT up to a maximum of 100 steps.
-#
-# TEST passes if the resulting location matches TARGET and fails
-# otherwise.
-
-proc repeat_cmd_until { command current target test } {
-    global gdb_prompt
-
-    set count 0
-    gdb_test_multiple "$command" "$test" {
-       -re "$current.*$gdb_prompt $" {
-           incr count
-           if { $count < 100 } {
-               send_gdb "$command\n"
-               exp_continue
-           } else {
-               fail "$test"
-           }
-       }
-       -re "$target.*$gdb_prompt $" {
-           pass "$test"
-       }
-    }
-}
-
 # Check if the compiler emits epilogue information associated
 # with the closing brace or with the last statement line.
 #