blob: c5d5671032ebf144562615e0cebad45be9fb520a [file] [log] [blame]
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001#include "Python.h"
2#include "hashtable.h"
3#include "frameobject.h"
4#include "pythread.h"
5#include "osdefs.h"
6
Serhiy Storchakab451f912017-02-04 12:18:38 +02007#include "clinic/_tracemalloc.c.h"
8/*[clinic input]
9module _tracemalloc
10[clinic start generated code]*/
11/*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/
12
Victor Stinnered3b0bc2013-11-23 12:27:24 +010013/* Trace memory blocks allocated by PyMem_RawMalloc() */
14#define TRACE_RAW_MALLOC
15
16/* Forward declaration */
17static void tracemalloc_stop(void);
Victor Stinnered3b0bc2013-11-23 12:27:24 +010018static void* raw_malloc(size_t size);
19static void raw_free(void *ptr);
20
21#ifdef Py_DEBUG
22# define TRACE_DEBUG
23#endif
24
Victor Stinnered3b0bc2013-11-23 12:27:24 +010025/* Protected by the GIL */
26static struct {
Victor Stinnerd8f0d922014-06-02 21:57:10 +020027 PyMemAllocatorEx mem;
28 PyMemAllocatorEx raw;
29 PyMemAllocatorEx obj;
Victor Stinnered3b0bc2013-11-23 12:27:24 +010030} allocators;
31
Victor Stinnered3b0bc2013-11-23 12:27:24 +010032
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020033#if defined(TRACE_RAW_MALLOC)
Victor Stinnered3b0bc2013-11-23 12:27:24 +010034/* This lock is needed because tracemalloc_free() is called without
35 the GIL held from PyMem_RawFree(). It cannot acquire the lock because it
36 would introduce a deadlock in PyThreadState_DeleteCurrent(). */
37static PyThread_type_lock tables_lock;
38# define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1)
39# define TABLES_UNLOCK() PyThread_release_lock(tables_lock)
40#else
41 /* variables are protected by the GIL */
42# define TABLES_LOCK()
43# define TABLES_UNLOCK()
44#endif
45
Victor Stinnere492ae52016-03-22 12:58:23 +010046
47#define DEFAULT_DOMAIN 0
48
Victor Stinnere492ae52016-03-22 12:58:23 +010049/* Pack the frame_t structure to reduce the memory footprint. */
50typedef struct
51#ifdef __GNUC__
52__attribute__((packed))
53#endif
54{
Benjamin Petersonca470632016-09-06 13:47:26 -070055 uintptr_t ptr;
Victor Stinner5ea4c062017-06-20 17:46:36 +020056 unsigned int domain;
Victor Stinnere492ae52016-03-22 12:58:23 +010057} pointer_t;
58
Victor Stinnered3b0bc2013-11-23 12:27:24 +010059/* Pack the frame_t structure to reduce the memory footprint on 64-bit
Victor Stinnere492ae52016-03-22 12:58:23 +010060 architectures: 12 bytes instead of 16. */
Victor Stinnered3b0bc2013-11-23 12:27:24 +010061typedef struct
62#ifdef __GNUC__
63__attribute__((packed))
Victor Stinnerdd382ef2014-02-01 03:43:58 +010064#elif defined(_MSC_VER)
Segev Finer39243772017-07-25 11:47:43 +030065#pragma pack(push, 4)
Victor Stinnered3b0bc2013-11-23 12:27:24 +010066#endif
67{
Victor Stinner7105e9f2016-03-15 14:28:04 +010068 /* filename cannot be NULL: "<unknown>" is used if the Python frame
69 filename is NULL */
Victor Stinnered3b0bc2013-11-23 12:27:24 +010070 PyObject *filename;
Victor Stinner95283342016-03-15 21:57:02 +010071 unsigned int lineno;
Victor Stinnered3b0bc2013-11-23 12:27:24 +010072} frame_t;
Segev Finer39243772017-07-25 11:47:43 +030073#ifdef _MSC_VER
74#pragma pack(pop)
75#endif
Victor Stinnered3b0bc2013-11-23 12:27:24 +010076
Victor Stinnere492ae52016-03-22 12:58:23 +010077
Victor Stinnered3b0bc2013-11-23 12:27:24 +010078typedef struct {
79 Py_uhash_t hash;
80 int nframe;
81 frame_t frames[1];
82} traceback_t;
83
84#define TRACEBACK_SIZE(NFRAME) \
85 (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1))
Victor Stinnerf28ce602013-11-27 22:27:13 +010086
87#define MAX_NFRAME \
Victor Stinner52aee852014-08-16 15:44:02 +020088 ((INT_MAX - (int)sizeof(traceback_t)) / (int)sizeof(frame_t) + 1)
Victor Stinnered3b0bc2013-11-23 12:27:24 +010089
Victor Stinnere492ae52016-03-22 12:58:23 +010090
Victor Stinnered3b0bc2013-11-23 12:27:24 +010091static PyObject *unknown_filename = NULL;
92static traceback_t tracemalloc_empty_traceback;
93
Victor Stinner7a5be142013-11-26 01:06:02 +010094/* Trace of a memory block */
Victor Stinnered3b0bc2013-11-23 12:27:24 +010095typedef struct {
Victor Stinner7a5be142013-11-26 01:06:02 +010096 /* Size of the memory block in bytes */
Victor Stinnered3b0bc2013-11-23 12:27:24 +010097 size_t size;
Victor Stinner7a5be142013-11-26 01:06:02 +010098
99 /* Traceback where the memory block was allocated */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100100 traceback_t *traceback;
101} trace_t;
102
Victor Stinnere492ae52016-03-22 12:58:23 +0100103
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100104/* Size in bytes of currently traced memory.
105 Protected by TABLES_LOCK(). */
106static size_t tracemalloc_traced_memory = 0;
107
Victor Stinner3c0481d2013-11-27 21:39:49 +0100108/* Peak size in bytes of traced memory.
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100109 Protected by TABLES_LOCK(). */
Victor Stinner3c0481d2013-11-27 21:39:49 +0100110static size_t tracemalloc_peak_traced_memory = 0;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100111
Serhiy Storchaka56a6d852014-12-01 18:28:43 +0200112/* Hash table used as a set to intern filenames:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100113 PyObject* => PyObject*.
114 Protected by the GIL */
115static _Py_hashtable_t *tracemalloc_filenames = NULL;
116
Victor Stinnerf28ce602013-11-27 22:27:13 +0100117/* Buffer to store a new traceback in traceback_new().
118 Protected by the GIL. */
119static traceback_t *tracemalloc_traceback = NULL;
120
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100121/* Hash table used as a set to intern tracebacks:
122 traceback_t* => traceback_t*
123 Protected by the GIL */
124static _Py_hashtable_t *tracemalloc_tracebacks = NULL;
125
126/* pointer (void*) => trace (trace_t).
127 Protected by TABLES_LOCK(). */
128static _Py_hashtable_t *tracemalloc_traces = NULL;
129
Victor Stinnere492ae52016-03-22 12:58:23 +0100130
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100131#ifdef TRACE_DEBUG
132static void
133tracemalloc_error(const char *format, ...)
134{
135 va_list ap;
136 fprintf(stderr, "tracemalloc: ");
137 va_start(ap, format);
138 vfprintf(stderr, format, ap);
139 va_end(ap);
140 fprintf(stderr, "\n");
141 fflush(stderr);
142}
143#endif
144
Victor Stinnere492ae52016-03-22 12:58:23 +0100145
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200146#if defined(TRACE_RAW_MALLOC)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100147#define REENTRANT_THREADLOCAL
148
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900149static Py_tss_t tracemalloc_reentrant_key = Py_tss_NEEDS_INIT;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100150
151/* Any non-NULL pointer can be used */
152#define REENTRANT Py_True
153
154static int
155get_reentrant(void)
156{
Victor Stinner4a066472016-03-22 17:45:09 +0100157 void *ptr;
158
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900159 assert(PyThread_tss_is_created(&tracemalloc_reentrant_key));
160 ptr = PyThread_tss_get(&tracemalloc_reentrant_key);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100161 if (ptr != NULL) {
162 assert(ptr == REENTRANT);
163 return 1;
164 }
165 else
166 return 0;
167}
168
169static void
170set_reentrant(int reentrant)
171{
Victor Stinner2ead3d22013-11-26 01:08:53 +0100172 assert(reentrant == 0 || reentrant == 1);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900173 assert(PyThread_tss_is_created(&tracemalloc_reentrant_key));
Victor Stinner4a066472016-03-22 17:45:09 +0100174
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100175 if (reentrant) {
Victor Stinner0cfc0582016-03-22 17:40:07 +0100176 assert(!get_reentrant());
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900177 PyThread_tss_set(&tracemalloc_reentrant_key, REENTRANT);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100178 }
179 else {
Victor Stinner0cfc0582016-03-22 17:40:07 +0100180 assert(get_reentrant());
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900181 PyThread_tss_set(&tracemalloc_reentrant_key, NULL);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100182 }
183}
184
185#else
186
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200187/* TRACE_RAW_MALLOC not defined: variable protected by the GIL */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100188static int tracemalloc_reentrant = 0;
189
190static int
191get_reentrant(void)
192{
193 return tracemalloc_reentrant;
194}
195
196static void
197set_reentrant(int reentrant)
198{
Victor Stinnerd5871e62016-03-23 00:17:04 +0100199 assert(reentrant != tracemalloc_reentrant);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100200 tracemalloc_reentrant = reentrant;
201}
202#endif
203
Victor Stinnere492ae52016-03-22 12:58:23 +0100204
Victor Stinner285cf0a2016-03-21 22:00:58 +0100205static Py_uhash_t
Victor Stinner5dacbd42016-03-23 09:52:13 +0100206hashtable_hash_pyobject(_Py_hashtable_t *ht, const void *pkey)
Victor Stinner51b846c2016-03-18 21:52:22 +0100207{
Victor Stinner285cf0a2016-03-21 22:00:58 +0100208 PyObject *obj;
209
Victor Stinner5dacbd42016-03-23 09:52:13 +0100210 _Py_HASHTABLE_READ_KEY(ht, pkey, obj);
Victor Stinner285cf0a2016-03-21 22:00:58 +0100211 return PyObject_Hash(obj);
212}
213
Victor Stinnere492ae52016-03-22 12:58:23 +0100214
Victor Stinner285cf0a2016-03-21 22:00:58 +0100215static int
Victor Stinner5dacbd42016-03-23 09:52:13 +0100216hashtable_compare_unicode(_Py_hashtable_t *ht, const void *pkey,
Victor Stinner285cf0a2016-03-21 22:00:58 +0100217 const _Py_hashtable_entry_t *entry)
218{
Victor Stinnere492ae52016-03-22 12:58:23 +0100219 PyObject *key1, *key2;
Victor Stinner285cf0a2016-03-21 22:00:58 +0100220
Victor Stinner5dacbd42016-03-23 09:52:13 +0100221 _Py_HASHTABLE_READ_KEY(ht, pkey, key1);
222 _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, key2);
Victor Stinner285cf0a2016-03-21 22:00:58 +0100223
Victor Stinnere492ae52016-03-22 12:58:23 +0100224 if (key1 != NULL && key2 != NULL)
225 return (PyUnicode_Compare(key1, key2) == 0);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100226 else
Victor Stinnere492ae52016-03-22 12:58:23 +0100227 return key1 == key2;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100228}
229
Victor Stinnere492ae52016-03-22 12:58:23 +0100230
231static Py_uhash_t
Victor Stinner5dacbd42016-03-23 09:52:13 +0100232hashtable_hash_pointer_t(_Py_hashtable_t *ht, const void *pkey)
Victor Stinnere492ae52016-03-22 12:58:23 +0100233{
234 pointer_t ptr;
235 Py_uhash_t hash;
236
Victor Stinner5dacbd42016-03-23 09:52:13 +0100237 _Py_HASHTABLE_READ_KEY(ht, pkey, ptr);
Victor Stinnere492ae52016-03-22 12:58:23 +0100238
239 hash = (Py_uhash_t)_Py_HashPointer((void*)ptr.ptr);
240 hash ^= ptr.domain;
241 return hash;
242}
243
244
doko@ubuntu.combc731502016-05-18 01:06:01 +0200245static int
Victor Stinner5dacbd42016-03-23 09:52:13 +0100246hashtable_compare_pointer_t(_Py_hashtable_t *ht, const void *pkey,
Victor Stinnere492ae52016-03-22 12:58:23 +0100247 const _Py_hashtable_entry_t *entry)
248{
249 pointer_t ptr1, ptr2;
250
Victor Stinner5dacbd42016-03-23 09:52:13 +0100251 _Py_HASHTABLE_READ_KEY(ht, pkey, ptr1);
252 _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, ptr2);
Victor Stinnere492ae52016-03-22 12:58:23 +0100253
254 /* compare pointer before domain, because pointer is more likely to be
255 different */
256 return (ptr1.ptr == ptr2.ptr && ptr1.domain == ptr2.domain);
257
258}
259
260
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100261static _Py_hashtable_t *
Victor Stinner285cf0a2016-03-21 22:00:58 +0100262hashtable_new(size_t key_size, size_t data_size,
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100263 _Py_hashtable_hash_func hash_func,
264 _Py_hashtable_compare_func compare_func)
265{
Victor Stinnerc9553872016-03-22 12:13:01 +0100266 _Py_hashtable_allocator_t hashtable_alloc = {malloc, free};
Victor Stinner285cf0a2016-03-21 22:00:58 +0100267 return _Py_hashtable_new_full(key_size, data_size, 0,
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100268 hash_func, compare_func,
Victor Stinnerc9553872016-03-22 12:13:01 +0100269 &hashtable_alloc);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100270}
271
Victor Stinnere492ae52016-03-22 12:58:23 +0100272
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100273static void*
274raw_malloc(size_t size)
275{
276 return allocators.raw.malloc(allocators.raw.ctx, size);
277}
278
279static void
280raw_free(void *ptr)
281{
282 allocators.raw.free(allocators.raw.ctx, ptr);
283}
284
Victor Stinnere492ae52016-03-22 12:58:23 +0100285
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100286static Py_uhash_t
Victor Stinner5dacbd42016-03-23 09:52:13 +0100287hashtable_hash_traceback(_Py_hashtable_t *ht, const void *pkey)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100288{
Victor Stinnerb32a7ed2016-03-21 23:05:08 +0100289 traceback_t *traceback;
Victor Stinner285cf0a2016-03-21 22:00:58 +0100290
Victor Stinner5dacbd42016-03-23 09:52:13 +0100291 _Py_HASHTABLE_READ_KEY(ht, pkey, traceback);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100292 return traceback->hash;
293}
294
Victor Stinnere492ae52016-03-22 12:58:23 +0100295
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100296static int
Victor Stinner5dacbd42016-03-23 09:52:13 +0100297hashtable_compare_traceback(_Py_hashtable_t *ht, const void *pkey,
298 const _Py_hashtable_entry_t *entry)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100299{
Victor Stinner285cf0a2016-03-21 22:00:58 +0100300 traceback_t *traceback1, *traceback2;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100301 const frame_t *frame1, *frame2;
302 int i;
303
Victor Stinner5dacbd42016-03-23 09:52:13 +0100304 _Py_HASHTABLE_READ_KEY(ht, pkey, traceback1);
305 _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, traceback2);
Victor Stinner285cf0a2016-03-21 22:00:58 +0100306
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100307 if (traceback1->nframe != traceback2->nframe)
308 return 0;
309
310 for (i=0; i < traceback1->nframe; i++) {
311 frame1 = &traceback1->frames[i];
312 frame2 = &traceback2->frames[i];
313
314 if (frame1->lineno != frame2->lineno)
315 return 0;
316
317 if (frame1->filename != frame2->filename) {
318 assert(PyUnicode_Compare(frame1->filename, frame2->filename) != 0);
319 return 0;
320 }
321 }
322 return 1;
323}
324
Victor Stinnere492ae52016-03-22 12:58:23 +0100325
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100326static void
327tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame)
328{
329 PyCodeObject *code;
330 PyObject *filename;
331 _Py_hashtable_entry_t *entry;
Victor Stinner95283342016-03-15 21:57:02 +0100332 int lineno;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100333
334 frame->filename = unknown_filename;
Victor Stinner95283342016-03-15 21:57:02 +0100335 lineno = PyFrame_GetLineNumber(pyframe);
336 if (lineno < 0)
337 lineno = 0;
338 frame->lineno = (unsigned int)lineno;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100339
340 code = pyframe->f_code;
341 if (code == NULL) {
342#ifdef TRACE_DEBUG
Victor Stinner4dc74202013-11-26 01:18:52 +0100343 tracemalloc_error("failed to get the code object of the frame");
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100344#endif
345 return;
346 }
347
348 if (code->co_filename == NULL) {
349#ifdef TRACE_DEBUG
350 tracemalloc_error("failed to get the filename of the code object");
351#endif
352 return;
353 }
354
355 filename = code->co_filename;
356 assert(filename != NULL);
357 if (filename == NULL)
358 return;
359
360 if (!PyUnicode_Check(filename)) {
361#ifdef TRACE_DEBUG
Martin Panter6245cb32016-04-15 02:14:19 +0000362 tracemalloc_error("filename is not a unicode string");
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100363#endif
364 return;
365 }
366 if (!PyUnicode_IS_READY(filename)) {
367 /* Don't make a Unicode string ready to avoid reentrant calls
368 to tracemalloc_malloc() or tracemalloc_realloc() */
369#ifdef TRACE_DEBUG
370 tracemalloc_error("filename is not a ready unicode string");
371#endif
372 return;
373 }
374
375 /* intern the filename */
Victor Stinner285cf0a2016-03-21 22:00:58 +0100376 entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_filenames, filename);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100377 if (entry != NULL) {
Victor Stinner5dacbd42016-03-23 09:52:13 +0100378 _Py_HASHTABLE_ENTRY_READ_KEY(tracemalloc_filenames, entry, filename);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100379 }
380 else {
381 /* tracemalloc_filenames is responsible to keep a reference
382 to the filename */
383 Py_INCREF(filename);
Victor Stinner285cf0a2016-03-21 22:00:58 +0100384 if (_Py_HASHTABLE_SET_NODATA(tracemalloc_filenames, filename) < 0) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100385 Py_DECREF(filename);
386#ifdef TRACE_DEBUG
387 tracemalloc_error("failed to intern the filename");
388#endif
389 return;
390 }
391 }
392
393 /* the tracemalloc_filenames table keeps a reference to the filename */
394 frame->filename = filename;
395}
396
Victor Stinnere492ae52016-03-22 12:58:23 +0100397
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100398static Py_uhash_t
399traceback_hash(traceback_t *traceback)
400{
401 /* code based on tuplehash() of Objects/tupleobject.c */
Victor Stinner4d8c29c2013-12-16 23:05:13 +0100402 Py_uhash_t x, y; /* Unsigned for defined overflow behavior. */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100403 int len = traceback->nframe;
404 Py_uhash_t mult = _PyHASH_MULTIPLIER;
405 frame_t *frame;
406
407 x = 0x345678UL;
408 frame = traceback->frames;
409 while (--len >= 0) {
Victor Stinner4d8c29c2013-12-16 23:05:13 +0100410 y = (Py_uhash_t)PyObject_Hash(frame->filename);
411 y ^= (Py_uhash_t)frame->lineno;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100412 frame++;
413
414 x = (x ^ y) * mult;
415 /* the cast might truncate len; that doesn't change hash stability */
Victor Stinner4d8c29c2013-12-16 23:05:13 +0100416 mult += (Py_uhash_t)(82520UL + len + len);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100417 }
418 x += 97531UL;
419 return x;
420}
421
Victor Stinnere492ae52016-03-22 12:58:23 +0100422
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100423static void
424traceback_get_frames(traceback_t *traceback)
425{
426 PyThreadState *tstate;
427 PyFrameObject *pyframe;
428
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100429 tstate = PyGILState_GetThisThreadState();
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100430 if (tstate == NULL) {
431#ifdef TRACE_DEBUG
432 tracemalloc_error("failed to get the current thread state");
433#endif
434 return;
435 }
436
437 for (pyframe = tstate->frame; pyframe != NULL; pyframe = pyframe->f_back) {
438 tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]);
439 assert(traceback->frames[traceback->nframe].filename != NULL);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100440 traceback->nframe++;
Victor Stinner9e00e802018-10-25 13:31:16 +0200441 if (traceback->nframe == _Py_tracemalloc_config.max_nframe)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100442 break;
443 }
444}
445
Victor Stinnere492ae52016-03-22 12:58:23 +0100446
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100447static traceback_t *
448traceback_new(void)
449{
Victor Stinnerf28ce602013-11-27 22:27:13 +0100450 traceback_t *traceback;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100451 _Py_hashtable_entry_t *entry;
452
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100453 assert(PyGILState_Check());
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100454
455 /* get frames */
Victor Stinnerf28ce602013-11-27 22:27:13 +0100456 traceback = tracemalloc_traceback;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100457 traceback->nframe = 0;
458 traceback_get_frames(traceback);
459 if (traceback->nframe == 0)
460 return &tracemalloc_empty_traceback;
461 traceback->hash = traceback_hash(traceback);
462
463 /* intern the traceback */
Victor Stinner285cf0a2016-03-21 22:00:58 +0100464 entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_tracebacks, traceback);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100465 if (entry != NULL) {
Victor Stinner5dacbd42016-03-23 09:52:13 +0100466 _Py_HASHTABLE_ENTRY_READ_KEY(tracemalloc_tracebacks, entry, traceback);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100467 }
468 else {
469 traceback_t *copy;
470 size_t traceback_size;
471
472 traceback_size = TRACEBACK_SIZE(traceback->nframe);
473
474 copy = raw_malloc(traceback_size);
475 if (copy == NULL) {
476#ifdef TRACE_DEBUG
477 tracemalloc_error("failed to intern the traceback: malloc failed");
478#endif
479 return NULL;
480 }
481 memcpy(copy, traceback, traceback_size);
482
Victor Stinner285cf0a2016-03-21 22:00:58 +0100483 if (_Py_HASHTABLE_SET_NODATA(tracemalloc_tracebacks, copy) < 0) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100484 raw_free(copy);
485#ifdef TRACE_DEBUG
486 tracemalloc_error("failed to intern the traceback: putdata failed");
487#endif
488 return NULL;
489 }
490 traceback = copy;
491 }
492 return traceback;
493}
494
Victor Stinnere492ae52016-03-22 12:58:23 +0100495
Victor Stinner5e14a382016-03-23 22:03:55 +0100496static int
497tracemalloc_use_domain_cb(_Py_hashtable_t *old_traces,
498 _Py_hashtable_entry_t *entry, void *user_data)
499{
Benjamin Petersonca470632016-09-06 13:47:26 -0700500 uintptr_t ptr;
Victor Stinner5e14a382016-03-23 22:03:55 +0100501 pointer_t key;
502 _Py_hashtable_t *new_traces = (_Py_hashtable_t *)user_data;
503 const void *pdata = _Py_HASHTABLE_ENTRY_PDATA(old_traces, entry);
504
505 _Py_HASHTABLE_ENTRY_READ_KEY(old_traces, entry, ptr);
506 key.ptr = ptr;
507 key.domain = DEFAULT_DOMAIN;
508
509 return _Py_hashtable_set(new_traces,
510 sizeof(key), &key,
511 old_traces->data_size, pdata);
512}
513
514
Benjamin Petersonca470632016-09-06 13:47:26 -0700515/* Convert tracemalloc_traces from compact key (uintptr_t) to pointer_t key.
Victor Stinner5e14a382016-03-23 22:03:55 +0100516 * Return 0 on success, -1 on error. */
517static int
518tracemalloc_use_domain(void)
519{
520 _Py_hashtable_t *new_traces = NULL;
521
Victor Stinner9e00e802018-10-25 13:31:16 +0200522 assert(!_Py_tracemalloc_config.use_domain);
Victor Stinner5e14a382016-03-23 22:03:55 +0100523
524 new_traces = hashtable_new(sizeof(pointer_t),
525 sizeof(trace_t),
526 hashtable_hash_pointer_t,
527 hashtable_compare_pointer_t);
528 if (new_traces == NULL) {
529 return -1;
530 }
531
532 if (_Py_hashtable_foreach(tracemalloc_traces, tracemalloc_use_domain_cb,
533 new_traces) < 0)
534 {
535 _Py_hashtable_destroy(new_traces);
536 return -1;
537 }
538
539 _Py_hashtable_destroy(tracemalloc_traces);
540 tracemalloc_traces = new_traces;
541
Victor Stinner9e00e802018-10-25 13:31:16 +0200542 _Py_tracemalloc_config.use_domain = 1;
Victor Stinner5e14a382016-03-23 22:03:55 +0100543
544 return 0;
545}
546
547
Victor Stinnere492ae52016-03-22 12:58:23 +0100548static void
Victor Stinner5ea4c062017-06-20 17:46:36 +0200549tracemalloc_remove_trace(unsigned int domain, uintptr_t ptr)
Victor Stinnere492ae52016-03-22 12:58:23 +0100550{
551 trace_t trace;
552 int removed;
553
Victor Stinner9e00e802018-10-25 13:31:16 +0200554 assert(_Py_tracemalloc_config.tracing);
Victor Stinner10b73e12016-03-22 13:39:05 +0100555
Victor Stinner9e00e802018-10-25 13:31:16 +0200556 if (_Py_tracemalloc_config.use_domain) {
Victor Stinnere492ae52016-03-22 12:58:23 +0100557 pointer_t key = {ptr, domain};
558 removed = _Py_HASHTABLE_POP(tracemalloc_traces, key, trace);
559 }
560 else {
561 removed = _Py_HASHTABLE_POP(tracemalloc_traces, ptr, trace);
562 }
563 if (!removed) {
564 return;
565 }
566
567 assert(tracemalloc_traced_memory >= trace.size);
568 tracemalloc_traced_memory -= trace.size;
569}
570
571#define REMOVE_TRACE(ptr) \
Benjamin Petersonca470632016-09-06 13:47:26 -0700572 tracemalloc_remove_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr))
Victor Stinnere492ae52016-03-22 12:58:23 +0100573
574
Victor Stinner52968672013-11-24 11:37:15 +0100575static int
Victor Stinner5ea4c062017-06-20 17:46:36 +0200576tracemalloc_add_trace(unsigned int domain, uintptr_t ptr,
Victor Stinner10b73e12016-03-22 13:39:05 +0100577 size_t size)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100578{
Victor Stinnerca79ccd2016-03-23 09:38:54 +0100579 pointer_t key = {ptr, domain};
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100580 traceback_t *traceback;
581 trace_t trace;
Victor Stinnerca79ccd2016-03-23 09:38:54 +0100582 _Py_hashtable_entry_t* entry;
Victor Stinner52968672013-11-24 11:37:15 +0100583 int res;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100584
Victor Stinner9e00e802018-10-25 13:31:16 +0200585 assert(_Py_tracemalloc_config.tracing);
Victor Stinner10b73e12016-03-22 13:39:05 +0100586
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100587 traceback = traceback_new();
Victor Stinnere492ae52016-03-22 12:58:23 +0100588 if (traceback == NULL) {
Victor Stinner52968672013-11-24 11:37:15 +0100589 return -1;
Victor Stinnere492ae52016-03-22 12:58:23 +0100590 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100591
Victor Stinner9e00e802018-10-25 13:31:16 +0200592 if (!_Py_tracemalloc_config.use_domain && domain != DEFAULT_DOMAIN) {
Victor Stinner5e14a382016-03-23 22:03:55 +0100593 /* first trace using a non-zero domain whereas traces use compact
Benjamin Petersonca470632016-09-06 13:47:26 -0700594 (uintptr_t) keys: switch to pointer_t keys. */
Victor Stinner5e14a382016-03-23 22:03:55 +0100595 if (tracemalloc_use_domain() < 0) {
596 return -1;
597 }
598 }
599
Victor Stinner9e00e802018-10-25 13:31:16 +0200600 if (_Py_tracemalloc_config.use_domain) {
Victor Stinnerca79ccd2016-03-23 09:38:54 +0100601 entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, key);
Victor Stinnere492ae52016-03-22 12:58:23 +0100602 }
603 else {
Victor Stinnerca79ccd2016-03-23 09:38:54 +0100604 entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, ptr);
Victor Stinnerd606ba72013-11-24 11:28:20 +0100605 }
Victor Stinner52968672013-11-24 11:37:15 +0100606
Victor Stinnerca79ccd2016-03-23 09:38:54 +0100607 if (entry != NULL) {
608 /* the memory block is already tracked */
609 _Py_HASHTABLE_ENTRY_READ_DATA(tracemalloc_traces, entry, trace);
610 assert(tracemalloc_traced_memory >= trace.size);
611 tracemalloc_traced_memory -= trace.size;
612
613 trace.size = size;
614 trace.traceback = traceback;
615 _Py_HASHTABLE_ENTRY_WRITE_DATA(tracemalloc_traces, entry, trace);
616 }
617 else {
618 trace.size = size;
619 trace.traceback = traceback;
620
Victor Stinner9e00e802018-10-25 13:31:16 +0200621 if (_Py_tracemalloc_config.use_domain) {
Victor Stinnerca79ccd2016-03-23 09:38:54 +0100622 res = _Py_HASHTABLE_SET(tracemalloc_traces, key, trace);
623 }
624 else {
625 res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace);
626 }
627 if (res != 0) {
628 return res;
629 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100630 }
Victor Stinnere492ae52016-03-22 12:58:23 +0100631
Benjamin Peterson2f8bfef2016-09-07 09:26:18 -0700632 assert(tracemalloc_traced_memory <= SIZE_MAX - size);
Victor Stinnere492ae52016-03-22 12:58:23 +0100633 tracemalloc_traced_memory += size;
634 if (tracemalloc_traced_memory > tracemalloc_peak_traced_memory)
635 tracemalloc_peak_traced_memory = tracemalloc_traced_memory;
636 return 0;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100637}
638
Victor Stinnere492ae52016-03-22 12:58:23 +0100639#define ADD_TRACE(ptr, size) \
Benjamin Petersonca470632016-09-06 13:47:26 -0700640 tracemalloc_add_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr), size)
Victor Stinnere492ae52016-03-22 12:58:23 +0100641
642
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100643static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200644tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100645{
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200646 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100647 void *ptr;
648
Benjamin Peterson2f8bfef2016-09-07 09:26:18 -0700649 assert(elsize == 0 || nelem <= SIZE_MAX / elsize);
Victor Stinnerdb067af2014-05-02 22:31:14 +0200650
651 if (use_calloc)
652 ptr = alloc->calloc(alloc->ctx, nelem, elsize);
653 else
654 ptr = alloc->malloc(alloc->ctx, nelem * elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100655 if (ptr == NULL)
656 return NULL;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100657
Victor Stinner88c29872013-12-04 01:47:46 +0100658 TABLES_LOCK();
Victor Stinnere492ae52016-03-22 12:58:23 +0100659 if (ADD_TRACE(ptr, nelem * elsize) < 0) {
Victor Stinner15116802013-12-04 01:29:35 +0100660 /* Failed to allocate a trace for the new memory block */
Victor Stinner88c29872013-12-04 01:47:46 +0100661 TABLES_UNLOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100662 alloc->free(alloc->ctx, ptr);
663 return NULL;
Victor Stinner52968672013-11-24 11:37:15 +0100664 }
Victor Stinner88c29872013-12-04 01:47:46 +0100665 TABLES_UNLOCK();
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100666 return ptr;
667}
668
Victor Stinnere492ae52016-03-22 12:58:23 +0100669
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100670static void*
Victor Stinner15116802013-12-04 01:29:35 +0100671tracemalloc_realloc(void *ctx, void *ptr, size_t new_size)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100672{
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200673 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100674 void *ptr2;
675
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100676 ptr2 = alloc->realloc(alloc->ctx, ptr, new_size);
Victor Stinner15116802013-12-04 01:29:35 +0100677 if (ptr2 == NULL)
678 return NULL;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100679
Victor Stinner15116802013-12-04 01:29:35 +0100680 if (ptr != NULL) {
681 /* an existing memory block has been resized */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100682
Victor Stinner88c29872013-12-04 01:47:46 +0100683 TABLES_LOCK();
Victor Stinner42bcf372016-03-23 09:08:08 +0100684
685 /* tracemalloc_add_trace() updates the trace if there is already
686 a trace at address (domain, ptr2) */
687 if (ptr2 != ptr) {
688 REMOVE_TRACE(ptr);
689 }
Victor Stinner08facd22013-11-24 12:27:59 +0100690
Victor Stinnere492ae52016-03-22 12:58:23 +0100691 if (ADD_TRACE(ptr2, new_size) < 0) {
Victor Stinner15116802013-12-04 01:29:35 +0100692 /* Memory allocation failed. The error cannot be reported to
Raymond Hettinger15f44ab2016-08-30 10:47:49 -0700693 the caller, because realloc() may already have shrunk the
Victor Stinner15116802013-12-04 01:29:35 +0100694 memory block and so removed bytes.
695
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +0300696 This case is very unlikely: a hash entry has just been
Victor Stinner88c29872013-12-04 01:47:46 +0100697 released, so the hash table should have at least one free entry.
698
699 The GIL and the table lock ensures that only one thread is
700 allocating memory. */
Barry Warsawb2e57942017-09-14 18:13:16 -0700701 Py_UNREACHABLE();
Victor Stinner52968672013-11-24 11:37:15 +0100702 }
Victor Stinner88c29872013-12-04 01:47:46 +0100703 TABLES_UNLOCK();
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100704 }
Victor Stinner15116802013-12-04 01:29:35 +0100705 else {
706 /* new allocation */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100707
Victor Stinner88c29872013-12-04 01:47:46 +0100708 TABLES_LOCK();
Victor Stinnere492ae52016-03-22 12:58:23 +0100709 if (ADD_TRACE(ptr2, new_size) < 0) {
Victor Stinner15116802013-12-04 01:29:35 +0100710 /* Failed to allocate a trace for the new memory block */
Victor Stinner88c29872013-12-04 01:47:46 +0100711 TABLES_UNLOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100712 alloc->free(alloc->ctx, ptr2);
713 return NULL;
714 }
Victor Stinner88c29872013-12-04 01:47:46 +0100715 TABLES_UNLOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100716 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100717 return ptr2;
718}
719
Victor Stinnere492ae52016-03-22 12:58:23 +0100720
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100721static void
722tracemalloc_free(void *ctx, void *ptr)
723{
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200724 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100725
726 if (ptr == NULL)
727 return;
728
729 /* GIL cannot be locked in PyMem_RawFree() because it would introduce
730 a deadlock in PyThreadState_DeleteCurrent(). */
731
732 alloc->free(alloc->ctx, ptr);
Victor Stinner88c29872013-12-04 01:47:46 +0100733
734 TABLES_LOCK();
Victor Stinnere492ae52016-03-22 12:58:23 +0100735 REMOVE_TRACE(ptr);
Victor Stinner88c29872013-12-04 01:47:46 +0100736 TABLES_UNLOCK();
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100737}
738
Victor Stinnere492ae52016-03-22 12:58:23 +0100739
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100740static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200741tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100742{
Victor Stinner15116802013-12-04 01:29:35 +0100743 void *ptr;
744
745 if (get_reentrant()) {
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200746 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnerdb067af2014-05-02 22:31:14 +0200747 if (use_calloc)
748 return alloc->calloc(alloc->ctx, nelem, elsize);
749 else
750 return alloc->malloc(alloc->ctx, nelem * elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100751 }
752
753 /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() for
754 allocations larger than 512 bytes, don't trace the same memory
755 allocation twice. */
756 set_reentrant(1);
757
Victor Stinnerdb067af2014-05-02 22:31:14 +0200758 ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100759
760 set_reentrant(0);
761 return ptr;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100762}
763
Victor Stinnere492ae52016-03-22 12:58:23 +0100764
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100765static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200766tracemalloc_malloc_gil(void *ctx, size_t size)
767{
768 return tracemalloc_alloc_gil(0, ctx, 1, size);
769}
770
Victor Stinnere492ae52016-03-22 12:58:23 +0100771
Victor Stinnerdb067af2014-05-02 22:31:14 +0200772static void*
773tracemalloc_calloc_gil(void *ctx, size_t nelem, size_t elsize)
774{
775 return tracemalloc_alloc_gil(1, ctx, nelem, elsize);
776}
777
Victor Stinnere492ae52016-03-22 12:58:23 +0100778
Victor Stinnerdb067af2014-05-02 22:31:14 +0200779static void*
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100780tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size)
781{
Victor Stinner15116802013-12-04 01:29:35 +0100782 void *ptr2;
783
784 if (get_reentrant()) {
785 /* Reentrant call to PyMem_Realloc() and PyMem_RawRealloc().
786 Example: PyMem_RawRealloc() is called internally by pymalloc
787 (_PyObject_Malloc() and _PyObject_Realloc()) to allocate a new
788 arena (new_arena()). */
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200789 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinner15116802013-12-04 01:29:35 +0100790
791 ptr2 = alloc->realloc(alloc->ctx, ptr, new_size);
Victor Stinner88c29872013-12-04 01:47:46 +0100792 if (ptr2 != NULL && ptr != NULL) {
793 TABLES_LOCK();
Victor Stinnere492ae52016-03-22 12:58:23 +0100794 REMOVE_TRACE(ptr);
Victor Stinner88c29872013-12-04 01:47:46 +0100795 TABLES_UNLOCK();
796 }
Victor Stinner15116802013-12-04 01:29:35 +0100797 return ptr2;
798 }
799
800 /* Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for
801 allocations larger than 512 bytes. Don't trace the same memory
802 allocation twice. */
803 set_reentrant(1);
804
805 ptr2 = tracemalloc_realloc(ctx, ptr, new_size);
806
807 set_reentrant(0);
808 return ptr2;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100809}
810
Victor Stinnere492ae52016-03-22 12:58:23 +0100811
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100812#ifdef TRACE_RAW_MALLOC
813static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200814tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100815{
Victor Stinner15116802013-12-04 01:29:35 +0100816 PyGILState_STATE gil_state;
Victor Stinner15116802013-12-04 01:29:35 +0100817 void *ptr;
818
819 if (get_reentrant()) {
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200820 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnerdb067af2014-05-02 22:31:14 +0200821 if (use_calloc)
822 return alloc->calloc(alloc->ctx, nelem, elsize);
823 else
824 return alloc->malloc(alloc->ctx, nelem * elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100825 }
826
827 /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc()
828 indirectly which would call PyGILState_Ensure() if reentrant are not
829 disabled. */
830 set_reentrant(1);
831
Victor Stinner15116802013-12-04 01:29:35 +0100832 gil_state = PyGILState_Ensure();
Victor Stinnerdb067af2014-05-02 22:31:14 +0200833 ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100834 PyGILState_Release(gil_state);
Victor Stinner15116802013-12-04 01:29:35 +0100835
836 set_reentrant(0);
837 return ptr;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100838}
839
Victor Stinnere492ae52016-03-22 12:58:23 +0100840
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100841static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200842tracemalloc_raw_malloc(void *ctx, size_t size)
843{
844 return tracemalloc_raw_alloc(0, ctx, 1, size);
845}
846
Victor Stinnere492ae52016-03-22 12:58:23 +0100847
Victor Stinnerdb067af2014-05-02 22:31:14 +0200848static void*
849tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize)
850{
851 return tracemalloc_raw_alloc(1, ctx, nelem, elsize);
852}
853
Victor Stinnere492ae52016-03-22 12:58:23 +0100854
Victor Stinnerdb067af2014-05-02 22:31:14 +0200855static void*
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100856tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size)
857{
Victor Stinner15116802013-12-04 01:29:35 +0100858 PyGILState_STATE gil_state;
Victor Stinner15116802013-12-04 01:29:35 +0100859 void *ptr2;
860
861 if (get_reentrant()) {
862 /* Reentrant call to PyMem_RawRealloc(). */
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200863 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinner15116802013-12-04 01:29:35 +0100864
865 ptr2 = alloc->realloc(alloc->ctx, ptr, new_size);
Victor Stinner15116802013-12-04 01:29:35 +0100866
Victor Stinner88c29872013-12-04 01:47:46 +0100867 if (ptr2 != NULL && ptr != NULL) {
868 TABLES_LOCK();
Victor Stinnere492ae52016-03-22 12:58:23 +0100869 REMOVE_TRACE(ptr);
Victor Stinner88c29872013-12-04 01:47:46 +0100870 TABLES_UNLOCK();
871 }
Victor Stinner15116802013-12-04 01:29:35 +0100872 return ptr2;
873 }
874
875 /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc()
876 indirectly which would call PyGILState_Ensure() if reentrant calls are
877 not disabled. */
878 set_reentrant(1);
879
Victor Stinner15116802013-12-04 01:29:35 +0100880 gil_state = PyGILState_Ensure();
881 ptr2 = tracemalloc_realloc(ctx, ptr, new_size);
882 PyGILState_Release(gil_state);
Victor Stinner15116802013-12-04 01:29:35 +0100883
884 set_reentrant(0);
885 return ptr2;
886}
887#endif /* TRACE_RAW_MALLOC */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100888
Victor Stinnere492ae52016-03-22 12:58:23 +0100889
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100890static int
Victor Stinner285cf0a2016-03-21 22:00:58 +0100891tracemalloc_clear_filename(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry,
892 void *user_data)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100893{
Victor Stinner285cf0a2016-03-21 22:00:58 +0100894 PyObject *filename;
895
Victor Stinner5dacbd42016-03-23 09:52:13 +0100896 _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, filename);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100897 Py_DECREF(filename);
898 return 0;
899}
900
Victor Stinnere492ae52016-03-22 12:58:23 +0100901
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100902static int
Victor Stinner285cf0a2016-03-21 22:00:58 +0100903traceback_free_traceback(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry,
904 void *user_data)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100905{
Victor Stinner285cf0a2016-03-21 22:00:58 +0100906 traceback_t *traceback;
907
Victor Stinner5dacbd42016-03-23 09:52:13 +0100908 _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, traceback);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100909 raw_free(traceback);
910 return 0;
911}
912
Victor Stinnere492ae52016-03-22 12:58:23 +0100913
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100914/* reentrant flag must be set to call this function and GIL must be held */
915static void
916tracemalloc_clear_traces(void)
917{
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100918 /* The GIL protects variables againt concurrent access */
919 assert(PyGILState_Check());
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100920
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100921 TABLES_LOCK();
922 _Py_hashtable_clear(tracemalloc_traces);
923 tracemalloc_traced_memory = 0;
Victor Stinner3c0481d2013-11-27 21:39:49 +0100924 tracemalloc_peak_traced_memory = 0;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100925 TABLES_UNLOCK();
926
927 _Py_hashtable_foreach(tracemalloc_tracebacks, traceback_free_traceback, NULL);
928 _Py_hashtable_clear(tracemalloc_tracebacks);
929
930 _Py_hashtable_foreach(tracemalloc_filenames, tracemalloc_clear_filename, NULL);
931 _Py_hashtable_clear(tracemalloc_filenames);
932}
933
Victor Stinnere492ae52016-03-22 12:58:23 +0100934
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100935static int
936tracemalloc_init(void)
937{
Victor Stinner9e00e802018-10-25 13:31:16 +0200938 if (_Py_tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100939 PyErr_SetString(PyExc_RuntimeError,
940 "the tracemalloc module has been unloaded");
941 return -1;
942 }
943
Victor Stinner9e00e802018-10-25 13:31:16 +0200944 if (_Py_tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100945 return 0;
946
947 PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
948
949#ifdef REENTRANT_THREADLOCAL
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900950 if (PyThread_tss_create(&tracemalloc_reentrant_key) != 0) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100951#ifdef MS_WINDOWS
952 PyErr_SetFromWindowsErr(0);
953#else
954 PyErr_SetFromErrno(PyExc_OSError);
955#endif
956 return -1;
957 }
958#endif
959
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200960#if defined(TRACE_RAW_MALLOC)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100961 if (tables_lock == NULL) {
962 tables_lock = PyThread_allocate_lock();
963 if (tables_lock == NULL) {
964 PyErr_SetString(PyExc_RuntimeError, "cannot allocate lock");
965 return -1;
966 }
967 }
968#endif
969
Victor Stinner285cf0a2016-03-21 22:00:58 +0100970 tracemalloc_filenames = hashtable_new(sizeof(PyObject *), 0,
971 hashtable_hash_pyobject,
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100972 hashtable_compare_unicode);
973
Victor Stinner285cf0a2016-03-21 22:00:58 +0100974 tracemalloc_tracebacks = hashtable_new(sizeof(traceback_t *), 0,
975 hashtable_hash_traceback,
976 hashtable_compare_traceback);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100977
Victor Stinner9e00e802018-10-25 13:31:16 +0200978 if (_Py_tracemalloc_config.use_domain) {
Victor Stinnere492ae52016-03-22 12:58:23 +0100979 tracemalloc_traces = hashtable_new(sizeof(pointer_t),
980 sizeof(trace_t),
981 hashtable_hash_pointer_t,
982 hashtable_compare_pointer_t);
983 }
984 else {
Benjamin Petersonca470632016-09-06 13:47:26 -0700985 tracemalloc_traces = hashtable_new(sizeof(uintptr_t),
Victor Stinnere492ae52016-03-22 12:58:23 +0100986 sizeof(trace_t),
987 _Py_hashtable_hash_ptr,
988 _Py_hashtable_compare_direct);
989 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100990
991 if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL
Victor Stinner285cf0a2016-03-21 22:00:58 +0100992 || tracemalloc_traces == NULL) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100993 PyErr_NoMemory();
994 return -1;
995 }
996
997 unknown_filename = PyUnicode_FromString("<unknown>");
998 if (unknown_filename == NULL)
999 return -1;
1000 PyUnicode_InternInPlace(&unknown_filename);
1001
1002 tracemalloc_empty_traceback.nframe = 1;
1003 /* borrowed reference */
1004 tracemalloc_empty_traceback.frames[0].filename = unknown_filename;
1005 tracemalloc_empty_traceback.frames[0].lineno = 0;
1006 tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback);
1007
Victor Stinner9e00e802018-10-25 13:31:16 +02001008 _Py_tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001009 return 0;
1010}
1011
Victor Stinnere492ae52016-03-22 12:58:23 +01001012
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001013static void
1014tracemalloc_deinit(void)
1015{
Victor Stinner9e00e802018-10-25 13:31:16 +02001016 if (_Py_tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001017 return;
Victor Stinner9e00e802018-10-25 13:31:16 +02001018 _Py_tracemalloc_config.initialized = TRACEMALLOC_FINALIZED;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001019
1020 tracemalloc_stop();
1021
1022 /* destroy hash tables */
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001023 _Py_hashtable_destroy(tracemalloc_tracebacks);
1024 _Py_hashtable_destroy(tracemalloc_filenames);
Victor Stinner285cf0a2016-03-21 22:00:58 +01001025 _Py_hashtable_destroy(tracemalloc_traces);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001026
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02001027#if defined(TRACE_RAW_MALLOC)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001028 if (tables_lock != NULL) {
1029 PyThread_free_lock(tables_lock);
1030 tables_lock = NULL;
1031 }
1032#endif
1033
1034#ifdef REENTRANT_THREADLOCAL
Masayuki Yamamoto731e1892017-10-06 19:41:34 +09001035 PyThread_tss_delete(&tracemalloc_reentrant_key);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001036#endif
1037
1038 Py_XDECREF(unknown_filename);
1039}
1040
Victor Stinnere492ae52016-03-22 12:58:23 +01001041
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001042static int
Victor Stinnerf28ce602013-11-27 22:27:13 +01001043tracemalloc_start(int max_nframe)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001044{
Victor Stinnerd8f0d922014-06-02 21:57:10 +02001045 PyMemAllocatorEx alloc;
Victor Stinnerf28ce602013-11-27 22:27:13 +01001046 size_t size;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001047
Victor Stinnera7368ac2017-11-15 18:11:45 -08001048 if (max_nframe < 1 || max_nframe > MAX_NFRAME) {
1049 PyErr_Format(PyExc_ValueError,
1050 "the number of frames must be in range [1; %i]",
1051 (int)MAX_NFRAME);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001052 return -1;
Victor Stinnera7368ac2017-11-15 18:11:45 -08001053 }
1054
1055 if (tracemalloc_init() < 0) {
1056 return -1;
1057 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001058
Victor Stinner9e00e802018-10-25 13:31:16 +02001059 if (_Py_tracemalloc_config.tracing) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001060 /* hook already installed: do nothing */
1061 return 0;
1062 }
1063
Victor Stinner52aee852014-08-16 15:44:02 +02001064 assert(1 <= max_nframe && max_nframe <= MAX_NFRAME);
Victor Stinner9e00e802018-10-25 13:31:16 +02001065 _Py_tracemalloc_config.max_nframe = max_nframe;
Victor Stinnerf28ce602013-11-27 22:27:13 +01001066
1067 /* allocate a buffer to store a new traceback */
1068 size = TRACEBACK_SIZE(max_nframe);
1069 assert(tracemalloc_traceback == NULL);
1070 tracemalloc_traceback = raw_malloc(size);
1071 if (tracemalloc_traceback == NULL) {
1072 PyErr_NoMemory();
1073 return -1;
1074 }
1075
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001076#ifdef TRACE_RAW_MALLOC
1077 alloc.malloc = tracemalloc_raw_malloc;
Victor Stinnerdb067af2014-05-02 22:31:14 +02001078 alloc.calloc = tracemalloc_raw_calloc;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001079 alloc.realloc = tracemalloc_raw_realloc;
1080 alloc.free = tracemalloc_free;
1081
1082 alloc.ctx = &allocators.raw;
1083 PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
1084 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc);
1085#endif
1086
1087 alloc.malloc = tracemalloc_malloc_gil;
Victor Stinnerdb067af2014-05-02 22:31:14 +02001088 alloc.calloc = tracemalloc_calloc_gil;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001089 alloc.realloc = tracemalloc_realloc_gil;
1090 alloc.free = tracemalloc_free;
1091
1092 alloc.ctx = &allocators.mem;
1093 PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem);
1094 PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc);
1095
1096 alloc.ctx = &allocators.obj;
1097 PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj);
1098 PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc);
1099
1100 /* everything is ready: start tracing Python memory allocations */
Victor Stinner9e00e802018-10-25 13:31:16 +02001101 _Py_tracemalloc_config.tracing = 1;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001102
1103 return 0;
1104}
1105
Victor Stinnere492ae52016-03-22 12:58:23 +01001106
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001107static void
1108tracemalloc_stop(void)
1109{
Victor Stinner9e00e802018-10-25 13:31:16 +02001110 if (!_Py_tracemalloc_config.tracing)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001111 return;
1112
1113 /* stop tracing Python memory allocations */
Victor Stinner9e00e802018-10-25 13:31:16 +02001114 _Py_tracemalloc_config.tracing = 0;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001115
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001116 /* unregister the hook on memory allocators */
1117#ifdef TRACE_RAW_MALLOC
1118 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
1119#endif
1120 PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem);
1121 PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj);
1122
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001123 tracemalloc_clear_traces();
Victor Stinner285cf0a2016-03-21 22:00:58 +01001124
1125 /* release memory */
Victor Stinnerf28ce602013-11-27 22:27:13 +01001126 raw_free(tracemalloc_traceback);
1127 tracemalloc_traceback = NULL;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001128}
1129
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001130
Victor Stinnere492ae52016-03-22 12:58:23 +01001131
Serhiy Storchakab451f912017-02-04 12:18:38 +02001132/*[clinic input]
1133_tracemalloc.is_tracing
1134
1135Return True if the tracemalloc module is tracing Python memory allocations.
1136[clinic start generated code]*/
1137
1138static PyObject *
1139_tracemalloc_is_tracing_impl(PyObject *module)
Serhiy Storchaka97353842017-02-05 22:58:46 +02001140/*[clinic end generated code: output=2d763b42601cd3ef input=af104b0a00192f63]*/
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001141{
Victor Stinner9e00e802018-10-25 13:31:16 +02001142 return PyBool_FromLong(_Py_tracemalloc_config.tracing);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001143}
1144
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001145
Serhiy Storchakab451f912017-02-04 12:18:38 +02001146/*[clinic input]
1147_tracemalloc.clear_traces
Victor Stinnere492ae52016-03-22 12:58:23 +01001148
Serhiy Storchakab451f912017-02-04 12:18:38 +02001149Clear traces of memory blocks allocated by Python.
1150[clinic start generated code]*/
1151
1152static PyObject *
1153_tracemalloc_clear_traces_impl(PyObject *module)
1154/*[clinic end generated code: output=a86080ee41b84197 input=0dab5b6c785183a5]*/
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001155{
Victor Stinner9e00e802018-10-25 13:31:16 +02001156 if (!_Py_tracemalloc_config.tracing)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001157 Py_RETURN_NONE;
1158
1159 set_reentrant(1);
1160 tracemalloc_clear_traces();
1161 set_reentrant(0);
1162
1163 Py_RETURN_NONE;
1164}
1165
Victor Stinnere492ae52016-03-22 12:58:23 +01001166
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001167static PyObject*
1168frame_to_pyobject(frame_t *frame)
1169{
1170 PyObject *frame_obj, *lineno_obj;
1171
1172 frame_obj = PyTuple_New(2);
1173 if (frame_obj == NULL)
1174 return NULL;
1175
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001176 Py_INCREF(frame->filename);
1177 PyTuple_SET_ITEM(frame_obj, 0, frame->filename);
1178
Victor Stinner95283342016-03-15 21:57:02 +01001179 lineno_obj = PyLong_FromUnsignedLong(frame->lineno);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001180 if (lineno_obj == NULL) {
1181 Py_DECREF(frame_obj);
1182 return NULL;
1183 }
1184 PyTuple_SET_ITEM(frame_obj, 1, lineno_obj);
1185
1186 return frame_obj;
1187}
1188
Victor Stinnere492ae52016-03-22 12:58:23 +01001189
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001190static PyObject*
1191traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table)
1192{
1193 int i;
1194 PyObject *frames, *frame;
1195
1196 if (intern_table != NULL) {
1197 if (_Py_HASHTABLE_GET(intern_table, traceback, frames)) {
1198 Py_INCREF(frames);
1199 return frames;
1200 }
1201 }
1202
1203 frames = PyTuple_New(traceback->nframe);
1204 if (frames == NULL)
1205 return NULL;
1206
1207 for (i=0; i < traceback->nframe; i++) {
1208 frame = frame_to_pyobject(&traceback->frames[i]);
1209 if (frame == NULL) {
1210 Py_DECREF(frames);
1211 return NULL;
1212 }
1213 PyTuple_SET_ITEM(frames, i, frame);
1214 }
1215
1216 if (intern_table != NULL) {
1217 if (_Py_HASHTABLE_SET(intern_table, traceback, frames) < 0) {
1218 Py_DECREF(frames);
1219 PyErr_NoMemory();
1220 return NULL;
1221 }
1222 /* intern_table keeps a new reference to frames */
1223 Py_INCREF(frames);
1224 }
1225 return frames;
1226}
1227
Victor Stinnere492ae52016-03-22 12:58:23 +01001228
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001229static PyObject*
Victor Stinner5ea4c062017-06-20 17:46:36 +02001230trace_to_pyobject(unsigned int domain, trace_t *trace,
Victor Stinnere492ae52016-03-22 12:58:23 +01001231 _Py_hashtable_t *intern_tracebacks)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001232{
1233 PyObject *trace_obj = NULL;
Victor Stinnere492ae52016-03-22 12:58:23 +01001234 PyObject *obj;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001235
Victor Stinnere492ae52016-03-22 12:58:23 +01001236 trace_obj = PyTuple_New(3);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001237 if (trace_obj == NULL)
1238 return NULL;
1239
Victor Stinnere492ae52016-03-22 12:58:23 +01001240 obj = PyLong_FromSize_t(domain);
1241 if (obj == NULL) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001242 Py_DECREF(trace_obj);
1243 return NULL;
1244 }
Victor Stinnere492ae52016-03-22 12:58:23 +01001245 PyTuple_SET_ITEM(trace_obj, 0, obj);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001246
Victor Stinnere492ae52016-03-22 12:58:23 +01001247 obj = PyLong_FromSize_t(trace->size);
1248 if (obj == NULL) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001249 Py_DECREF(trace_obj);
1250 return NULL;
1251 }
Victor Stinnere492ae52016-03-22 12:58:23 +01001252 PyTuple_SET_ITEM(trace_obj, 1, obj);
1253
1254 obj = traceback_to_pyobject(trace->traceback, intern_tracebacks);
1255 if (obj == NULL) {
1256 Py_DECREF(trace_obj);
1257 return NULL;
1258 }
1259 PyTuple_SET_ITEM(trace_obj, 2, obj);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001260
1261 return trace_obj;
1262}
1263
Victor Stinnere492ae52016-03-22 12:58:23 +01001264
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001265typedef struct {
1266 _Py_hashtable_t *traces;
1267 _Py_hashtable_t *tracebacks;
1268 PyObject *list;
1269} get_traces_t;
1270
1271static int
Victor Stinner285cf0a2016-03-21 22:00:58 +01001272tracemalloc_get_traces_fill(_Py_hashtable_t *traces, _Py_hashtable_entry_t *entry,
1273 void *user_data)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001274{
1275 get_traces_t *get_traces = user_data;
Victor Stinner5ea4c062017-06-20 17:46:36 +02001276 unsigned int domain;
Victor Stinner5dacbd42016-03-23 09:52:13 +01001277 trace_t trace;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001278 PyObject *tracemalloc_obj;
1279 int res;
1280
Victor Stinner9e00e802018-10-25 13:31:16 +02001281 if (_Py_tracemalloc_config.use_domain) {
Victor Stinnere492ae52016-03-22 12:58:23 +01001282 pointer_t key;
Victor Stinner5dacbd42016-03-23 09:52:13 +01001283 _Py_HASHTABLE_ENTRY_READ_KEY(traces, entry, key);
Victor Stinnere492ae52016-03-22 12:58:23 +01001284 domain = key.domain;
1285 }
1286 else {
1287 domain = DEFAULT_DOMAIN;
1288 }
Victor Stinner5dacbd42016-03-23 09:52:13 +01001289 _Py_HASHTABLE_ENTRY_READ_DATA(traces, entry, trace);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001290
Victor Stinner5dacbd42016-03-23 09:52:13 +01001291 tracemalloc_obj = trace_to_pyobject(domain, &trace, get_traces->tracebacks);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001292 if (tracemalloc_obj == NULL)
1293 return 1;
1294
1295 res = PyList_Append(get_traces->list, tracemalloc_obj);
1296 Py_DECREF(tracemalloc_obj);
1297 if (res < 0)
1298 return 1;
1299
1300 return 0;
1301}
1302
Victor Stinnere492ae52016-03-22 12:58:23 +01001303
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001304static int
Victor Stinner285cf0a2016-03-21 22:00:58 +01001305tracemalloc_pyobject_decref_cb(_Py_hashtable_t *tracebacks,
1306 _Py_hashtable_entry_t *entry,
1307 void *user_data)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001308{
Victor Stinnerc9553872016-03-22 12:13:01 +01001309 PyObject *obj;
Victor Stinnere8c6b2f2016-03-23 09:25:01 +01001310 _Py_HASHTABLE_ENTRY_READ_DATA(tracebacks, entry, obj);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001311 Py_DECREF(obj);
1312 return 0;
1313}
1314
Victor Stinnere492ae52016-03-22 12:58:23 +01001315
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001316
Serhiy Storchakab451f912017-02-04 12:18:38 +02001317/*[clinic input]
1318_tracemalloc._get_traces
1319
1320Get traces of all memory blocks allocated by Python.
1321
1322Return a list of (size: int, traceback: tuple) tuples.
1323traceback is a tuple of (filename: str, lineno: int) tuples.
1324
1325Return an empty list if the tracemalloc module is disabled.
1326[clinic start generated code]*/
1327
1328static PyObject *
1329_tracemalloc__get_traces_impl(PyObject *module)
1330/*[clinic end generated code: output=e9929876ced4b5cc input=6c7d2230b24255aa]*/
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001331{
1332 get_traces_t get_traces;
1333 int err;
1334
1335 get_traces.traces = NULL;
1336 get_traces.tracebacks = NULL;
1337 get_traces.list = PyList_New(0);
1338 if (get_traces.list == NULL)
1339 goto error;
1340
Victor Stinner9e00e802018-10-25 13:31:16 +02001341 if (!_Py_tracemalloc_config.tracing)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001342 return get_traces.list;
1343
Victor Stinnerde2f1322013-11-26 00:26:23 +01001344 /* the traceback hash table is used temporarily to intern traceback tuple
1345 of (filename, lineno) tuples */
Victor Stinnerc9553872016-03-22 12:13:01 +01001346 get_traces.tracebacks = hashtable_new(sizeof(traceback_t *),
1347 sizeof(PyObject *),
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001348 _Py_hashtable_hash_ptr,
1349 _Py_hashtable_compare_direct);
1350 if (get_traces.tracebacks == NULL) {
1351 PyErr_NoMemory();
1352 goto error;
1353 }
1354
1355 TABLES_LOCK();
1356 get_traces.traces = _Py_hashtable_copy(tracemalloc_traces);
1357 TABLES_UNLOCK();
1358
1359 if (get_traces.traces == NULL) {
1360 PyErr_NoMemory();
1361 goto error;
1362 }
1363
1364 set_reentrant(1);
1365 err = _Py_hashtable_foreach(get_traces.traces,
1366 tracemalloc_get_traces_fill, &get_traces);
1367 set_reentrant(0);
1368 if (err)
1369 goto error;
1370
1371 goto finally;
1372
1373error:
1374 Py_CLEAR(get_traces.list);
1375
1376finally:
1377 if (get_traces.tracebacks != NULL) {
1378 _Py_hashtable_foreach(get_traces.tracebacks,
Victor Stinner285cf0a2016-03-21 22:00:58 +01001379 tracemalloc_pyobject_decref_cb, NULL);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001380 _Py_hashtable_destroy(get_traces.tracebacks);
1381 }
Victor Stinnerc9553872016-03-22 12:13:01 +01001382 if (get_traces.traces != NULL) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001383 _Py_hashtable_destroy(get_traces.traces);
Victor Stinnerc9553872016-03-22 12:13:01 +01001384 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001385
1386 return get_traces.list;
1387}
1388
Victor Stinnere492ae52016-03-22 12:58:23 +01001389
Victor Stinner0611c262016-03-15 22:22:13 +01001390static traceback_t*
Victor Stinner5ea4c062017-06-20 17:46:36 +02001391tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr)
Victor Stinner0611c262016-03-15 22:22:13 +01001392{
1393 trace_t trace;
1394 int found;
1395
Victor Stinner9e00e802018-10-25 13:31:16 +02001396 if (!_Py_tracemalloc_config.tracing)
Victor Stinner0611c262016-03-15 22:22:13 +01001397 return NULL;
1398
1399 TABLES_LOCK();
Victor Stinner9e00e802018-10-25 13:31:16 +02001400 if (_Py_tracemalloc_config.use_domain) {
Victor Stinner10b73e12016-03-22 13:39:05 +01001401 pointer_t key = {ptr, domain};
Victor Stinnere492ae52016-03-22 12:58:23 +01001402 found = _Py_HASHTABLE_GET(tracemalloc_traces, key, trace);
1403 }
1404 else {
1405 found = _Py_HASHTABLE_GET(tracemalloc_traces, ptr, trace);
1406 }
Victor Stinner0611c262016-03-15 22:22:13 +01001407 TABLES_UNLOCK();
1408
1409 if (!found)
1410 return NULL;
1411
1412 return trace.traceback;
1413}
1414
Victor Stinnere492ae52016-03-22 12:58:23 +01001415
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001416
Serhiy Storchakab451f912017-02-04 12:18:38 +02001417/*[clinic input]
1418_tracemalloc._get_object_traceback
1419
1420 obj: object
1421 /
1422
1423Get the traceback where the Python object obj was allocated.
1424
1425Return a tuple of (filename: str, lineno: int) tuples.
1426Return None if the tracemalloc module is disabled or did not
1427trace the allocation of the object.
1428[clinic start generated code]*/
1429
1430static PyObject *
1431_tracemalloc__get_object_traceback(PyObject *module, PyObject *obj)
1432/*[clinic end generated code: output=41ee0553a658b0aa input=29495f1b21c53212]*/
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001433{
1434 PyTypeObject *type;
1435 void *ptr;
Victor Stinner0611c262016-03-15 22:22:13 +01001436 traceback_t *traceback;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001437
1438 type = Py_TYPE(obj);
Victor Stinner626bff82018-10-25 17:31:10 +02001439 if (PyType_IS_GC(type)) {
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001440 ptr = (void *)((char *)obj - sizeof(PyGC_Head));
Victor Stinner626bff82018-10-25 17:31:10 +02001441 }
1442 else {
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001443 ptr = (void *)obj;
Victor Stinner626bff82018-10-25 17:31:10 +02001444 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001445
Benjamin Petersonca470632016-09-06 13:47:26 -07001446 traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr);
Victor Stinner0611c262016-03-15 22:22:13 +01001447 if (traceback == NULL)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001448 Py_RETURN_NONE;
1449
Victor Stinner0611c262016-03-15 22:22:13 +01001450 return traceback_to_pyobject(traceback, NULL);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001451}
1452
Victor Stinnere492ae52016-03-22 12:58:23 +01001453
Victor Stinner0611c262016-03-15 22:22:13 +01001454#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str))
1455
1456static void
1457_PyMem_DumpFrame(int fd, frame_t * frame)
1458{
1459 PUTS(fd, " File \"");
1460 _Py_DumpASCII(fd, frame->filename);
1461 PUTS(fd, "\", line ");
1462 _Py_DumpDecimal(fd, frame->lineno);
1463 PUTS(fd, "\n");
1464}
1465
1466/* Dump the traceback where a memory block was allocated into file descriptor
1467 fd. The function may block on TABLES_LOCK() but it is unlikely. */
1468void
1469_PyMem_DumpTraceback(int fd, const void *ptr)
1470{
1471 traceback_t *traceback;
1472 int i;
1473
Victor Stinnerf966e532018-11-13 15:14:58 +01001474 if (!_Py_tracemalloc_config.tracing) {
1475 PUTS(fd, "Enable tracemalloc to get the memory block "
1476 "allocation traceback\n\n");
1477 return;
1478 }
1479
Benjamin Petersonca470632016-09-06 13:47:26 -07001480 traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr);
Victor Stinner0611c262016-03-15 22:22:13 +01001481 if (traceback == NULL)
1482 return;
1483
1484 PUTS(fd, "Memory block allocated at (most recent call first):\n");
1485 for (i=0; i < traceback->nframe; i++) {
1486 _PyMem_DumpFrame(fd, &traceback->frames[i]);
1487 }
1488 PUTS(fd, "\n");
1489}
1490
1491#undef PUTS
1492
Victor Stinnere492ae52016-03-22 12:58:23 +01001493
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001494
Serhiy Storchakab451f912017-02-04 12:18:38 +02001495/*[clinic input]
1496_tracemalloc.start
1497
Victor Stinnera7368ac2017-11-15 18:11:45 -08001498 nframe: int = 1
Serhiy Storchakab451f912017-02-04 12:18:38 +02001499 /
1500
1501Start tracing Python memory allocations.
1502
1503Also set the maximum number of frames stored in the traceback of a
1504trace to nframe.
1505[clinic start generated code]*/
1506
1507static PyObject *
Victor Stinnera7368ac2017-11-15 18:11:45 -08001508_tracemalloc_start_impl(PyObject *module, int nframe)
1509/*[clinic end generated code: output=caae05c23c159d3c input=40d849b5b29d1933]*/
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001510{
Victor Stinnera7368ac2017-11-15 18:11:45 -08001511 if (tracemalloc_start(nframe) < 0) {
Victor Stinner3728d6c2013-11-23 12:37:20 +01001512 return NULL;
1513 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001514 Py_RETURN_NONE;
1515}
1516
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001517
Serhiy Storchakab451f912017-02-04 12:18:38 +02001518/*[clinic input]
1519_tracemalloc.stop
Victor Stinnere492ae52016-03-22 12:58:23 +01001520
Serhiy Storchakab451f912017-02-04 12:18:38 +02001521Stop tracing Python memory allocations.
1522
1523Also clear traces of memory blocks allocated by Python.
1524[clinic start generated code]*/
1525
1526static PyObject *
1527_tracemalloc_stop_impl(PyObject *module)
1528/*[clinic end generated code: output=c3c42ae03e3955cd input=7478f075e51dae18]*/
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001529{
1530 tracemalloc_stop();
1531 Py_RETURN_NONE;
1532}
1533
Victor Stinnere492ae52016-03-22 12:58:23 +01001534
Serhiy Storchakab451f912017-02-04 12:18:38 +02001535/*[clinic input]
1536_tracemalloc.get_traceback_limit
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001537
Serhiy Storchakab451f912017-02-04 12:18:38 +02001538Get the maximum number of frames stored in the traceback of a trace.
1539
1540By default, a trace of an allocated memory block only stores
1541the most recent frame: the limit is 1.
1542[clinic start generated code]*/
1543
1544static PyObject *
1545_tracemalloc_get_traceback_limit_impl(PyObject *module)
1546/*[clinic end generated code: output=d556d9306ba95567 input=da3cd977fc68ae3b]*/
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001547{
Victor Stinner9e00e802018-10-25 13:31:16 +02001548 return PyLong_FromLong(_Py_tracemalloc_config.max_nframe);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001549}
1550
Victor Stinnere492ae52016-03-22 12:58:23 +01001551
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001552
Serhiy Storchakab451f912017-02-04 12:18:38 +02001553/*[clinic input]
1554_tracemalloc.get_tracemalloc_memory
1555
1556Get the memory usage in bytes of the tracemalloc module.
1557
1558This memory is used internally to trace memory allocations.
1559[clinic start generated code]*/
1560
1561static PyObject *
1562_tracemalloc_get_tracemalloc_memory_impl(PyObject *module)
1563/*[clinic end generated code: output=e3f14e280a55f5aa input=5d919c0f4d5132ad]*/
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001564{
1565 size_t size;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001566
1567 size = _Py_hashtable_size(tracemalloc_tracebacks);
1568 size += _Py_hashtable_size(tracemalloc_filenames);
1569
1570 TABLES_LOCK();
1571 size += _Py_hashtable_size(tracemalloc_traces);
1572 TABLES_UNLOCK();
1573
Serhiy Storchakab451f912017-02-04 12:18:38 +02001574 return PyLong_FromSize_t(size);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001575}
1576
Victor Stinnere492ae52016-03-22 12:58:23 +01001577
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001578
Serhiy Storchakab451f912017-02-04 12:18:38 +02001579/*[clinic input]
1580_tracemalloc.get_traced_memory
1581
1582Get the current size and peak size of memory blocks traced by tracemalloc.
1583
1584Returns a tuple: (current: int, peak: int).
1585[clinic start generated code]*/
1586
1587static PyObject *
1588_tracemalloc_get_traced_memory_impl(PyObject *module)
1589/*[clinic end generated code: output=5b167189adb9e782 input=61ddb5478400ff66]*/
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001590{
Victor Stinner3c0481d2013-11-27 21:39:49 +01001591 Py_ssize_t size, peak_size;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001592
Victor Stinner9e00e802018-10-25 13:31:16 +02001593 if (!_Py_tracemalloc_config.tracing)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001594 return Py_BuildValue("ii", 0, 0);
1595
1596 TABLES_LOCK();
1597 size = tracemalloc_traced_memory;
Victor Stinner3c0481d2013-11-27 21:39:49 +01001598 peak_size = tracemalloc_peak_traced_memory;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001599 TABLES_UNLOCK();
1600
Serhiy Storchakab451f912017-02-04 12:18:38 +02001601 return Py_BuildValue("nn", size, peak_size);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001602}
1603
Victor Stinnere492ae52016-03-22 12:58:23 +01001604
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001605static PyMethodDef module_methods[] = {
Serhiy Storchakab451f912017-02-04 12:18:38 +02001606 _TRACEMALLOC_IS_TRACING_METHODDEF
1607 _TRACEMALLOC_CLEAR_TRACES_METHODDEF
1608 _TRACEMALLOC__GET_TRACES_METHODDEF
1609 _TRACEMALLOC__GET_OBJECT_TRACEBACK_METHODDEF
1610 _TRACEMALLOC_START_METHODDEF
1611 _TRACEMALLOC_STOP_METHODDEF
1612 _TRACEMALLOC_GET_TRACEBACK_LIMIT_METHODDEF
1613 _TRACEMALLOC_GET_TRACEMALLOC_MEMORY_METHODDEF
1614 _TRACEMALLOC_GET_TRACED_MEMORY_METHODDEF
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001615 /* sentinel */
1616 {NULL, NULL}
1617};
1618
1619PyDoc_STRVAR(module_doc,
1620"Debug module to trace memory blocks allocated by Python.");
1621
1622static struct PyModuleDef module_def = {
1623 PyModuleDef_HEAD_INIT,
1624 "_tracemalloc",
1625 module_doc,
1626 0, /* non-negative size to be able to unload the module */
1627 module_methods,
1628 NULL,
1629};
1630
1631PyMODINIT_FUNC
1632PyInit__tracemalloc(void)
1633{
1634 PyObject *m;
1635 m = PyModule_Create(&module_def);
1636 if (m == NULL)
1637 return NULL;
1638
1639 if (tracemalloc_init() < 0)
1640 return NULL;
1641
1642 return m;
1643}
1644
Victor Stinnere492ae52016-03-22 12:58:23 +01001645
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001646int
Victor Stinnera7368ac2017-11-15 18:11:45 -08001647_PyTraceMalloc_Init(int nframe)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001648{
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001649 assert(PyGILState_Check());
Victor Stinnera7368ac2017-11-15 18:11:45 -08001650 if (nframe == 0) {
1651 return 0;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001652 }
Victor Stinnerf28ce602013-11-27 22:27:13 +01001653 return tracemalloc_start(nframe);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001654}
1655
Victor Stinnere492ae52016-03-22 12:58:23 +01001656
Victor Stinnerbe0708f2013-12-01 10:03:26 +01001657void
1658_PyTraceMalloc_Fini(void)
1659{
Victor Stinnerbe0708f2013-12-01 10:03:26 +01001660 assert(PyGILState_Check());
Victor Stinnerbe0708f2013-12-01 10:03:26 +01001661 tracemalloc_deinit();
1662}
Victor Stinner10b73e12016-03-22 13:39:05 +01001663
1664int
Victor Stinner5ea4c062017-06-20 17:46:36 +02001665PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
1666 size_t size)
Victor Stinner10b73e12016-03-22 13:39:05 +01001667{
1668 int res;
Victor Stinner10b73e12016-03-22 13:39:05 +01001669 PyGILState_STATE gil_state;
Victor Stinner10b73e12016-03-22 13:39:05 +01001670
Victor Stinner9e00e802018-10-25 13:31:16 +02001671 if (!_Py_tracemalloc_config.tracing) {
Victor Stinner10b73e12016-03-22 13:39:05 +01001672 /* tracemalloc is not tracing: do nothing */
1673 return -2;
1674 }
1675
Victor Stinner10b73e12016-03-22 13:39:05 +01001676 gil_state = PyGILState_Ensure();
Victor Stinner10b73e12016-03-22 13:39:05 +01001677
1678 TABLES_LOCK();
1679 res = tracemalloc_add_trace(domain, ptr, size);
1680 TABLES_UNLOCK();
1681
Victor Stinner10b73e12016-03-22 13:39:05 +01001682 PyGILState_Release(gil_state);
Victor Stinner10b73e12016-03-22 13:39:05 +01001683 return res;
1684}
1685
1686
1687int
Victor Stinner5ea4c062017-06-20 17:46:36 +02001688PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
Victor Stinner10b73e12016-03-22 13:39:05 +01001689{
Victor Stinner9e00e802018-10-25 13:31:16 +02001690 if (!_Py_tracemalloc_config.tracing) {
Victor Stinner10b73e12016-03-22 13:39:05 +01001691 /* tracemalloc is not tracing: do nothing */
1692 return -2;
1693 }
1694
1695 TABLES_LOCK();
1696 tracemalloc_remove_trace(domain, ptr);
1697 TABLES_UNLOCK();
1698
1699 return 0;
1700}
1701
1702
Victor Stinner9e00e802018-10-25 13:31:16 +02001703/* If the object memory block is already traced, update its trace
1704 with the current Python traceback.
1705
1706 Do nothing if tracemalloc is not tracing memory allocations
1707 or if the object memory block is not already traced. */
1708int
1709_PyTraceMalloc_NewReference(PyObject *op)
1710{
1711 assert(PyGILState_Check());
1712
1713 if (!_Py_tracemalloc_config.tracing) {
1714 /* tracemalloc is not tracing: do nothing */
1715 return -1;
1716 }
1717
1718 uintptr_t ptr;
1719 PyTypeObject *type = Py_TYPE(op);
1720 if (PyType_IS_GC(type)) {
1721 ptr = (uintptr_t)((char *)op - sizeof(PyGC_Head));
1722 }
1723 else {
1724 ptr = (uintptr_t)op;
1725 }
1726
1727 _Py_hashtable_entry_t* entry;
1728 int res = -1;
1729
1730 TABLES_LOCK();
1731 if (_Py_tracemalloc_config.use_domain) {
1732 pointer_t key = {ptr, DEFAULT_DOMAIN};
1733 entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, key);
1734 }
1735 else {
1736 entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, ptr);
1737 }
1738
1739 if (entry != NULL) {
1740 /* update the traceback of the memory block */
1741 traceback_t *traceback = traceback_new();
1742 if (traceback != NULL) {
1743 trace_t trace;
1744 _Py_HASHTABLE_ENTRY_READ_DATA(tracemalloc_traces, entry, trace);
1745 trace.traceback = traceback;
1746 _Py_HASHTABLE_ENTRY_WRITE_DATA(tracemalloc_traces, entry, trace);
1747 res = 0;
1748 }
1749 }
1750 /* else: cannot track the object, its memory block size is unknown */
1751 TABLES_UNLOCK();
1752
1753 return res;
1754}
1755
1756
Victor Stinner10b73e12016-03-22 13:39:05 +01001757PyObject*
Victor Stinner5ea4c062017-06-20 17:46:36 +02001758_PyTraceMalloc_GetTraceback(unsigned int domain, uintptr_t ptr)
Victor Stinner10b73e12016-03-22 13:39:05 +01001759{
1760 traceback_t *traceback;
1761
1762 traceback = tracemalloc_get_traceback(domain, ptr);
1763 if (traceback == NULL)
1764 Py_RETURN_NONE;
1765
1766 return traceback_to_pyobject(traceback, NULL);
1767}