Running gdb.cp/cpexprs.exp on x86-64 GNU/Linux, I see:
break base::~base
Breakpoint 117 at 0x555555555d90: file .../src/gdb/testsuite/gdb.cp/cpexprs.cc, line 135.
(gdb) continue
Continuing.
Breakpoint 117, base::~base (this=0x7fffffffd0f8, __in_chrg=<optimized out>) at .../src/gdb/testsuite/gdb.cp/cpexprs.cc:135
135 ~base (void) { } // base::~base
(gdb) PASS: gdb.cp/cpexprs.exp: continue to base::~base
Here, the breakpoint only got one location because both the in-charge
and the not-in-charge dtors are identical and got the same address:
$ nm -A ./testsuite/outputs/gdb.cp/cpexprs/cpexprs| c++filt |grep "~base"
./testsuite/outputs/gdb.cp/cpexprs/cpexprs:
0000000000001d84 W base::~base()
./testsuite/outputs/gdb.cp/cpexprs/cpexprs:
0000000000001d84 W base::~base()
While on Cygwin, we get two locations for the same breakpoint, which
the testcase isn't expecting:
break base::~base
Breakpoint 117 at 0x100402678: base::~base. (2 locations)
(gdb) continue
Continuing.
Thread 1 "cpexprs" hit Breakpoint 117.1, base::~base (this=0x7ffffcaf8, __in_chrg=<optimized out>) at .../src/gdb/testsuite/gdb.cp/cpexprs.cc:135
135 ~base (void) { } // base::~base
(gdb) FAIL: gdb.cp/cpexprs.exp: continue to base::~base
We got two locations because the in-charge and the not-in-charge dtors
have different addresses:
$ nm -A outputs/gdb.cp/cpexprs/cpexprs.exe | c++filt | grep "~base"
outputs/gdb.cp/cpexprs/cpexprs.exe:
0000000100402680 T base::~base()
outputs/gdb.cp/cpexprs/cpexprs.exe:
0000000100402690 T base::~base()
On Cygwin, we also see the typical failure due to not expecting the
inferior to be multi-threaded:
(gdb) continue
Continuing.
[New Thread 628.0xe08]
Thread 1 "cpexprs" hit Breakpoint 200, test_function (argc=1, argv=0x7ffffcc20) at .../src/gdb/testsuite/gdb.cp/cpexprs.cc:336
336 derived d;
(gdb) FAIL: gdb.cp/cpexprs.exp: continue to test_function for policyd3::~policyd
Both issues are fixed by this patch, and now the testcase passes
cleanly on Cygwin, for me.
Reviewed-By: Keith Seitz <keiths@redhat.com>
Change-Id: If7eb95d595f083f36dfebf9045c0fc40ef5c5df1
delete_breakpoints
if { ! [gdb_breakpoint test_function] } {
fail "set test_function breakpoint for $func"
- } elseif { [gdb_test "continue" \
- "Continuing.\r\n\r\nBreakpoint $DEC+,.*test_function.*" \
- "continue to test_function for $func"] != 0 } {
- } else {
- gdb_breakpoint "$func"
- set i [expr {[string last : $func] + 1}]
- set efunc [string_to_regexp [string range $func $i end]]
- gdb_test "continue" \
- "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \
- "continue to $func"
+ return
+ }
+
+ # Accept any input between "Continuing" and the breakpoint hit, as
+ # on Cygwin, we may see a "New Thread" notification. This is the
+ # Cygwin runtime spawning its own internal threads.
+ if { [gdb_test "continue" \
+ "Continuing.\r\n.*Breakpoint $DEC+,.*test_function.*" \
+ "continue to test_function for $func"] != 0 } {
+ return
}
+
+ # On some systems, the in-charge and not-in-charge dtors of a
+ # class may end up with the same address, so setting a breakpoint
+ # at a dtor like base::~base only finds one location. On other
+ # systems (e.g. Cygwin), the two dtors for the same class may have
+ # different addresses, so we find two locations for the
+ # breakpoint. Thus, expect that the breakpoint hit may or may not
+ # report a location number.
+ set bp_re "$DEC+(\.$DEC+)?"
+
+ gdb_breakpoint "$func"
+ set i [expr {[string last : $func] + 1}]
+ set efunc [string_to_regexp [string range $func $i end]]
+ gdb_test "continue" \
+ "Continuing.\r\n.*Breakpoint $bp_re,.*$efunc.*" \
+ "continue to $func"
}
# Add a function to the list of tested functions