Skip to content

Commit cbe85e7

Browse files
committed
pythongh-127086: Ignore memory mmap in FileIO testing
`mmap`, `munmap`, and `mprotect` are used by CPython for memory management, which may occur in the middle of the FileIO tests. The system calls can also be used with files, so `strace` includes them in its `%file` and `%desc` filters. Filter out the `mmap` system calls related to memory allocation for the file tests. Currently FileIO doesn't do `mmap` at all, so didn't add code to track from `mmap` through `munmap` since it wouldn't be used. For now if an `mmap` on a fd happens, the call will be included (which may cause test to fail), and at that time support for tracking the address throug `munmap` could be added.
1 parent 0af4ec3 commit cbe85e7

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

Lib/test/support/strace_helper.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,27 @@ def sections(self):
7171
return sections
7272

7373

74+
def filter_memory(syscalls):
75+
"""Filter out memory allocation calls from File I/O calls.
76+
77+
Some calls (mmap, munmap, etc) can be used on files or to just get a block
78+
of memory. Use this function to filter out the memory related calls from
79+
other calls."""
80+
81+
def _filter(call):
82+
# mmap can operate on a fd or `NULL` which gives a block of memory.
83+
# Ignore the `NULL` ones.
84+
if call.syscall == 'mmap' and call.args[0] == 'NULL':
85+
return False
86+
87+
if call.syscall in ('munmap', 'mprotect'):
88+
return False
89+
90+
return True
91+
92+
return [call for call in syscalls if _filter(call)]
93+
94+
7495
@support.requires_subprocess()
7596
def strace_python(code, strace_flags, check=True):
7697
"""Run strace and return the trace.
@@ -92,8 +113,6 @@ def _make_error(reason, details):
92113
"-c",
93114
textwrap.dedent(code),
94115
__run_using_command=[_strace_binary] + strace_flags,
95-
# Don't want to trace our JIT's own mmap and mprotect calls:
96-
PYTHON_JIT="0",
97116
)
98117
except OSError as err:
99118
return _make_error("Caught OSError", err)
@@ -144,9 +163,14 @@ def get_events(code, strace_flags, prelude, cleanup):
144163
return all_sections['code']
145164

146165

147-
def get_syscalls(code, strace_flags, prelude="", cleanup=""):
166+
def get_syscalls(code, strace_flags, prelude="", cleanup="",
167+
ignore_memory=True):
148168
"""Get the syscalls which a given chunk of python code generates"""
149169
events = get_events(code, strace_flags, prelude=prelude, cleanup=cleanup)
170+
171+
if ignore_memory:
172+
events = filter_memory(events)
173+
150174
return [ev.syscall for ev in events]
151175

152176

@@ -169,5 +193,5 @@ def requires_strace():
169193
return unittest.skipUnless(_can_strace(), "Requires working strace")
170194

171195

172-
__all__ = ["get_events", "get_syscalls", "requires_strace", "strace_python",
173-
"StraceEvent", "StraceResult"]
196+
__all__ = ["filter_memory", "get_events", "get_syscalls", "requires_strace",
197+
"strace_python", "StraceEvent", "StraceResult"]

Lib/test/test_fileio.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,7 @@ def testErrnoOnClosedReadinto(self, f):
364364

365365
@strace_helper.requires_strace()
366366
def test_syscalls_read(self):
367-
"""Check that the set of system calls produced by the I/O stack is what
368-
is expected for various read cases.
367+
"""Check set of system calls during common I/O patterns
369368
370369
It's expected as bits of the I/O implementation change, this will need
371370
to change. The goal is to catch changes that unintentionally add
@@ -383,6 +382,11 @@ def check_readall(name, code, prelude="", cleanup="",
383382
prelude=prelude,
384383
cleanup=cleanup)
385384

385+
# Some system calls (ex. mmap) can be used for both File I/O and
386+
# memory allocation. Filter out the ones used for memory
387+
# allocation.
388+
syscalls = strace_helper.filter_memory(syscalls)
389+
386390
# The first call should be an open that returns a
387391
# file descriptor (fd). Afer that calls may vary. Once the file
388392
# is opened, check calls refer to it by fd as the filename
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Filter out memory-related ``mmap``, ``munmap``, and ``mprotect`` calls from
2+
file-related ones when testing :mod:`io` behavior using strace.

0 commit comments

Comments
 (0)