aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Python
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2025-02-16 15:28:01 +0300
committershadchin <shadchin@yandex-team.com>2025-02-16 16:03:50 +0300
commita27b6a96fdc5ca444428ddef4823d0486dcdccb9 (patch)
treeadde5c24d9ea37e1634e7972e27e682a820ab941 /contrib/tools/python3/Python
parent7a3958c3c6de324baab9dba4bd4eb808c1b839a6 (diff)
downloadydb-a27b6a96fdc5ca444428ddef4823d0486dcdccb9.tar.gz
Update Python 3 to 3.12.9
commit_hash:c8651982d81e18f18e037fb247cc6ae53c4fa7f1
Diffstat (limited to 'contrib/tools/python3/Python')
-rw-r--r--contrib/tools/python3/Python/ceval.c34
-rw-r--r--contrib/tools/python3/Python/errors.c9
-rw-r--r--contrib/tools/python3/Python/generated_cases.c.h2
-rw-r--r--contrib/tools/python3/Python/pylifecycle.c9
-rw-r--r--contrib/tools/python3/Python/pythonrun.c62
-rw-r--r--contrib/tools/python3/Python/sysmodule.c7
-rw-r--r--contrib/tools/python3/Python/tracemalloc.c258
7 files changed, 232 insertions, 149 deletions
diff --git a/contrib/tools/python3/Python/ceval.c b/contrib/tools/python3/Python/ceval.c
index 6110883ca0..3985b52649 100644
--- a/contrib/tools/python3/Python/ceval.c
+++ b/contrib/tools/python3/Python/ceval.c
@@ -20,6 +20,7 @@
#include "pycore_range.h" // _PyRangeIterObject
#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs
#include "pycore_sysmodule.h" // _PySys_Audit()
+#include "pycore_traceback.h" // _PyTraceBack_FromFrame
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_typeobject.h" // _PySuper_Lookup()
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
@@ -544,6 +545,7 @@ fail:
static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause);
static int exception_group_match(
+ _PyInterpreterFrame *frame,
PyObject* exc_value, PyObject *match_type,
PyObject **match, PyObject **rest);
@@ -1856,7 +1858,7 @@ raise_error:
*/
static int
-exception_group_match(PyObject* exc_value, PyObject *match_type,
+exception_group_match(_PyInterpreterFrame *frame, PyObject* exc_value, PyObject *match_type,
PyObject **match, PyObject **rest)
{
if (Py_IsNone(exc_value)) {
@@ -1883,6 +1885,15 @@ exception_group_match(PyObject* exc_value, PyObject *match_type,
if (wrapped == NULL) {
return -1;
}
+ PyFrameObject *f = _PyFrame_GetFrameObject(frame);
+ if (f != NULL) {
+ PyObject *tb = _PyTraceBack_FromFrame(NULL, f);
+ if (tb == NULL) {
+ return -1;
+ }
+ PyException_SetTraceback(wrapped, tb);
+ Py_DECREF(tb);
+ }
*match = wrapped;
}
*rest = Py_NewRef(Py_None);
@@ -1898,8 +1909,25 @@ exception_group_match(PyObject* exc_value, PyObject *match_type,
if (pair == NULL) {
return -1;
}
- assert(PyTuple_CheckExact(pair));
- assert(PyTuple_GET_SIZE(pair) == 2);
+
+ if (!PyTuple_CheckExact(pair)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.split must return a tuple, not %.200s",
+ Py_TYPE(exc_value)->tp_name, Py_TYPE(pair)->tp_name);
+ Py_DECREF(pair);
+ return -1;
+ }
+
+ // allow tuples of length > 2 for backwards compatibility
+ if (PyTuple_GET_SIZE(pair) < 2) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.split must return a 2-tuple, "
+ "got tuple of size %zd",
+ Py_TYPE(exc_value)->tp_name, PyTuple_GET_SIZE(pair));
+ Py_DECREF(pair);
+ return -1;
+ }
+
*match = Py_NewRef(PyTuple_GET_ITEM(pair, 0));
*rest = Py_NewRef(PyTuple_GET_ITEM(pair, 1));
Py_DECREF(pair);
diff --git a/contrib/tools/python3/Python/errors.c b/contrib/tools/python3/Python/errors.c
index 7a16841eba..e4b7fd6b24 100644
--- a/contrib/tools/python3/Python/errors.c
+++ b/contrib/tools/python3/Python/errors.c
@@ -305,6 +305,15 @@ PyErr_SetString(PyObject *exception, const char *string)
_PyErr_SetString(tstate, exception, string);
}
+void
+_PyErr_SetLocaleString(PyObject *exception, const char *string)
+{
+ PyObject *value = PyUnicode_DecodeLocale(string, "surrogateescape");
+ if (value != NULL) {
+ PyErr_SetObject(exception, value);
+ Py_DECREF(value);
+ }
+}
PyObject* _Py_HOT_FUNCTION
PyErr_Occurred(void)
diff --git a/contrib/tools/python3/Python/generated_cases.c.h b/contrib/tools/python3/Python/generated_cases.c.h
index bbaf589e2e..246d37e771 100644
--- a/contrib/tools/python3/Python/generated_cases.c.h
+++ b/contrib/tools/python3/Python/generated_cases.c.h
@@ -2952,7 +2952,7 @@
match = NULL;
rest = NULL;
- int res = exception_group_match(exc_value, match_type,
+ int res = exception_group_match(frame, exc_value, match_type,
&match, &rest);
#line 2958 "Python/generated_cases.c.h"
Py_DECREF(exc_value);
diff --git a/contrib/tools/python3/Python/pylifecycle.c b/contrib/tools/python3/Python/pylifecycle.c
index e9c1a0d72d..ef4e607657 100644
--- a/contrib/tools/python3/Python/pylifecycle.c
+++ b/contrib/tools/python3/Python/pylifecycle.c
@@ -654,6 +654,11 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
// didn't depend on interp->feature_flags being set already.
_PyObject_InitState(interp);
+ status = _PyTraceMalloc_Init();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
PyThreadState *tstate = _PyThreadState_New(interp);
if (tstate == NULL) {
return _PyStatus_ERR("can't make first thread");
@@ -1928,7 +1933,7 @@ Py_FinalizeEx(void)
/* Disable tracemalloc after all Python objects have been destroyed,
so it is possible to use tracemalloc in objects destructor. */
- _PyTraceMalloc_Fini();
+ _PyTraceMalloc_Stop();
/* Finalize any remaining import state */
// XXX Move these up to where finalize_modules() is currently.
@@ -1981,6 +1986,8 @@ Py_FinalizeEx(void)
finalize_interp_clear(tstate);
+ _PyTraceMalloc_Fini();
+
#ifdef WITH_PYMALLOC
if (malloc_stats) {
_PyObject_DebugMallocStats(stderr);
diff --git a/contrib/tools/python3/Python/pythonrun.c b/contrib/tools/python3/Python/pythonrun.c
index 5f3d249df4..cf84573a8e 100644
--- a/contrib/tools/python3/Python/pythonrun.c
+++ b/contrib/tools/python3/Python/pythonrun.c
@@ -538,43 +538,37 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
*offset = hold;
}
- if (Py_TYPE(err) == (PyTypeObject*)PyExc_SyntaxError) {
- v = PyObject_GetAttr(err, &_Py_ID(end_lineno));
- if (!v) {
- PyErr_Clear();
- *end_lineno = *lineno;
- }
- else if (v == Py_None) {
- *end_lineno = *lineno;
- Py_DECREF(v);
- } else {
- hold = PyLong_AsSsize_t(v);
- Py_DECREF(v);
- if (hold < 0 && PyErr_Occurred())
- goto finally;
- *end_lineno = hold;
- }
-
- v = PyObject_GetAttr(err, &_Py_ID(end_offset));
- if (!v) {
- PyErr_Clear();
- *end_offset = -1;
- }
- else if (v == Py_None) {
- *end_offset = -1;
- Py_DECREF(v);
- } else {
- hold = PyLong_AsSsize_t(v);
- Py_DECREF(v);
- if (hold < 0 && PyErr_Occurred())
- goto finally;
- *end_offset = hold;
- }
- } else {
- // SyntaxError subclasses
+ v = PyObject_GetAttr(err, &_Py_ID(end_lineno));
+ if (!v) {
+ PyErr_Clear();
*end_lineno = *lineno;
+ }
+ else if (v == Py_None) {
+ *end_lineno = *lineno;
+ Py_DECREF(v);
+ } else {
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred())
+ goto finally;
+ *end_lineno = hold;
+ }
+
+ v = PyObject_GetAttr(err, &_Py_ID(end_offset));
+ if (!v) {
+ PyErr_Clear();
*end_offset = -1;
}
+ else if (v == Py_None) {
+ *end_offset = -1;
+ Py_DECREF(v);
+ } else {
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred())
+ goto finally;
+ *end_offset = hold;
+ }
v = PyObject_GetAttr(err, &_Py_ID(text));
if (!v)
diff --git a/contrib/tools/python3/Python/sysmodule.c b/contrib/tools/python3/Python/sysmodule.c
index 7240f8e4e1..7813048be4 100644
--- a/contrib/tools/python3/Python/sysmodule.c
+++ b/contrib/tools/python3/Python/sysmodule.c
@@ -2653,6 +2653,7 @@ PySys_ResetWarnOptions(void)
static int
_PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
{
+ assert(tstate != NULL);
PyObject *warnoptions = get_warnoptions(tstate);
if (warnoptions == NULL) {
return -1;
@@ -2667,11 +2668,11 @@ void
PySys_AddWarnOptionUnicode(PyObject *option)
{
PyThreadState *tstate = _PyThreadState_GET();
+ _Py_EnsureTstateNotNULL(tstate);
+ assert(!_PyErr_Occurred(tstate));
if (_PySys_AddWarnOptionWithError(tstate, option) < 0) {
/* No return value, therefore clear error state if possible */
- if (tstate) {
- _PyErr_Clear(tstate);
- }
+ _PyErr_Clear(tstate);
}
}
diff --git a/contrib/tools/python3/Python/tracemalloc.c b/contrib/tools/python3/Python/tracemalloc.c
index e13064bd14..852e5b0391 100644
--- a/contrib/tools/python3/Python/tracemalloc.c
+++ b/contrib/tools/python3/Python/tracemalloc.c
@@ -2,6 +2,7 @@
#include "pycore_fileutils.h" // _Py_write_noraise()
#include "pycore_gc.h" // PyGC_Head
#include "pycore_hashtable.h" // _Py_hashtable_t
+#include "pycore_initconfig.h" // _PyStatus_NO_MEMORY()
#include "pycore_object.h" // _PyType_PreHeaderSize
#include "pycore_pymem.h" // _Py_tracemalloc_config
#include "pycore_runtime.h" // _Py_ID()
@@ -536,12 +537,16 @@ tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize)
return NULL;
TABLES_LOCK();
- if (ADD_TRACE(ptr, nelem * elsize) < 0) {
- /* Failed to allocate a trace for the new memory block */
- TABLES_UNLOCK();
- alloc->free(alloc->ctx, ptr);
- return NULL;
+
+ if (tracemalloc_config.tracing) {
+ if (ADD_TRACE(ptr, nelem * elsize) < 0) {
+ /* Failed to allocate a trace for the new memory block */
+ alloc->free(alloc->ctx, ptr);
+ ptr = NULL;
+ }
}
+ // else: gh-128679: tracemalloc.stop() was called by another thread
+
TABLES_UNLOCK();
return ptr;
}
@@ -557,11 +562,15 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size)
if (ptr2 == NULL)
return NULL;
+ TABLES_LOCK();
+ if (!tracemalloc_config.tracing) {
+ // gh-128679: tracemalloc.stop() was called by another thread
+ goto done;
+ }
+
if (ptr != NULL) {
/* an existing memory block has been resized */
- TABLES_LOCK();
-
/* tracemalloc_add_trace() updates the trace if there is already
a trace at address ptr2 */
if (ptr2 != ptr) {
@@ -580,20 +589,19 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size)
allocating memory. */
Py_FatalError("tracemalloc_realloc() failed to allocate a trace");
}
- TABLES_UNLOCK();
}
else {
/* new allocation */
- TABLES_LOCK();
if (ADD_TRACE(ptr2, new_size) < 0) {
/* Failed to allocate a trace for the new memory block */
- TABLES_UNLOCK();
alloc->free(alloc->ctx, ptr2);
- return NULL;
+ ptr2 = NULL;
}
- TABLES_UNLOCK();
}
+
+done:
+ TABLES_UNLOCK();
return ptr2;
}
@@ -612,7 +620,12 @@ tracemalloc_free(void *ctx, void *ptr)
alloc->free(alloc->ctx, ptr);
TABLES_LOCK();
- REMOVE_TRACE(ptr);
+
+ if (tracemalloc_config.tracing) {
+ REMOVE_TRACE(ptr);
+ }
+ // else: gh-128679: tracemalloc.stop() was called by another thread
+
TABLES_UNLOCK();
}
@@ -671,7 +684,9 @@ tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size)
ptr2 = alloc->realloc(alloc->ctx, ptr, new_size);
if (ptr2 != NULL && ptr != NULL) {
TABLES_LOCK();
- REMOVE_TRACE(ptr);
+ if (tracemalloc_config.tracing) {
+ REMOVE_TRACE(ptr);
+ }
TABLES_UNLOCK();
}
return ptr2;
@@ -746,7 +761,9 @@ tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size)
if (ptr2 != NULL && ptr != NULL) {
TABLES_LOCK();
- REMOVE_TRACE(ptr);
+ if (tracemalloc_config.tracing) {
+ REMOVE_TRACE(ptr);
+ }
TABLES_UNLOCK();
}
return ptr2;
@@ -777,46 +794,36 @@ tracemalloc_clear_filename(void *value)
/* reentrant flag must be set to call this function and GIL must be held */
static void
-tracemalloc_clear_traces(void)
+tracemalloc_clear_traces_unlocked(void)
{
+ set_reentrant(1);
+
/* The GIL protects variables against concurrent access */
assert(PyGILState_Check());
- TABLES_LOCK();
_Py_hashtable_clear(tracemalloc_traces);
_Py_hashtable_clear(tracemalloc_domains);
tracemalloc_traced_memory = 0;
tracemalloc_peak_traced_memory = 0;
- TABLES_UNLOCK();
_Py_hashtable_clear(tracemalloc_tracebacks);
_Py_hashtable_clear(tracemalloc_filenames);
+
+ set_reentrant(0);
}
-int
+PyStatus
_PyTraceMalloc_Init(void)
{
- if (tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) {
- PyErr_SetString(PyExc_RuntimeError,
- "the tracemalloc module has been unloaded");
- return -1;
- }
-
- if (tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED)
- return 0;
+ assert(tracemalloc_config.initialized == TRACEMALLOC_NOT_INITIALIZED);
PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
#ifdef REENTRANT_THREADLOCAL
if (PyThread_tss_create(&tracemalloc_reentrant_key) != 0) {
-#ifdef MS_WINDOWS
- PyErr_SetFromWindowsErr(0);
-#else
- PyErr_SetFromErrno(PyExc_OSError);
-#endif
- return -1;
+ return _PyStatus_NO_MEMORY();
}
#endif
@@ -824,8 +831,7 @@ _PyTraceMalloc_Init(void)
if (tables_lock == NULL) {
tables_lock = PyThread_allocate_lock();
if (tables_lock == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "cannot allocate lock");
- return -1;
+ return _PyStatus_NO_MEMORY();
}
}
#endif
@@ -842,9 +848,9 @@ _PyTraceMalloc_Init(void)
tracemalloc_domains = tracemalloc_create_domains_table();
if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL
- || tracemalloc_traces == NULL || tracemalloc_domains == NULL) {
- PyErr_NoMemory();
- return -1;
+ || tracemalloc_traces == NULL || tracemalloc_domains == NULL)
+ {
+ return _PyStatus_NO_MEMORY();
}
tracemalloc_empty_traceback.nframe = 1;
@@ -855,7 +861,7 @@ _PyTraceMalloc_Init(void)
tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback);
tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED;
- return 0;
+ return _PyStatus_OK();
}
@@ -900,10 +906,6 @@ _PyTraceMalloc_Start(int max_nframe)
return -1;
}
- if (_PyTraceMalloc_Init() < 0) {
- return -1;
- }
-
if (tracemalloc_config.tracing) {
/* hook already installed: do nothing */
return 0;
@@ -954,8 +956,13 @@ _PyTraceMalloc_Start(int max_nframe)
void
_PyTraceMalloc_Stop(void)
{
- if (!tracemalloc_config.tracing)
- return;
+ // Lock to synchronize with tracemalloc_free() which checks
+ // 'tracing' while holding the lock.
+ TABLES_LOCK();
+
+ if (!tracemalloc_config.tracing) {
+ goto done;
+ }
/* stop tracing Python memory allocations */
tracemalloc_config.tracing = 0;
@@ -967,11 +974,14 @@ _PyTraceMalloc_Stop(void)
PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem);
PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj);
- tracemalloc_clear_traces();
+ tracemalloc_clear_traces_unlocked();
/* release memory */
raw_free(tracemalloc_traceback);
tracemalloc_traceback = NULL;
+
+done:
+ TABLES_UNLOCK();
}
@@ -1221,23 +1231,17 @@ tracemalloc_pyobject_decref(void *value)
static traceback_t*
-tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr)
+tracemalloc_get_traceback_unlocked(unsigned int domain, uintptr_t ptr)
{
-
- if (!tracemalloc_config.tracing)
+ if (!tracemalloc_config.tracing) {
return NULL;
+ }
- trace_t *trace;
- TABLES_LOCK();
_Py_hashtable_t *traces = tracemalloc_get_traces_table(domain);
+ trace_t *trace = NULL;
if (traces) {
trace = _Py_hashtable_get(traces, TO_PTR(ptr));
}
- else {
- trace = NULL;
- }
- TABLES_UNLOCK();
-
if (!trace) {
return NULL;
}
@@ -1266,13 +1270,20 @@ _PyMem_DumpTraceback(int fd, const void *ptr)
traceback_t *traceback;
int i;
- if (!tracemalloc_config.tracing) {
+ TABLES_LOCK();
+
+ if (tracemalloc_config.tracing) {
+ traceback = tracemalloc_get_traceback_unlocked(DEFAULT_DOMAIN,
+ (uintptr_t)ptr);
+ }
+ else {
+ traceback = NULL;
PUTS(fd, "Enable tracemalloc to get the memory block "
"allocation traceback\n\n");
- return;
}
- traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr);
+ TABLES_UNLOCK();
+
if (traceback == NULL)
return;
@@ -1301,38 +1312,62 @@ int
PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
size_t size)
{
- int res;
- PyGILState_STATE gil_state;
+ PyGILState_STATE gil_state = PyGILState_Ensure();
+ int result;
+ // gh-129185: Check before TABLES_LOCK() to support calls after
+ // _PyTraceMalloc_Fini().
if (!tracemalloc_config.tracing) {
- /* tracemalloc is not tracing: do nothing */
- return -2;
+ result = -2;
+ goto done;
}
- gil_state = PyGILState_Ensure();
-
TABLES_LOCK();
- res = tracemalloc_add_trace(domain, ptr, size);
- TABLES_UNLOCK();
+ if (tracemalloc_config.tracing) {
+ result = tracemalloc_add_trace(domain, ptr, size);
+ }
+ else {
+ // gh-128679: tracemalloc.stop() was called by another thread
+ result = -2;
+ }
+
+ TABLES_UNLOCK();
+done:
PyGILState_Release(gil_state);
- return res;
+ return result;
}
int
PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
{
+ // Need the GIL to prevent races on the first 'tracing' test
+ PyGILState_STATE gil_state = PyGILState_Ensure();
+ int result;
+
+ // gh-129185: Check before TABLES_LOCK() to support calls after
+ // _PyTraceMalloc_Fini()
if (!tracemalloc_config.tracing) {
- /* tracemalloc is not tracing: do nothing */
- return -2;
+ result = -2;
+ goto done;
}
TABLES_LOCK();
- tracemalloc_remove_trace(domain, ptr);
- TABLES_UNLOCK();
- return 0;
+ if (tracemalloc_config.tracing) {
+ tracemalloc_remove_trace(domain, ptr);
+ result = 0;
+ }
+ else {
+ /* tracemalloc is not tracing: do nothing */
+ result = -2;
+ }
+
+ TABLES_UNLOCK();
+done:
+ PyGILState_Release(gil_state);
+ return result;
}
@@ -1366,6 +1401,12 @@ _PyTraceMalloc_NewReference(PyObject *op)
int res = -1;
TABLES_LOCK();
+
+ if (!tracemalloc_config.tracing) {
+ // gh-128679: tracemalloc.stop() was called by another thread
+ goto done;
+ }
+
trace_t *trace = _Py_hashtable_get(tracemalloc_traces, TO_PTR(ptr));
if (trace != NULL) {
/* update the traceback of the memory block */
@@ -1376,6 +1417,8 @@ _PyTraceMalloc_NewReference(PyObject *op)
}
}
/* else: cannot track the object, its memory block size is unknown */
+
+done:
TABLES_UNLOCK();
return res;
@@ -1387,7 +1430,9 @@ _PyTraceMalloc_GetTraceback(unsigned int domain, uintptr_t ptr)
{
traceback_t *traceback;
- traceback = tracemalloc_get_traceback(domain, ptr);
+ TABLES_LOCK();
+ traceback = tracemalloc_get_traceback_unlocked(domain, ptr);
+ TABLES_UNLOCK();
if (traceback == NULL)
Py_RETURN_NONE;
@@ -1397,19 +1442,20 @@ _PyTraceMalloc_GetTraceback(unsigned int domain, uintptr_t ptr)
int
_PyTraceMalloc_IsTracing(void)
{
- return tracemalloc_config.tracing;
+ TABLES_LOCK();
+ int tracing = tracemalloc_config.tracing;
+ TABLES_UNLOCK();
+ return tracing;
}
void
_PyTraceMalloc_ClearTraces(void)
{
-
- if (!tracemalloc_config.tracing) {
- return;
+ TABLES_LOCK();
+ if (tracemalloc_config.tracing) {
+ tracemalloc_clear_traces_unlocked();
}
- set_reentrant(1);
- tracemalloc_clear_traces();
- set_reentrant(0);
+ TABLES_UNLOCK();
}
PyObject *
@@ -1496,19 +1542,10 @@ PyObject *
_PyTraceMalloc_GetObjectTraceback(PyObject *obj)
/*[clinic end generated code: output=41ee0553a658b0aa input=29495f1b21c53212]*/
{
- PyTypeObject *type;
- traceback_t *traceback;
-
- type = Py_TYPE(obj);
+ PyTypeObject *type = Py_TYPE(obj);
const size_t presize = _PyType_PreHeaderSize(type);
uintptr_t ptr = (uintptr_t)((char *)obj - presize);
-
- traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, ptr);
- if (traceback == NULL) {
- Py_RETURN_NONE;
- }
-
- return traceback_to_pyobject(traceback, NULL);
+ return _PyTraceMalloc_GetTraceback(DEFAULT_DOMAIN, ptr);
}
int _PyTraceMalloc_GetTracebackLimit(void) {
@@ -1520,14 +1557,19 @@ _PyTraceMalloc_GetMemory(void) {
size_t size;
- size = _Py_hashtable_size(tracemalloc_tracebacks);
- size += _Py_hashtable_size(tracemalloc_filenames);
-
TABLES_LOCK();
- size += _Py_hashtable_size(tracemalloc_traces);
- _Py_hashtable_foreach(tracemalloc_domains,
- tracemalloc_get_tracemalloc_memory_cb, &size);
+ if (tracemalloc_config.tracing) {
+ size = _Py_hashtable_size(tracemalloc_tracebacks);
+ size += _Py_hashtable_size(tracemalloc_filenames);
+ size += _Py_hashtable_size(tracemalloc_traces);
+ _Py_hashtable_foreach(tracemalloc_domains,
+ tracemalloc_get_tracemalloc_memory_cb, &size);
+ }
+ else {
+ size = 0;
+ }
TABLES_UNLOCK();
+
return size;
}
@@ -1537,12 +1579,15 @@ _PyTraceMalloc_GetTracedMemory(void)
{
Py_ssize_t size, peak_size;
- if (!tracemalloc_config.tracing)
- return Py_BuildValue("ii", 0, 0);
-
TABLES_LOCK();
- size = tracemalloc_traced_memory;
- peak_size = tracemalloc_peak_traced_memory;
+ if (tracemalloc_config.tracing) {
+ size = tracemalloc_traced_memory;
+ peak_size = tracemalloc_peak_traced_memory;
+ }
+ else {
+ size = 0;
+ peak_size = 0;
+ }
TABLES_UNLOCK();
return Py_BuildValue("nn", size, peak_size);
@@ -1551,10 +1596,9 @@ _PyTraceMalloc_GetTracedMemory(void)
void
_PyTraceMalloc_ResetPeak(void)
{
- if (!tracemalloc_config.tracing) {
- return;
- }
TABLES_LOCK();
- tracemalloc_peak_traced_memory = tracemalloc_traced_memory;
+ if (tracemalloc_config.tracing) {
+ tracemalloc_peak_traced_memory = tracemalloc_traced_memory;
+ }
TABLES_UNLOCK();
}