This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nuttx-ntfc.git
The following commit(s) were added to refs/heads/main by this push:
new 70cf7e9 tests: fix race in GdbController gcore tests
70cf7e9 is described below
commit 70cf7e93b88df8a94c7bbe1449820f5b4a93c133
Author: raiden00pl <[email protected]>
AuthorDate: Tue Aug 25 13:41:23 2026 +0200
tests: fix race in GdbController gcore tests
The gcore tests wrote the "Saved corefile" and GCORE_MARKER reply
lines into the pipe before calling generate_coredump(). If the
reader thread consumed those lines before generate_coredump()
reset _gcore_done and _last_corefile, the reset discarded them and
the wait timed out, returning None (seen as a flaky CI failure on
the Python 3.14 job).
Feed the reply via a proc.stdin.write side effect triggered by the
GCORE_MARKER echo command instead, so it arrives only after the
controller has issued the gcore command -- mirroring real gdb and
making the ordering deterministic.
Signed-off-by: raiden00pl <[email protected]>
Assisted-by: Claude Code
---
tests/debug/test_gdb_controller.py | 42 +++++++++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/tests/debug/test_gdb_controller.py
b/tests/debug/test_gdb_controller.py
index 48eaf2f..0218fda 100644
--- a/tests/debug/test_gdb_controller.py
+++ b/tests/debug/test_gdb_controller.py
@@ -76,6 +76,24 @@ def _pipe_process() -> Tuple[MagicMock, BinaryIO]:
return proc, w_file
+def _respond_on_gcore(
+ proc: MagicMock, w_file: BinaryIO, response: bytes
+) -> None:
+ """Feed *response* into the pipe when the gcore marker echo is sent.
+
+ Replying only after GdbController has issued the command mirrors real
+ gdb and avoids racing generate_coredump()'s state reset: lines written
+ to the pipe before the call may be consumed by the reader thread and
+ then discarded by the reset, leaving the wait to time out.
+ """
+
+ def write(data: bytes) -> None:
+ if GdbController.GCORE_MARKER.encode() in data:
+ w_file.write(response)
+
+ proc.stdin.write.side_effect = write
+
+
@pytest.fixture
def elf(tmp_path: "Path") -> "Path":
p = tmp_path / "app.elf"
@@ -468,8 +486,14 @@ class TestGdbControllerGenerateCoredump:
assert start_ok is True
- w_file.write(f"Saved corefile {corefile}\n".encode())
- w_file.write(f"{GdbController.GCORE_MARKER}\n".encode())
+ _respond_on_gcore(
+ proc,
+ w_file,
+ (
+ f"Saved corefile {corefile}\n"
+ f"{GdbController.GCORE_MARKER}\n"
+ ).encode(),
+ )
result = ctrl.generate_coredump(tmp_path, "test", timeout=5.0)
# Close write end → EOF → reader exits; join to avoid ResourceWarning
w_file.close()
@@ -489,8 +513,14 @@ class TestGdbControllerGenerateCoredump:
w_file.write(b"(gdb) \n")
ctrl.start(timeout=5.0)
- w_file.write(b"Unable to fetch a corefile\n")
- w_file.write(f"{GdbController.GCORE_MARKER}\n".encode())
+ _respond_on_gcore(
+ proc,
+ w_file,
+ (
+ "Unable to fetch a corefile\n"
+ f"{GdbController.GCORE_MARKER}\n"
+ ).encode(),
+ )
result = ctrl.generate_coredump(tmp_path, "test", timeout=5.0)
w_file.close()
ctrl.stop()
@@ -553,7 +583,9 @@ class TestGdbControllerGenerateCoredump:
ctrl = GdbController(elf, _cfg(gcore_cmd="gcore -t nuttx"))
w_file.write(b"(gdb) \n")
ctrl.start(timeout=5.0)
- w_file.write(f"{GdbController.GCORE_MARKER}\n".encode())
+ _respond_on_gcore(
+ proc, w_file, f"{GdbController.GCORE_MARKER}\n".encode()
+ )
ctrl.generate_coredump(tmp_path, "t", timeout=5.0)
w_file.close()
ctrl.stop()