Select Git revision
_tracemalloc.c
_tracemalloc.c 44.86 KiB
#include "Python.h"
#include "pycore_fileutils.h" // _Py_write_noraise()
#include "pycore_gc.h" // PyGC_Head
#include "pycore_hashtable.h" // _Py_hashtable_t
#include "pycore_pymem.h" // _Py_tracemalloc_config
#include "pycore_runtime.h" // _Py_ID()
#include "pycore_traceback.h"
#include <pycore_frame.h>
#include <stdlib.h> // malloc()
#include "clinic/_tracemalloc.c.h"
/*[clinic input]
module _tracemalloc
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/
_Py_DECLARE_STR(anon_unknown, "<unknown>");
/* Trace memory blocks allocated by PyMem_RawMalloc() */
#define TRACE_RAW_MALLOC
/* Forward declaration */
static void tracemalloc_stop(void);
static void* raw_malloc(size_t size);
static void raw_free(void *ptr);
#ifdef Py_DEBUG
# define TRACE_DEBUG
#endif
#define TO_PTR(key) ((const void *)(uintptr_t)(key))
#define FROM_PTR(key) ((uintptr_t)(key))
/* Protected by the GIL */
static struct {
PyMemAllocatorEx mem;
PyMemAllocatorEx raw;
PyMemAllocatorEx obj;
} allocators;
#if defined(TRACE_RAW_MALLOC)
/* This lock is needed because tracemalloc_free() is called without
the GIL held from PyMem_RawFree(). It cannot acquire the lock because it
would introduce a deadlock in _PyThreadState_DeleteCurrent(). */
static PyThread_type_lock tables_lock;
# define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1)
# define TABLES_UNLOCK() PyThread_release_lock(tables_lock)
#else
/* variables are protected by the GIL */
# define TABLES_LOCK()
# define TABLES_UNLOCK()
#endif
#define DEFAULT_DOMAIN 0
/* Pack the frame_t structure to reduce the memory footprint on 64-bit
architectures: 12 bytes instead of 16. */
typedef struct
#ifdef __GNUC__
__attribute__((packed))
#elif defined(_MSC_VER)
#pragma pack(push, 4)
#endif
{
/* filename cannot be NULL: "<unknown>" is used if the Python frame
filename is NULL */