mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
gh-141770: Annotate anonymous mmap usage if "-X dev" is used (gh-142079)
This commit is contained in:
parent
e3539e99e3
commit
c4ccaf4b10
15 changed files with 107 additions and 1 deletions
|
|
@ -1236,6 +1236,12 @@ Build changes
|
|||
modules that are missing or packaged separately.
|
||||
(Contributed by Stan Ulbrych and Petr Viktorin in :gh:`139707`.)
|
||||
|
||||
* Annotating anonymous mmap usage is now supported if Linux kernel supports
|
||||
:manpage:`PR_SET_VMA_ANON_NAME <PR_SET_VMA(2const)>` (Linux 5.17 or newer).
|
||||
Annotations are visible in ``/proc/<pid>/maps`` if the kernel supports the feature
|
||||
and :option:`-X dev <-X>` is passed to the Python or Python is built in :ref:`debug mode <debug-build>`.
|
||||
(Contributed by Donghee Na in :gh:`141770`)
|
||||
|
||||
|
||||
Porting to Python 3.15
|
||||
======================
|
||||
|
|
|
|||
45
Include/internal/pycore_mmap.h
Normal file
45
Include/internal/pycore_mmap.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef Py_INTERNAL_MMAP_H
|
||||
#define Py_INTERNAL_MMAP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_pystate.h"
|
||||
|
||||
#if defined(HAVE_PR_SET_VMA_ANON_NAME) && defined(__linux__)
|
||||
# include <linux/prctl.h>
|
||||
# include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PR_SET_VMA_ANON_NAME) && defined(__linux__)
|
||||
static inline void
|
||||
_PyAnnotateMemoryMap(void *addr, size_t size, const char *name)
|
||||
{
|
||||
#ifndef Py_DEBUG
|
||||
if (!_Py_GetConfig()->dev_mode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
assert(strlen(name) < 80);
|
||||
int old_errno = errno;
|
||||
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (unsigned long)addr, size, name);
|
||||
/* Ignore errno from prctl */
|
||||
/* See: https://bugzilla.redhat.com/show_bug.cgi?id=2302746 */
|
||||
errno = old_errno;
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
_PyAnnotateMemoryMap(void *Py_UNUSED(addr), size_t Py_UNUSED(size), const char *Py_UNUSED(name))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // !Py_INTERNAL_MMAP_H
|
||||
|
|
@ -1378,6 +1378,7 @@ PYTHON_HEADERS= \
|
|||
$(srcdir)/Include/internal/pycore_long.h \
|
||||
$(srcdir)/Include/internal/pycore_memoryobject.h \
|
||||
$(srcdir)/Include/internal/pycore_mimalloc.h \
|
||||
$(srcdir)/Include/internal/pycore_mmap.h \
|
||||
$(srcdir)/Include/internal/pycore_modsupport.h \
|
||||
$(srcdir)/Include/internal/pycore_moduleobject.h \
|
||||
$(srcdir)/Include/internal/pycore_namespace.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Annotate anonymous mmap usage only when supported by the
|
||||
Linux kernel and if ``-X dev`` is used or Python is built in debug mode. Patch by Donghee Na.
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
# endif
|
||||
#endif
|
||||
#include "ctypes.h"
|
||||
#include "pycore_mmap.h" // _PyAnnotateMemoryMap()
|
||||
|
||||
/* BLOCKSIZE can be adjusted. Larger blocksize will take a larger memory
|
||||
overhead, but allocate less blocks from the system. It may be that some
|
||||
|
|
@ -74,14 +75,16 @@ static void more_core(void)
|
|||
if (item == NULL)
|
||||
return;
|
||||
#else
|
||||
size_t mem_size = count * sizeof(ITEM);
|
||||
item = (ITEM *)mmap(NULL,
|
||||
count * sizeof(ITEM),
|
||||
mem_size,
|
||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1,
|
||||
0);
|
||||
if (item == (void *)MAP_FAILED)
|
||||
return;
|
||||
_PyAnnotateMemoryMap(item, mem_size, "cpython:ctypes");
|
||||
#endif
|
||||
|
||||
#ifdef MALLOC_CLOSURE_DEBUG
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t()
|
||||
#include "pycore_bytesobject.h" // _PyBytes_Find()
|
||||
#include "pycore_fileutils.h" // _Py_stat_struct
|
||||
#include "pycore_mmap.h" // _PyAnnotateMemoryMap()
|
||||
#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
|
||||
|
||||
#include <stddef.h> // offsetof()
|
||||
|
|
@ -1951,6 +1952,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
|
|||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return NULL;
|
||||
}
|
||||
_PyAnnotateMemoryMap(m_obj->data, map_size, "cpython:mmap");
|
||||
m_obj->access = (access_mode)access;
|
||||
return (PyObject *)m_obj;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Python.h"
|
||||
#include "pycore_interp.h" // _PyInterpreterState_HasFeature
|
||||
#include "pycore_mmap.h" // _PyAnnotateMemoryMap()
|
||||
#include "pycore_object.h" // _PyDebugAllocatorStats() definition
|
||||
#include "pycore_obmalloc.h"
|
||||
#include "pycore_obmalloc_init.h"
|
||||
|
|
@ -467,6 +468,7 @@ _PyMem_ArenaAlloc(void *Py_UNUSED(ctx), size_t size)
|
|||
if (ptr == MAP_FAILED)
|
||||
return NULL;
|
||||
assert(ptr != NULL);
|
||||
_PyAnnotateMemoryMap(ptr, size, "cpython:pymalloc");
|
||||
return ptr;
|
||||
#else
|
||||
return malloc(size);
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_llist.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_lock.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_long.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_mmap.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_modsupport.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_moduleobject.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_namespace.h" />
|
||||
|
|
|
|||
|
|
@ -735,6 +735,9 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_long.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\internal\pycore_mmap.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\internal\pycore_modsupport.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "pycore_intrinsics.h"
|
||||
#include "pycore_list.h"
|
||||
#include "pycore_long.h"
|
||||
#include "pycore_mmap.h"
|
||||
#include "pycore_opcode_metadata.h"
|
||||
#include "pycore_opcode_utils.h"
|
||||
#include "pycore_optimizer.h"
|
||||
|
|
@ -75,6 +76,9 @@ jit_alloc(size_t size)
|
|||
int prot = PROT_READ | PROT_WRITE;
|
||||
unsigned char *memory = mmap(NULL, size, prot, flags, -1, 0);
|
||||
int failed = memory == MAP_FAILED;
|
||||
if (!failed) {
|
||||
_PyAnnotateMemoryMap(memory, size, "cpython:jit");
|
||||
}
|
||||
#endif
|
||||
if (failed) {
|
||||
jit_error("unable to allocate memory");
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#include "pycore_ceval.h" // _PyPerf_Callbacks
|
||||
#include "pycore_frame.h"
|
||||
#include "pycore_interp.h"
|
||||
#include "pycore_mmap.h" // _PyAnnotateMemoryMap()
|
||||
#include "pycore_runtime.h" // _PyRuntime
|
||||
|
||||
#ifdef PY_HAVE_PERF_TRAMPOLINE
|
||||
|
|
@ -1085,6 +1086,7 @@ static void* perf_map_jit_init(void) {
|
|||
close(fd);
|
||||
return NULL; // Memory mapping failed
|
||||
}
|
||||
_PyAnnotateMemoryMap(perf_jit_map_state.mapped_buffer, page_size, "cpython:perf_jit_trampoline");
|
||||
#endif
|
||||
|
||||
perf_jit_map_state.mapped_size = page_size;
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ any DWARF information available for them).
|
|||
#include "Python.h"
|
||||
#include "pycore_ceval.h" // _PyPerf_Callbacks
|
||||
#include "pycore_interpframe.h" // _PyFrame_GetCode()
|
||||
#include "pycore_mmap.h" // _PyAnnotateMemoryMap()
|
||||
#include "pycore_runtime.h" // _PyRuntime
|
||||
|
||||
|
||||
|
|
@ -290,6 +291,7 @@ new_code_arena(void)
|
|||
perf_status = PERF_STATUS_FAILED;
|
||||
return -1;
|
||||
}
|
||||
_PyAnnotateMemoryMap(memory, mem_size, "cpython:perf_trampoline");
|
||||
void *start = &_Py_trampoline_func_start;
|
||||
void *end = &_Py_trampoline_func_end;
|
||||
size_t code_size = end - start;
|
||||
|
|
|
|||
19
configure
generated
vendored
19
configure
generated
vendored
|
|
@ -23947,6 +23947,25 @@ printf "%s\n" "#define HAVE_UT_NAMESIZE 1" >>confdefs.h
|
|||
fi
|
||||
|
||||
|
||||
ac_fn_check_decl "$LINENO" "PR_SET_VMA_ANON_NAME" "ac_cv_have_decl_PR_SET_VMA_ANON_NAME" "#include <linux/prctl.h>
|
||||
#include <sys/prctl.h>
|
||||
" "$ac_c_undeclared_builtin_options" "CFLAGS"
|
||||
if test "x$ac_cv_have_decl_PR_SET_VMA_ANON_NAME" = xyes
|
||||
then :
|
||||
ac_have_decl=1
|
||||
else case e in #(
|
||||
e) ac_have_decl=0 ;;
|
||||
esac
|
||||
fi
|
||||
printf "%s\n" "#define HAVE_DECL_PR_SET_VMA_ANON_NAME $ac_have_decl" >>confdefs.h
|
||||
if test $ac_have_decl = 1
|
||||
then :
|
||||
|
||||
printf "%s\n" "#define HAVE_PR_SET_VMA_ANON_NAME 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# check for openpty, login_tty, and forkpty
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5583,6 +5583,13 @@ AC_CHECK_DECLS([UT_NAMESIZE],
|
|||
[],
|
||||
[@%:@include <utmp.h>])
|
||||
|
||||
AC_CHECK_DECLS([PR_SET_VMA_ANON_NAME],
|
||||
[AC_DEFINE([HAVE_PR_SET_VMA_ANON_NAME], [1],
|
||||
[Define if you have the 'PR_SET_VMA_ANON_NAME' constant.])],
|
||||
[],
|
||||
[@%:@include <linux/prctl.h>
|
||||
@%:@include <sys/prctl.h>])
|
||||
|
||||
# check for openpty, login_tty, and forkpty
|
||||
|
||||
AC_CHECK_FUNCS([openpty], [],
|
||||
|
|
|
|||
|
|
@ -228,6 +228,10 @@
|
|||
/* Define to 1 if you have the <db.h> header file. */
|
||||
#undef HAVE_DB_H
|
||||
|
||||
/* Define to 1 if you have the declaration of 'PR_SET_VMA_ANON_NAME', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_PR_SET_VMA_ANON_NAME
|
||||
|
||||
/* Define to 1 if you have the declaration of 'RTLD_DEEPBIND', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_RTLD_DEEPBIND
|
||||
|
|
@ -996,6 +1000,9 @@
|
|||
/* Define if your compiler supports function prototype */
|
||||
#undef HAVE_PROTOTYPES
|
||||
|
||||
/* Define if you have the 'PR_SET_VMA_ANON_NAME' constant. */
|
||||
#undef HAVE_PR_SET_VMA_ANON_NAME
|
||||
|
||||
/* Define to 1 if you have the 'pthread_condattr_setclock' function. */
|
||||
#undef HAVE_PTHREAD_CONDATTR_SETCLOCK
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue