gdb/testsuite: do not hard-code location indices in condbreak-multi-context.exp
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Tue, 24 Nov 2020 08:56:38 +0000 (09:56 +0100)
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Tue, 24 Nov 2020 08:57:31 +0000 (09:57 +0100)
Breakpoint locations are sorted according to their addresses.  The
addresses are determined by how the compiler emits the code.
Therefore, we may have a different order of locations depending on the
compiler we use.  To make the gdb.base/condbreak-multi-context.exp
test flexible enough for different compilers' output, do not hard-code
location indices.

Tested with GCC and Clang.

gdb/testsuite/ChangeLog:
2020-11-24  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

* gdb.base/condbreak-multi-context.exp: Do not hard-code location
indices.

gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/condbreak-multi-context.exp

index fa1f0e8faaf630517b6b1a4f7f6e90c64b3a3545..5f62e45fed82ca5d75f2156f1be1f6810f906aa6 100644 (file)
@@ -1,3 +1,8 @@
+2020-11-24  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+       * gdb.base/condbreak-multi-context.exp: Do not hard-code location
+       indices.
+
 2020-11-24  Joel Brobecker  <brobecker@adacore.com>
 
        * gdb.dwarf2/dw2-fixed-point.exp: Fix the expected output of
index cef4280a81c27f24b32d353f4274cee384134aef..f89452f54c529f5ca1f46be517bff1bd2179c8e4 100644 (file)
@@ -25,28 +25,79 @@ if {[prepare_for_testing "failed to prepare" ${binfile} ${srcfile}]} {
 set warning "warning: failed to validate condition"
 set fill "\[^\r\n\]*"
 
-# Check that breakpoints are as expected.
+# Location indices are determined by their address, which depends on
+# how the compiler emits the code.  We keep a map from the location
+# index to the location context (i.e. A, Base, or C), so that we can
+# write tests without hard-coding location indices.
+set loc_name(1) ""
+set loc_name(2) ""
+set loc_name(3) ""
+# And, for convenience, a reverse map from the name to the index.
+set loc_index(A)    0
+set loc_index(Base) 0
+set loc_index(C)    0
+
+# Find breakpoint location contexts.
+
+proc find_location_contexts {} {
+    global loc_name loc_index bpnum1 fill
+    global decimal hex gdb_prompt
+
+    gdb_test_multiple "info breakpoint $bpnum1" "find_location_indices" {
+       -re "stop only if ${fill}\r\n" {
+           exp_continue
+       }
+       -re "^${bpnum1}\.($decimal) ${fill} ${hex} in (A|Base|C)::func${fill}\r\n" {
+           set index $expect_out(1,string)
+           set name $expect_out(2,string)
+           set loc_name($index) $name
+           set loc_index($name) $index
+           exp_continue
+       }
+       -re "$gdb_prompt $" {
+           verbose -log "Loc names: $loc_name(1), $loc_name(2), $loc_name(3)"
+           gdb_assert { ![string equal $loc_name(1) $loc_name(2)] }
+           gdb_assert { ![string equal $loc_name(1) $loc_name(3)] }
+           gdb_assert { ![string equal $loc_name(2) $loc_name(3)] }
+           gdb_assert { [string length $loc_name(1)] > 0 }
+           gdb_assert { [string length $loc_name(2)] > 0 }
+           gdb_assert { [string length $loc_name(3)] > 0 }
+       }
+    }
+}
 
-proc test_info_break {suffix} {
-    global bpnum1 bpnum2 fill
+# Test the breakpoint location enabled states.  STATES is a list of
+# location states.  We assume STATES to contain the state for A, Base,
+# and C, and in this order.  E.g. {N* y n} for 'N*' at A::func, 'y' at
+# B::func, and 'n' at C::func, respectively.
 
-    set bp_hit_info "${fill}(\r\n${fill}breakpoint already hit 1 time)?"
+proc check_bp_locations {bpnum states cond {msg ""}} {
+    global loc_name fill
 
-    gdb_test "info break ${bpnum1} ${bpnum2}" \
-       [multi_line \
-            "Num${fill}" \
-            "${bpnum1}${fill}breakpoint${fill}keep y${fill}MULTIPLE${fill}" \
-            "${fill}stop only if a == 10${bp_hit_info}" \
-            "${bpnum1}.1${fill}N\\*${fill}Base::func${fill}" \
-            "${bpnum1}.2${fill}y${fill}A::func${fill}" \
-            "${bpnum1}.3${fill}N\\*${fill}C::func${fill}" \
-            "${bpnum2}${fill}breakpoint${fill}keep y${fill}MULTIPLE${fill}" \
-            "${fill}stop only if c == 30${bp_hit_info}" \
-            "${bpnum2}.1${fill}N\\*${fill}Base::func${fill}" \
-            "${bpnum2}.2${fill}N\\*${fill}A::func${fill}" \
-            "${bpnum2}.3${fill}y${fill}C::func${fill}" \
-            "\\(\\*\\): Breakpoint condition is invalid at this location."] \
-       "info break $suffix"
+    # Map location names to location states.
+    set loc_states(A)    [lindex $states 0]
+    set loc_states(Base) [lindex $states 1]
+    set loc_states(C)    [lindex $states 2]
+
+    if {$cond == ""} {
+       set cond_info ""
+    } else {
+       set bp_hit_info "${fill}(\r\n${fill}breakpoint already hit 1 time)?"
+       set cond_info "\r\n${fill}stop only if ${cond}${bp_hit_info}"
+    }
+
+    set expected [multi_line \
+       "Num${fill}" \
+       "${bpnum}${fill}breakpoint${fill}keep y${fill}MULTIPLE${fill}${cond_info}" \
+       "${bpnum}.1${fill} $loc_states($loc_name(1)) ${fill}" \
+       "${bpnum}.2${fill} $loc_states($loc_name(2)) ${fill}" \
+       "${bpnum}.3${fill} $loc_states($loc_name(3)) ${fill}"]
+
+    if {[lsearch $states N*] >= 0} {
+       append expected "\r\n\\(\\*\\): Breakpoint condition is invalid at this location."
+    }
+
+    gdb_test "info break $bpnum" $expected "check bp $bpnum $msg"
 }
 
 # Scenario 1: Define breakpoints conditionally, using the "break N if
@@ -54,12 +105,15 @@ proc test_info_break {suffix} {
 # only.
 
 with_test_prefix "scenario 1" {
-    # Define the conditional breakpoints.
+    # Define the conditional breakpoints.  Two locations (Base::func
+    # and C::func) should be disabled.  We do not test location
+    # indices strictly at this moment, because we don't know them,
+    # yet.  We have strict location index tests below.
     gdb_test "break func if a == 10" \
        [multi_line \
-            "${warning} at location 1, disabling:" \
+            "${warning} at location $decimal, disabling:" \
             "  No symbol \"a\" in current context." \
-            "${warning} at location 3, disabling:" \
+            "${warning} at location $decimal, disabling:" \
             "  No symbol \"a\" in current context." \
             "Breakpoint $decimal at $fill .3 locations."] \
        "define bp with condition a == 10"
@@ -67,15 +121,20 @@ with_test_prefix "scenario 1" {
 
     gdb_test "break func if c == 30" \
        [multi_line \
-            ".*${warning} at location 1, disabling:" \
+            ".*${warning} at location $decimal, disabling:" \
             "  No symbol \"c\" in current context." \
-            ".*${warning} at location 2, disabling:" \
+            ".*${warning} at location $decimal, disabling:" \
             "  No symbol \"c\" in current context." \
             ".*Breakpoint $decimal at $fill .3 locations."] \
        "define bp with condition c == 30"
     set bpnum2 [get_integer_valueof "\$bpnum" 0 "get bpnum2"]
 
-    test_info_break 1
+    find_location_contexts
+
+    with_test_prefix "before run" {
+       check_bp_locations $bpnum1 {y N* N*} "a == 10"
+       check_bp_locations $bpnum2 {N* N* y} "c == 30"
+    }
 
     # Do not use runto_main, it deletes all breakpoints.
     gdb_run_cmd
@@ -92,14 +151,17 @@ with_test_prefix "scenario 1" {
     # No more hits!
     gdb_continue_to_end
 
-    test_info_break 2
+    with_test_prefix "after run" {
+       check_bp_locations $bpnum1 {y N* N*} "a == 10"
+       check_bp_locations $bpnum2 {N* N* y} "c == 30"
+    }
 }
 
 # Start GDB with two breakpoints and define the conditions separately.
 
 proc setup_bps {} {
-    global srcfile binfile srcfile2
-    global bpnum1 bpnum2 bp_location warning
+    global srcfile binfile srcfile2 decimal
+    global bpnum1 bpnum2 bp_location warning loc_index
 
     clean_restart ${binfile}
 
@@ -111,19 +173,21 @@ proc setup_bps {} {
     set bpnum2 [get_integer_valueof "\$bpnum" 0 "get bpnum2"]
 
     # Defining a condition on 'a' disables 2 locations.
+    set locs [lsort -integer "$loc_index(Base) $loc_index(C)"]
     gdb_test "cond $bpnum1 a == 10" \
        [multi_line \
-            "$warning at location ${bpnum1}.1, disabling:" \
+            "$warning at location ${bpnum1}.[lindex $locs 0], disabling:" \
             "  No symbol \"a\" in current context." \
-            "$warning at location ${bpnum1}.3, disabling:" \
+            "$warning at location ${bpnum1}.[lindex $locs 1], disabling:" \
             "  No symbol \"a\" in current context."]
 
     # Defining a condition on 'c' disables 2 locations.
+    set locs [lsort -integer "$loc_index(Base) $loc_index(A)"]
     gdb_test "cond $bpnum2 c == 30" \
        [multi_line \
-            "$warning at location ${bpnum2}.1, disabling:" \
+            "$warning at location ${bpnum2}.[lindex $locs 0], disabling:" \
             "  No symbol \"c\" in current context." \
-            "$warning at location ${bpnum2}.2, disabling:" \
+            "$warning at location ${bpnum2}.[lindex $locs 1], disabling:" \
             "  No symbol \"c\" in current context."]
 }
 
@@ -135,7 +199,10 @@ proc setup_bps {} {
 with_test_prefix "scenario 2" {
     setup_bps
 
-    test_info_break 1
+    with_test_prefix "before run" {
+       check_bp_locations $bpnum1 {y N* N*} "a == 10"
+       check_bp_locations $bpnum2 {N* N* y} "c == 30"
+    }
 
     # Do not use runto_main, it deletes all breakpoints.
     gdb_run_cmd
@@ -152,22 +219,10 @@ with_test_prefix "scenario 2" {
     # No more hits!
     gdb_continue_to_end
 
-    test_info_break 2
-}
-
-# Test the breakpoint location enabled states.
-
-proc check_bp_locations {bpnum states msg} {
-    global fill
-
-    set expected  ".*${bpnum}.1${fill} [lindex $states 0] ${fill}\r\n"
-    append expected "${bpnum}.2${fill} [lindex $states 1] ${fill}\r\n"
-    append expected "${bpnum}.3${fill} [lindex $states 2] ${fill}"
-    if {[lsearch $states N*] >= 0} {
-       append expected "\r\n\\(\\*\\): Breakpoint condition is invalid at this location."
+    with_test_prefix "after run" {
+       check_bp_locations $bpnum1 {y N* N*} "a == 10"
+       check_bp_locations $bpnum2 {N* N* y} "c == 30"
     }
-
-    gdb_test "info break $bpnum" $expected "check bp $bpnum $msg"
 }
 
 # Scenario 3: Apply misc. checks on the already-defined breakpoints.
@@ -175,44 +230,45 @@ proc check_bp_locations {bpnum states msg} {
 with_test_prefix "scenario 3" {
     setup_bps
 
+    set locs [lsort -integer "$loc_index(Base) $loc_index(A)"]
     gdb_test "cond $bpnum1 c == 30" \
        [multi_line \
-            "${warning} at location ${bpnum1}.1, disabling:" \
+            "${warning} at location ${bpnum1}.[lindex $locs 0], disabling:" \
             "  No symbol \"c\" in current context." \
-            "${warning} at location ${bpnum1}.2, disabling:" \
+            "${warning} at location ${bpnum1}.[lindex $locs 1], disabling:" \
             "  No symbol \"c\" in current context." \
-            "Breakpoint ${bpnum1}'s condition is now valid at location 3, enabling."] \
+            "Breakpoint ${bpnum1}'s condition is now valid at location $loc_index(C), enabling."] \
        "change the condition of bp 1"
-    check_bp_locations $bpnum1 {N* N* y} "after changing the condition"
+    check_bp_locations $bpnum1 {N* N* y} "c == 30" "after changing the condition"
 
     gdb_test "cond $bpnum1" \
        [multi_line \
-            "Breakpoint ${bpnum1}'s condition is now valid at location 1, enabling." \
-            "Breakpoint ${bpnum1}'s condition is now valid at location 2, enabling." \
+            "Breakpoint ${bpnum1}'s condition is now valid at location [lindex $locs 0], enabling." \
+            "Breakpoint ${bpnum1}'s condition is now valid at location [lindex $locs 1], enabling." \
             "Breakpoint ${bpnum1} now unconditional."] \
        "reset the condition of bp 1"
-    check_bp_locations $bpnum1 {y y y} "after resetting the condition"
+    check_bp_locations $bpnum1 {y y y} "" "after resetting the condition"
 
-    gdb_test_no_output "disable ${bpnum2}.2"
-    check_bp_locations $bpnum2 {N* N* y} "after disabling loc 2"
+    gdb_test_no_output "disable ${bpnum2}.$loc_index(A)"
+    check_bp_locations $bpnum2 {N* N* y} "c == 30" "after disabling loc for A"
 
     gdb_test "cond $bpnum2" ".*" "reset the condition of bp 2"
-    check_bp_locations $bpnum2 {y n y} "loc 2 should remain disabled"
+    check_bp_locations $bpnum2 {n y y} "" "loc for A should remain disabled"
 
-    gdb_test_no_output "disable ${bpnum2}.3"
-    check_bp_locations $bpnum2 {y n n} "after disabling loc 3"
+    gdb_test_no_output "disable ${bpnum2}.$loc_index(C)"
+    check_bp_locations $bpnum2 {n y n} "" "after disabling loc for C"
 
     gdb_test "cond $bpnum2 c == 30" \
        [multi_line \
-            "${warning} at location ${bpnum2}.1, disabling:" \
+            "${warning} at location ${bpnum2}.$loc_index(Base), disabling:" \
             "  No symbol \"c\" in current context."] \
        "re-define a condition"
-    check_bp_locations $bpnum2 {N* N* n} "loc 3 should remain disabled"
+    check_bp_locations $bpnum2 {N* N* n} "c == 30" "loc for C should remain disabled"
 
-    gdb_test "enable ${bpnum2}.1" \
-       "Breakpoint ${bpnum2}'s condition is invalid at location 1, cannot enable." \
+    gdb_test "enable ${bpnum2}.$loc_index(Base)" \
+       "Breakpoint ${bpnum2}'s condition is invalid at location $loc_index(Base), cannot enable." \
        "reject enabling a location that is disabled-by-cond"
-    check_bp_locations $bpnum2 {N* N* n} "after enable attempt"
+    check_bp_locations $bpnum2 {N* N* n} "c == 30" "after enable attempt"
 
     gdb_test "cond $bpnum2 garbage" \
        "No symbol \"garbage\" in current context." \
@@ -246,10 +302,10 @@ with_test_prefix "force" {
             "${warning} at location ${bpnum1}.3, disabling:" \
             "  No symbol \"foo\" in current context."] \
        "force the condition of bp 1"
-    check_bp_locations $bpnum1 {N* N* N*} "after forcing the condition"
+    check_bp_locations $bpnum1 {N* N* N*} "foo" "after forcing the condition"
 
     # Now with the 'break' command.
     gdb_breakpoint "func -force-condition if baz"
     set bpnum2 [get_integer_valueof "\$bpnum" 0 "get bpnum2"]
-    check_bp_locations $bpnum2 {N* N* N*} "set using the break command"
+    check_bp_locations $bpnum2 {N* N* N*} "baz" "set using the break command"
 }