Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Include/internal/pycore_pymem.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

#if defined(Py_DEBUG) && defined(HAVE_PR_SET_VMA_ANON_NAME) && defined(__linux__)
#include <linux/prctl.h>
#include <sys/prctl.h>
#endif

// Try to get the allocators name set by _PyMem_SetupAllocators().
// Return NULL if unknown.
// Export for '_testinternalcapi' shared extension.
Expand Down Expand Up @@ -91,6 +96,18 @@ static inline int _PyMem_IsULongFreed(unsigned long value)
#endif
}

static inline int
_PyAnnotateMemoryMap(void *addr, size_t size, const char *name)
{
#if defined(Py_DEBUG) && defined(HAVE_PR_SET_VMA_ANON_NAME) && defined(__linux__)
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 = 0;
#endif
return 0;
}

extern int _PyMem_GetAllocatorName(
const char *name,
PyMemAllocatorName *allocator);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Annotate anonymous mmap usage in debug builds only when supported by the
Linux kernel. Patch by Donghee Na.
5 changes: 4 additions & 1 deletion Modules/_ctypes/malloc_closure.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# endif
#endif
#include "ctypes.h"
#include "pycore_obmalloc.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
Expand Down Expand Up @@ -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:more_core");
#endif

#ifdef MALLOC_CLOSURE_DEBUG
Expand Down
2 changes: 2 additions & 0 deletions Modules/mmapmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_obmalloc.h" // _PyAnnotateMemoryMap()
#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()

#include <stddef.h> // offsetof()
Expand Down Expand Up @@ -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:new_mmap_object");
m_obj->access = (access_mode)access;
return (PyObject *)m_obj;
}
Expand Down
1 change: 1 addition & 0 deletions Objects/obmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ _PyMem_ArenaAlloc(void *Py_UNUSED(ctx), size_t size)
if (ptr == MAP_FAILED)
return NULL;
assert(ptr != NULL);
_PyAnnotateMemoryMap(ptr, size, "cpython:PyMem_ArenaAlloc");
return ptr;
#else
return malloc(size);
Expand Down
3 changes: 3 additions & 0 deletions Python/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,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_alloc");
}
#endif
if (failed) {
jit_error("unable to allocate memory");
Expand Down
2 changes: 2 additions & 0 deletions Python/perf_jit_trampoline.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include "pycore_ceval.h" // _PyPerf_Callbacks
#include "pycore_frame.h"
#include "pycore_interp.h"
#include "pycore_obmalloc.h" // _PyAnnotateMemoryMap()
#include "pycore_runtime.h" // _PyRuntime

#ifdef PY_HAVE_PERF_TRAMPOLINE
Expand Down Expand Up @@ -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_map_jit_init");
#endif

perf_jit_map_state.mapped_size = page_size;
Expand Down
2 changes: 2 additions & 0 deletions Python/perf_trampoline.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_obmalloc.h" // _PyAnnotateMemoryMap()
#include "pycore_runtime.h" // _PyRuntime


Expand Down Expand Up @@ -290,6 +291,7 @@ new_code_arena(void)
perf_status = PERF_STATUS_FAILED;
return -1;
}
_PyAnnotateMemoryMap(memory, mem_size, "cpython:new_code_arena");
void *start = &_Py_trampoline_func_start;
void *end = &_Py_trampoline_func_end;
size_t code_size = end - start;
Expand Down
19 changes: 19 additions & 0 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -5578,6 +5578,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], [],
Expand Down
7 changes: 7 additions & 0 deletions pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
Loading