]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Adjust gdb.cp/cpexprs.exp for Cygwin
authorPedro Alves <pedro@palves.net>
Mon, 9 Jun 2025 14:41:28 +0000 (15:41 +0100)
committerPedro Alves <pedro@palves.net>
Mon, 9 Jun 2025 16:54:43 +0000 (17:54 +0100)
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

gdb/testsuite/gdb.cp/cpexprs.exp.tcl

index 1ac35af5301687f1686dbc01089565af17d1745a..5c3dfd638569f30b3db8c1665154637ff6d99c3b 100644 (file)
@@ -28,17 +28,33 @@ proc test_breakpoint {func} {
     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