diff options
author | Carl Love <cel@us.ibm.com> | 2023-01-18 11:13:17 -0500 |
---|---|---|
committer | Carl Love <cel@us.ibm.com> | 2023-01-18 11:13:17 -0500 |
commit | b986eec55f460a9c77a0c06ec30d7280293f7a8c (patch) | |
tree | 0d78a889928fc6a76904b3689d36f134fe4d17b7 /gdb | |
parent | 15d2b36c5b60795067cec773a66d2627d2bf9266 (diff) | |
download | gdb-b986eec55f460a9c77a0c06ec30d7280293f7a8c.zip gdb-b986eec55f460a9c77a0c06ec30d7280293f7a8c.tar.gz gdb-b986eec55f460a9c77a0c06ec30d7280293f7a8c.tar.bz2 |
Revert "X86: reverse-finish fix"
This reverts commit b22548ddb30bfb167708e82d3bb932461c1b703a.
This patch is being reverted since the patch series is causing regressions.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/gdbthread.h | 4 | ||||
-rw-r--r-- | gdb/infcall.c | 3 | ||||
-rw-r--r-- | gdb/infcmd.c | 32 | ||||
-rw-r--r-- | gdb/infrun.c | 40 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-reverse.exp | 9 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/finish-reverse-next.c | 48 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/finish-reverse-next.exp | 104 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/singlejmp-reverse.exp | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/step-indirect-call-thunk.exp | 49 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/until-precsave.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/until-reverse.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 33 |
13 files changed, 106 insertions, 230 deletions
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index e4edff2..11d69fc 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -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; diff --git a/gdb/infcall.c b/gdb/infcall.c index 116605c..e09904f 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -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. */ diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 5fcd2ab..7d5ec77 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -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); } diff --git a/gdb/infrun.c b/gdb/infrun.c index 05b150b..edfb5ab 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -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; } diff --git a/gdb/testsuite/gdb.mi/mi-reverse.exp b/gdb/testsuite/gdb.mi/mi-reverse.exp index 619550a..020b6fe 100644 --- a/gdb/testsuite/gdb.mi/mi-reverse.exp +++ b/gdb/testsuite/gdb.mi/mi-reverse.exp @@ -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 diff --git a/gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp b/gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp index 0cbabd6..dd6e4d2 100644 --- a/gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp +++ b/gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp @@ -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 index f90ecbb..0000000 --- a/gdb/testsuite/gdb.reverse/finish-reverse-next.c +++ /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 index 63305c1..0000000 --- a/gdb/testsuite/gdb.reverse/finish-reverse-next.exp +++ /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" diff --git a/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp b/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp index 3678f2c..bc7e687 100644 --- a/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp +++ b/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp @@ -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 \(\);} diff --git a/gdb/testsuite/gdb.reverse/step-indirect-call-thunk.exp b/gdb/testsuite/gdb.reverse/step-indirect-call-thunk.exp index 4a0e0c2..94292d5 100644 --- a/gdb/testsuite/gdb.reverse/step-indirect-call-thunk.exp +++ b/gdb/testsuite/gdb.reverse/step-indirect-call-thunk.exp @@ -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" diff --git a/gdb/testsuite/gdb.reverse/until-precsave.exp b/gdb/testsuite/gdb.reverse/until-precsave.exp index 5090510..b5b2ba7 100644 --- a/gdb/testsuite/gdb.reverse/until-precsave.exp +++ b/gdb/testsuite/gdb.reverse/until-precsave.exp @@ -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) diff --git a/gdb/testsuite/gdb.reverse/until-reverse.exp b/gdb/testsuite/gdb.reverse/until-reverse.exp index 3256946..c9d0c7e 100644 --- a/gdb/testsuite/gdb.reverse/until-reverse.exp +++ b/gdb/testsuite/gdb.reverse/until-reverse.exp @@ -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) diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index a677f84..68337bd 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -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. # |