]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Adjust gdb.base/memops-watchpoint.exp for native Windows
authorPedro Alves <pedro@palves.net>
Tue, 23 Sep 2025 10:40:27 +0000 (11:40 +0100)
committerPedro Alves <pedro@palves.net>
Tue, 23 Sep 2025 11:22:12 +0000 (12:22 +0100)
On native Windows, I see:

 continue
 Continuing.

 Thread 1 hit Hardware watchpoint 2: -location a[28]

 Old value = 104 'h'
 New value = 0 '\000'
 0x00007ffe640a9953 in msvcrt!memmove () from C:\Windows\System32\msvcrt.dll
 (gdb) FAIL: gdb.base/memops-watchpoint.exp: continue until memset watchpoint hits
 ... two more of the same ...

This fails for a few reasons:

1) thread_prefix_re

  The thread_prefix_re regexp doesn't handle the case of a thread with
  no name:

      set thread_prefix_re "(?:Thread $::decimal \[^\r\n\]* hit )?"
^          ^

  Note how it expects two spaces between the thread number and the
  "hit" word.

  Fix it by dropping one of the spaces in the regexp.

2) libc vs msvcrt.dll

  This:

  -re ".*${function_re}.* \\(\\) from .*libc\[^\r\n\]+\r\n" {

  is expecting that the function exists in libc, which is not the case
  on Windows.

  Fix it by not expecting any particular library name.

3) endline consumed when it shouldn't

  All these patterns:

    -re ".*${function_re}.* \\(\\) at .*:$::decimal\r\n" {
    -re ".*${function_re}.* \\(\\) from .*libc\[^\r\n\]+\r\n" {
    -re "in \\?\\? \\(\\) from .*libc\[^\r\n\]+\r\n" {

  ... consume the \r\n, and then do exp_continue, expecting that
  eventually the:

    -re -wrap "" {

  ... pattern matches.  However, if the \r\n is already consumed, then
  -wrap doesn't work, because that expects "\r\n$gdb_prompt ".

  This wasn't noticed on Linux because there GDB prints at least one
  more line before the prompt:

    Old value = 104 'h'
    New value = 0 '\000'
    __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:171
    warning: 171    ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: No such file or directory
    (gdb) PASS: gdb.base/memops-watchpoint.exp: continue until memset watchpoint hits
    ...
    Old value = 100 'd'
    New value = 114 'r'
    __memcpy_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:272
    272     in ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
    (gdb) PASS: gdb.base/memops-watchpoint.exp: continue until memmove watchpoint hits
    ...

  Fix it by expecting but not consuming the endlines.

4) msvcrt.dll implements memset with memmove

  Note how we are expecting a memset hit, but we get a memmove:

    0x00007ffe640a9953 in msvcrt!memmove () from C:\Windows\System32\msvcrt.dll
    (gdb) FAIL: gdb.base/memops-watchpoint.exp: continue until memset watchpoint hits

  We already handle memcpy implemented with memmove and vice versa.
  Fix it by handling memset implemented with memmove in the same way.

With all these fixed, the test now passes cleanly on native Windows.
It still passes cleanly on GNU/Linux.

Change-Id: I1a8a448e3a94d1d6736aca817568b2c0408dc2dc

gdb/testsuite/gdb.base/memops-watchpoint.exp

index c23dac5c2d3ecd3347f1c5457bbbada6858e91bc..1a8d6d9ad43d03deb5b3d2e678d201fdc1e6ba4f 100644 (file)
@@ -54,7 +54,7 @@ gdb_test "watch -location c\[28\]" \
 
 proc continue_to_watchpoint {array_re source_function function_re
                             old_value_re new_value_re} {
-    set thread_prefix_re "(?:Thread $::decimal \[^\r\n\]* hit )?"
+    set thread_prefix_re "(?:Thread $::decimal \[^\r\n\]*hit )?"
 
     set saw_watch_trigger 0
     set saw_function 0
@@ -73,15 +73,15 @@ proc continue_to_watchpoint {array_re source_function function_re
            set saw_watch_trigger 1
            exp_continue
        }
-       -re ".*${function_re}.* \\(\\) at .*:$::decimal\r\n" {
+       -re "${function_re}.* \\(\\) at \[^\r\n\]+:${::decimal}(?=\r\n)" {
            set saw_function 1
            exp_continue
        }
-       -re ".*${function_re}.* \\(\\) from .*libc\[^\r\n\]+\r\n" {
+       -re "${function_re}.* \\(\\) from \[^\r\n\]+(?=\r\n)" {
            set saw_function 1
            exp_continue
        }
-       -re "in \\?\\? \\(\\) from .*libc\[^\r\n\]+\r\n" {
+       -re "in \\?\\? \\(\\) from \[^\r\n\]+(?=\r\n)" {
            set is_supported 0
            unsupported "symbol for ${source_function} not found"
            exp_continue
@@ -96,7 +96,8 @@ proc continue_to_watchpoint {array_re source_function function_re
     }
 }
 
-continue_to_watchpoint "a" "memset" "memset" "104 'h'" "0 '\\\\000'"
+# Note: Some architectures use memmove for memset.
+continue_to_watchpoint "a" "memset" "(memset|memmove)" "104 'h'" "0 '\\\\000'"
 
 # Note: Some architectures use memmove for memcpy.
 continue_to_watchpoint "b" "memcpy" "(memcpy|memmove)" "101 'e'" "114 'r'"