Home | History | Annotate | Line # | Download | only in gdb.reverse
      1 # Copyright 2008-2024 Free Software Foundation, Inc.
      2 
      3 # This program is free software; you can redistribute it and/or modify
      4 # it under the terms of the GNU General Public License as published by
      5 # the Free Software Foundation; either version 3 of the License, or
      6 # (at your option) any later version.
      7 #
      8 # This program is distributed in the hope that it will be useful,
      9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11 # GNU General Public License for more details.
     12 #
     13 # You should have received a copy of the GNU General Public License
     14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     15 
     16 # This file is part of the GDB testsuite.  It tests reverse stepping.
     17 # Lots of code borrowed from "step-test.exp".
     18 
     19 # The reverse finish command should return from a function and stop on
     20 # the first instruction of the source line where the function call is made.
     21 # Specifically, the behavior should match doing a reverse next from the
     22 # first instruction in the function.  GDB should only take one reverse step
     23 # or next statement to reach the previous source code line.
     24 
     25 # This testcase verifies the reverse-finish command stops at the first
     26 # instruction in the source code line where the function was called.  There
     27 # are two scenarios that must be checked:
     28 #   1) gdb is at the entry point instruction for the function
     29 #   2) gdb is in the body of the function.
     30 
     31 # This test verifies the fix for gdb bugzilla:
     32 #   https://sourceware.org/bugzilla/show_bug.cgi?id=29927
     33 
     34 # PowerPC supports two entry points to a function.  The normal entry point
     35 # is called the local entry point (LEP).  The alternate entry point is called
     36 # the global entry point (GEP).  A function call via a function pointer
     37 # will entry via the GEP.  A normal function call will enter via the LEP.
     38 #
     39 # This test has been expanded to include tests to verify the reverse-finish
     40 # command works properly if the function is called via the GEP.  The original
     41 # test only verified the reverse-finish command for a normal call that used
     42 # the LEP.
     43 
     44 if ![supports_reverse] {
     45     return
     46 }
     47 
     48 standard_testfile
     49 
     50 if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
     51     return -1
     52 }
     53 
     54 runto_main
     55 
     56 if [supports_process_record] {
     57     # Activate process record/replay.
     58     gdb_test_no_output "record" "turn on process record for test1"
     59 }
     60 
     61 
     62 ### TEST 1: reverse finish from the entry point instruction (LEP) in
     63 ### function1 when called using the normal entry point (LEP).
     64 
     65 # Set breakpoint at call to function1 in main.
     66 set bp_LEP_test [gdb_get_line_number "CALL VIA LEP" $srcfile]
     67 gdb_breakpoint $srcfile:$bp_LEP_test temporary
     68 
     69 # Continue to break point at function1 call in main.
     70 gdb_continue_to_breakpoint \
     71     "stopped at function1 entry point instruction to stepi into function" \
     72     ".*$srcfile:$bp_LEP_test\r\n.*"
     73 
     74 # stepi until we see "{" indicating we entered function1
     75 repeat_cmd_until "stepi" "CALL VIA LEP" "{" "stepi into function1 call" "100"
     76 
     77 # The reverse-finish command should stop on the function call instruction
     78 # which is the last instruction in the source code line.  Another reverse-next
     79 # instruction stops at the previous source code line.
     80 gdb_test "reverse-finish" ".*function1 \\(a, b\\);   // CALL VIA LEP.*" \
     81     "reverse-finish function1 LEP call from LEP "
     82 gdb_test "reverse-next" ".*b = 5;.*" "reverse next 2, at b = 5, call from LEP"
     83 
     84 
     85 gdb_test "reverse-continue" ".*" "setup for test 2"
     86 
     87 # Turn off record to clear logs and turn on again
     88 gdb_test "record stop"  "Process record is stopped.*" \
     89     "turn off process record for test1"
     90 gdb_test_no_output "record" "turn on process record for test2"
     91 
     92 
     93 ### TEST 2: reverse finish from the body of function1.
     94 
     95 # Set breakpoint at call to function1 in main.
     96 gdb_breakpoint $srcfile:$bp_LEP_test temporary
     97 
     98 # Continue to break point at function1 call in main.
     99 gdb_continue_to_breakpoint \
    100     "at function1 entry point instruction to step to body of function" \
    101     ".*$srcfile:$bp_LEP_test\r\n.*"
    102 
    103 # do a step instruction to get to the body of the function
    104 gdb_test "step" ".*int ret = 0;.*" "step test 1"
    105 
    106 # The reverse-finish command should stop on the function call instruction
    107 # which is the last instruction in the source code line.  Another reverse-next
    108 # instruction stops at the previous source code line.
    109 gdb_test "reverse-finish" ".*function1 \\(a, b\\);   // CALL VIA LEP.*" \
    110     "reverse-finish function1 LEP call from function body"
    111 gdb_test "reverse-next" ".*b = 5;.*" \
    112     "reverse next 2 at b = 5, from function body"
    113 
    114 gdb_test "reverse-continue" ".*" "setup for test 3"
    115 
    116 # Turn off record to clear logs and turn on again
    117 gdb_test "record stop"  "Process record is stopped.*" \
    118     "turn off process record for test2"
    119 gdb_test_no_output "record" "turn on process record for test3"
    120 
    121 
    122 ### TEST 3: reverse finish from the alternate entry point instruction (GEP) in
    123 ### function1 when called using the alternate entry point (GEP).
    124 
    125 # Set breakpoint at call to funp in main.
    126 set bp_GEP_test  [gdb_get_line_number "CALL VIA GEP" $srcfile]
    127 gdb_breakpoint $srcfile:$bp_GEP_test temporary
    128 
    129 # Continue to break point at funp call in main.
    130 gdb_continue_to_breakpoint \
    131     "stopped at function1 entry point instruction to stepi into funp" \
    132     ".*$srcfile:$bp_GEP_test\r\n.*"
    133 
    134 # stepi until we see "{" indicating we entered function.
    135 repeat_cmd_until "stepi" "CALL VIA GEP" "{" "stepi into funp call"
    136 
    137 # The reverse-finish command should stop on the function call instruction
    138 # which is the last instruction in the source code line.  Another reverse-next
    139 # instruction stops at the previous source code line.
    140 gdb_test "reverse-finish" ".*funp \\(a, b\\);.*" \
    141     "function1 GEP call call from GEP"
    142 gdb_test "reverse-next" ".*b = 50;.*" "reverse next 2 at b = 50, call from GEP"
    143 
    144 gdb_test "reverse-continue" ".*" "setup for test 4"
    145 
    146 # Turn off record to clear logs and turn on again
    147 gdb_test "record stop"  "Process record is stopped.*" \
    148     "turn off process record for test3"
    149 gdb_test_no_output "record" "turn on process record for test4"
    150 
    151 ### TEST 4: reverse finish from between the GEP and LEP in
    152 ### function1 when called using the alternate entry point (GEP).
    153 
    154 # Set breakpoint at call to funp in main.
    155 set bp_GEP_test  [gdb_get_line_number "CALL VIA GEP" $srcfile]
    156 gdb_breakpoint $srcfile:$bp_GEP_test temporary
    157 
    158 # Continue to break point at funp call in main.
    159 gdb_continue_to_breakpoint \
    160     "stopped at function1 entry point instruction to stepi into funp again" \
    161     ".*$srcfile:$bp_GEP_test\r\n.*"
    162 
    163 # stepi until we see "{" indicating we entered function.
    164 repeat_cmd_until "stepi" "CALL VIA GEP" "{" "stepi into funp call again"
    165 
    166 # do one more stepi so we are between the GEP and LEP.
    167 gdb_test "stepi" "{" "stepi to between GEP and LEP"
    168 
    169 # The reverse-finish command should stop on the function call instruction
    170 # which is the last instruction in the source code line.  Another reverse-next
    171 # instruction stops at the previous source code line.
    172 gdb_test "reverse-finish" ".*funp \\(a, b\\);.*" \
    173     "function1 GEP call call from GEP again"
    174 gdb_test "reverse-next" ".*b = 50;.*" \
    175     "reverse next 2 at b = 50, call from GEP again"
    176 
    177 gdb_test "reverse-continue" ".*" "setup for test 5"
    178 
    179 # Turn off record to clear logs and turn on again
    180 gdb_test "record stop"  "Process record is stopped.*" \
    181     "turn off process record for test4"
    182 gdb_test_no_output "record" "turn on process record for test5"
    183 
    184 
    185 ### TEST 5: reverse finish from the body of function 1 when calling using the
    186 ### alternate entrypoint (GEP).
    187 gdb_breakpoint $srcfile:$bp_GEP_test temporary
    188 
    189 # Continue to break point at funp call.
    190 gdb_continue_to_breakpoint \
    191     "at function1 entry point instruction to step to body of funp call" \
    192     ".*$srcfile:$bp_GEP_test\r\n.*"
    193 
    194 # Step into body of funp, called via GEP.
    195 gdb_test "step" ".*int ret = 0;.*" "step test 2"
    196 
    197 # The reverse-finish command should stop on the function call instruction
    198 # which is the last instruction in the source code line.  Another reverse-next
    199 # instruction stops at the previous source code line.
    200 gdb_test "reverse-finish" ".*funp \\(a, b\\);.*" \
    201     "reverse-finish function1 GEP call, from function body  "
    202 gdb_test "reverse-next" ".*b = 50;.*" \
    203     "reverse next 2 at b = 50 from function body"
    204