From: Simon Marchi Date: Thu, 8 Jan 2026 19:51:54 +0000 (-0500) Subject: gdb/testsuite: remove guile "test byte at sp, before flush" test X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de2ac4d00b9a2fd5d69ea1bc1c926d06611a875c;p=thirdparty%2Fbinutils-gdb.git gdb/testsuite: remove guile "test byte at sp, before flush" test When I run: $ while make check TESTS="gdb.guile/scm-ports.exp" RUNTESTFLAGS="--target_board=native-extended-gdbserver"; do done I eventually get: FAIL: gdb.guile/scm-ports.exp: buffered=1: test byte at sp, before flush I don't know why I only see this (or see this more often) with the native-extended-gdbserver board, I guess because it changes the timing of things. Also, this is with a debug/ASan/UBSan build of GDB, if that matters. This is with guile 3.0. This is what the test attempts to do: 1. create a rw memory port that is supposed to be buffered 2. write the byte at $sp with a new value, expecting that byte to only be in the port's buffer 3. read the memory at $sp (using parse-and-eval, bypassing the rw memory port), expecting to see the old byte value 4. flush the memory port, expecting that to write to new byte value at $sp 5. read the memory at $sp (using parse-and-eval again), expecting to see the new value It is step 3 that fails. My hypothesis is that even if the memory port we write to is buffered, the write to the underlying memory can happen before the "before flush" test happens. The Guile Buffering doc [1] says this: If you write data to a buffered port, it probably doesn’t go out to the mutable store directly. (This “probably” introduces some indeterminism in your program: what goes to the store, and when, depends on how full the buffer is. It is something that the user needs to explicitly be aware of.) The data is written to the store later – when the buffer fills up due to another write, or when force-output is called, or when close-port is called, or when the program exits, or even when the garbage collector runs. Because of the mention of the garbage collector, I tried putting some calls to gc-disable and gc-enable around that area, but it doesn't fix it. Given that the flushing behavior of the buffered port seems non-deterministic, I think that the buffering behavior can't easily be tested. I propose to get rid of that specific aspect of the test. As suggested by Tom de Vries, replace the "test byte at sp, before flush" test with a "test byte at sp, before write" one. I think this is useful as a sanity check to help prove that the memory write did in fact change the state of the program. Change-Id: I2f0afd7b2ebb7738e675f58397677f2f9a4e06bb Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29825 Reviewed-By: Thiago Jung Bauermann --- diff --git a/gdb/testsuite/gdb.guile/scm-ports.exp b/gdb/testsuite/gdb.guile/scm-ports.exp index 3cc8cde0af1..484f7bcddd0 100644 --- a/gdb/testsuite/gdb.guile/scm-ports.exp +++ b/gdb/testsuite/gdb.guile/scm-ports.exp @@ -113,20 +113,27 @@ proc test_mem_port_rw { buffered } { "define old-value" gdb_test_no_output "guile (define new-value (logxor old-value 1))" \ "define new-value" + + # Sanity check before the write. + gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") byte-at-sp))" \ + "= #t" \ + "test byte at sp, before write" + + # Write new byte at *SP. gdb_test "guile (print (put-bytevector rw-mem-port (make-bytevector 1 new-value)))" \ "= #" + + # Force flush, necessary if the port is buffered. if {$buffered} { - # Value shouldn't be in memory yet. - gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") byte-at-sp))" \ - "= #t" \ - "test byte at sp, before flush" gdb_test_no_output "guile (force-output rw-mem-port)" \ "flush port" } + # Value should be in memory now. gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") byte-at-sp))" \ "= #f" \ - "test byte at sp, after flush" + "test byte at sp, after write" + # Restore the value for cleanliness sake, and to verify close-port # flushes the buffer. gdb_test "guile (print (seek rw-mem-port (value->integer sp-reg) SEEK_SET))" \