Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
gh-142419: Add mmap.set_name method for user custom annotation#142480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
f19909ec65e691d354eba91d4aea59198516c13efc5586acd73ac4b9a931201831bd7ec7185f03a2654dcc3cf8abd02cc5fa52b0e73bf76294d0268a9df12f2d6d632ca4bcec987cf092a5d9a49adcf8e522ef4913138d92ece41bcf963610b7eac3c78537bFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -6,6 +6,7 @@ | ||
| from test.support.import_helper import import_module | ||
| from test.support.os_helper import TESTFN, unlink | ||
| from test.support.script_helper import assert_python_ok | ||
| import errno | ||
| import unittest | ||
| import os | ||
| import re | ||
| @@ -1165,6 +1166,46 @@ def test_flush_parameters(self): | ||
| m.flush(PAGESIZE) | ||
| m.flush(PAGESIZE, PAGESIZE) | ||
| @unittest.skipUnless(sys.platform == 'linux', 'Linux only') | ||
| @support.requires_linux_version(5, 17, 0) | ||
| def test_set_name(self): | ||
| # Test setting name on anonymous mmap | ||
| m = mmap.mmap(-1, PAGESIZE) | ||
| self.addCleanup(m.close) | ||
| try: | ||
| result = m.set_name('test_mapping') | ||
| except OSError as exc: | ||
| if exc.errno == errno.EINVAL: | ||
| # gh-142419: On Fedora, prctl(PR_SET_VMA_ANON_NAME) fails with | ||
| # EINVAL because the kernel option CONFIG_ANON_VMA_NAME is | ||
| # disabled. | ||
| # See: https://bugzilla.redhat.com/show_bug.cgi?id=2302746 | ||
| self.skipTest("prctl() failed with EINVAL") | ||
| else: | ||
| raise | ||
| self.assertIsNone(result) | ||
corona10 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| # Test name length limit (80 chars including prefix "cpython:mmap:" and '\0') | ||
| # Prefix is 13 chars, so max name is 66 chars | ||
| long_name = 'x' * 66 | ||
| result = m.set_name(long_name) | ||
| self.assertIsNone(result) | ||
| # Test name too long | ||
picnixz marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| too_long_name = 'x' * 67 | ||
| with self.assertRaises(ValueError): | ||
| m.set_name(too_long_name) | ||
| # Test that file-backed mmap raises error | ||
| with open(TESTFN, 'wb+') as f: | ||
| f.write(b'x' * PAGESIZE) | ||
| f.flush() | ||
| m2 = mmap.mmap(f.fileno(), PAGESIZE) | ||
| self.addCleanup(m2.close) | ||
| with self.assertRaises(ValueError): | ||
| m2.set_name('should_fail') | ||
| class LargeMmapTests(unittest.TestCase): | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| :meth:`mmap.mmap.set_name` method added to annotate an anonymous memory map | ||
| if Linux kernel supports ``PR_SET_VMA_ANON_NAME`` (Linux 5.17 or newer). | ||
| Patch by Donghee Na. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1117,6 +1117,47 @@ mmap_mmap_seek_impl(mmap_object *self, Py_ssize_t dist, int how) | ||
| return NULL; | ||
| } | ||
| /*[clinic input] | ||
| mmap.mmap.set_name | ||
| name: str | ||
| / | ||
| [clinic start generated code]*/ | ||
| static PyObject * | ||
| mmap_mmap_set_name_impl(mmap_object *self, const char *name) | ||
| /*[clinic end generated code: output=1edaf4fd51277760 input=6c7dd91cad205f07]*/ | ||
| { | ||
| #if defined(MAP_ANONYMOUS) && defined(__linux__) | ||
| const char *prefix = "cpython:mmap:"; | ||
corona10 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if (strlen(name) + strlen(prefix) > 79) { | ||
| PyErr_SetString(PyExc_ValueError, "name is too long"); | ||
| return NULL; | ||
| } | ||
| if (self->flags & MAP_ANONYMOUS) { | ||
| char buf[80]; | ||
| sprintf(buf, "%s%s", prefix, name); | ||
| if (_PyAnnotateMemoryMap(self->data, self->size, buf) < 0) { | ||
| PyErr_SetFromErrno(PyExc_OSError); | ||
| return NULL; | ||
| } | ||
| Py_RETURN_NONE; | ||
| } | ||
| else { | ||
| /* cannot name non-anonymous mappings */ | ||
| PyErr_SetString(PyExc_ValueError, | ||
| "Cannot set annotation on non-anonymous mappings"); | ||
| return NULL; | ||
| } | ||
| #else | ||
| /* naming not supported on this platform */ | ||
| PyErr_SetString(PyExc_NotImplementedError, | ||
| "Annotation of mmap is not supported on this platform"); | ||
| return NULL; | ||
| #endif | ||
| } | ||
| /*[clinic input] | ||
| mmap.mmap.seekable | ||
| @@ -1397,6 +1438,7 @@ static struct PyMethodDef mmap_object_methods[] = { | ||
| MMAP_MMAP_RESIZE_METHODDEF | ||
| MMAP_MMAP_SEEK_METHODDEF | ||
| MMAP_MMAP_SEEKABLE_METHODDEF | ||
| MMAP_MMAP_SET_NAME_METHODDEF | ||
| MMAP_MMAP_SIZE_METHODDEF | ||
| MMAP_MMAP_TELL_METHODDEF | ||
| MMAP_MMAP_WRITE_METHODDEF | ||
| @@ -1952,7 +1994,11 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) | ||
| PyErr_SetFromErrno(PyExc_OSError); | ||
| return NULL; | ||
| } | ||
| _PyAnnotateMemoryMap(m_obj->data, map_size, "cpython:mmap"); | ||
| #ifdef MAP_ANONYMOUS | ||
| if (m_obj->flags & MAP_ANONYMOUS) { | ||
| (void)_PyAnnotateMemoryMap(m_obj->data, map_size, "cpython:mmap"); | ||
| } | ||
| #endif | ||
| m_obj->access = (access_mode)access; | ||
| return (PyObject *)m_obj; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.