return sections
+def _filter_memory_call(call):
+ # mmap can operate on a fd or "MAP_ANONYMOUS" which gives a block of memory.
+ # Ignore "MAP_ANONYMOUS + the "MAP_ANON" alias.
+ if call.syscall == "mmap" and "MAP_ANON" in call.args[3]:
+ return True
+
+ if call.syscall in ("munmap", "mprotect"):
+ return True
+
+ return False
+
+
+def filter_memory(syscalls):
+ """Filter out memory allocation calls from File I/O calls.
+
+ Some calls (mmap, munmap, etc) can be used on files or to just get a block
+ of memory. Use this function to filter out the memory related calls from
+ other calls."""
+
+ return [call for call in syscalls if not _filter_memory_call(call)]
+
@support.requires_subprocess()
def strace_python(code, strace_flags, check=True):
"-c",
textwrap.dedent(code),
__run_using_command=[_strace_binary] + strace_flags,
- # Don't want to trace our JIT's own mmap and mprotect calls:
- PYTHON_JIT="0",
)
except OSError as err:
return _make_error("Caught OSError", err)
return all_sections['code']
-def get_syscalls(code, strace_flags, prelude="", cleanup=""):
+def get_syscalls(code, strace_flags, prelude="", cleanup="",
+ ignore_memory=True):
"""Get the syscalls which a given chunk of python code generates"""
events = get_events(code, strace_flags, prelude=prelude, cleanup=cleanup)
+
+ if ignore_memory:
+ events = filter_memory(events)
+
return [ev.syscall for ev in events]
return unittest.skipUnless(_can_strace(), "Requires working strace")
-__all__ = ["get_events", "get_syscalls", "requires_strace", "strace_python",
- "StraceEvent", "StraceResult"]
+__all__ = ["filter_memory", "get_events", "get_syscalls", "requires_strace",
+ "strace_python", "StraceEvent", "StraceResult"]
@strace_helper.requires_strace()
def test_syscalls_read(self):
- """Check that the set of system calls produced by the I/O stack is what
- is expected for various read cases.
+ """Check set of system calls during common I/O patterns
It's expected as bits of the I/O implementation change, this will need
to change. The goal is to catch changes that unintentionally add
prelude=prelude,
cleanup=cleanup)
+ # Some system calls (ex. mmap) can be used for both File I/O and
+ # memory allocation. Filter out the ones used for memory
+ # allocation.
+ syscalls = strace_helper.filter_memory(syscalls)
+
# The first call should be an open that returns a
# file descriptor (fd). Afer that calls may vary. Once the file
# is opened, check calls refer to it by fd as the filename