blob: 5752904d4779840ff6ee14ca4437bfac7706ab5b [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
7/* Trace memory blocks allocated by PyMem_RawMalloc() */
8#define TRACE_RAW_MALLOC
9
10/* Forward declaration */
11static void tracemalloc_stop(void);
Victor Stinnered3b0bc2013-11-23 12:27:24 +010012static void* raw_malloc(size_t size);
13static void raw_free(void *ptr);
14
15#ifdef Py_DEBUG
16# define TRACE_DEBUG
17#endif
18
Victor Stinnered3b0bc2013-11-23 12:27:24 +010019/* Protected by the GIL */
20static struct {
Victor Stinnerd8f0d922014-06-02 21:57:10 +020021 PyMemAllocatorEx mem;
22 PyMemAllocatorEx raw;
23 PyMemAllocatorEx obj;
Victor Stinnered3b0bc2013-11-23 12:27:24 +010024} allocators;
25
Victor Stinnered3b0bc2013-11-23 12:27:24 +010026static struct {
27 /* Module initialized?
28 Variable protected by the GIL */
29 enum {
30 TRACEMALLOC_NOT_INITIALIZED,
31 TRACEMALLOC_INITIALIZED,
32 TRACEMALLOC_FINALIZED
33 } initialized;
34
Victor Stinnered3b0bc2013-11-23 12:27:24 +010035 /* Is tracemalloc tracing memory allocations?
36 Variable protected by the GIL */
37 int tracing;
38
39 /* limit of the number of frames in a traceback, 1 by default.
40 Variable protected by the GIL. */
41 int max_nframe;
Victor Stinnerbe0708f2013-12-01 10:03:26 +010042} tracemalloc_config = {TRACEMALLOC_NOT_INITIALIZED, 0, 1};
Victor Stinnered3b0bc2013-11-23 12:27:24 +010043
44#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD)
45/* This lock is needed because tracemalloc_free() is called without
46 the GIL held from PyMem_RawFree(). It cannot acquire the lock because it
47 would introduce a deadlock in PyThreadState_DeleteCurrent(). */
48static PyThread_type_lock tables_lock;
49# define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1)
50# define TABLES_UNLOCK() PyThread_release_lock(tables_lock)
51#else
52 /* variables are protected by the GIL */
53# define TABLES_LOCK()
54# define TABLES_UNLOCK()
55#endif
56
57/* Pack the frame_t structure to reduce the memory footprint on 64-bit
58 architectures: 12 bytes instead of 16. This optimization might produce
59 SIGBUS on architectures not supporting unaligned memory accesses (64-bit
Victor Stinner444f1242015-03-18 16:05:18 +010060 MIPS CPU?): on such architecture, the structure must not be packed. */
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)
65_declspec(align(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;
73
74typedef struct {
75 Py_uhash_t hash;
76 int nframe;
77 frame_t frames[1];
78} traceback_t;
79
80#define TRACEBACK_SIZE(NFRAME) \
81 (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1))
Victor Stinnerf28ce602013-11-27 22:27:13 +010082
83#define MAX_NFRAME \
Victor Stinner52aee852014-08-16 15:44:02 +020084 ((INT_MAX - (int)sizeof(traceback_t)) / (int)sizeof(frame_t) + 1)
Victor Stinnered3b0bc2013-11-23 12:27:24 +010085
86static PyObject *unknown_filename = NULL;
87static traceback_t tracemalloc_empty_traceback;
88
Victor Stinner7a5be142013-11-26 01:06:02 +010089/* Trace of a memory block */
Victor Stinnered3b0bc2013-11-23 12:27:24 +010090typedef struct {
Victor Stinner7a5be142013-11-26 01:06:02 +010091 /* Size of the memory block in bytes */
Victor Stinnered3b0bc2013-11-23 12:27:24 +010092 size_t size;
Victor Stinner7a5be142013-11-26 01:06:02 +010093
94 /* Traceback where the memory block was allocated */
Victor Stinnered3b0bc2013-11-23 12:27:24 +010095 traceback_t *traceback;
96} trace_t;
97
98/* Size in bytes of currently traced memory.
99 Protected by TABLES_LOCK(). */
100static size_t tracemalloc_traced_memory = 0;
101
Victor Stinner3c0481d2013-11-27 21:39:49 +0100102/* Peak size in bytes of traced memory.
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100103 Protected by TABLES_LOCK(). */
Victor Stinner3c0481d2013-11-27 21:39:49 +0100104static size_t tracemalloc_peak_traced_memory = 0;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100105
Serhiy Storchaka56a6d852014-12-01 18:28:43 +0200106/* Hash table used as a set to intern filenames:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100107 PyObject* => PyObject*.
108 Protected by the GIL */
109static _Py_hashtable_t *tracemalloc_filenames = NULL;
110
Victor Stinnerf28ce602013-11-27 22:27:13 +0100111/* Buffer to store a new traceback in traceback_new().
112 Protected by the GIL. */
113static traceback_t *tracemalloc_traceback = NULL;
114
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100115/* Hash table used as a set to intern tracebacks:
116 traceback_t* => traceback_t*
117 Protected by the GIL */
118static _Py_hashtable_t *tracemalloc_tracebacks = NULL;
119
120/* pointer (void*) => trace (trace_t).
121 Protected by TABLES_LOCK(). */
122static _Py_hashtable_t *tracemalloc_traces = NULL;
123
124#ifdef TRACE_DEBUG
125static void
126tracemalloc_error(const char *format, ...)
127{
128 va_list ap;
129 fprintf(stderr, "tracemalloc: ");
130 va_start(ap, format);
131 vfprintf(stderr, format, ap);
132 va_end(ap);
133 fprintf(stderr, "\n");
134 fflush(stderr);
135}
136#endif
137
138#if defined(WITH_THREAD) && defined(TRACE_RAW_MALLOC)
139#define REENTRANT_THREADLOCAL
140
141/* If your OS does not provide native thread local storage, you can implement
142 it manually using a lock. Functions of thread.c cannot be used because
143 they use PyMem_RawMalloc() which leads to a reentrant call. */
144#if !(defined(_POSIX_THREADS) || defined(NT_THREADS))
145# error "need native thread local storage (TLS)"
146#endif
147
148static int tracemalloc_reentrant_key;
149
150/* Any non-NULL pointer can be used */
151#define REENTRANT Py_True
152
153static int
154get_reentrant(void)
155{
156 void *ptr = PyThread_get_key_value(tracemalloc_reentrant_key);
157 if (ptr != NULL) {
158 assert(ptr == REENTRANT);
159 return 1;
160 }
161 else
162 return 0;
163}
164
165static void
166set_reentrant(int reentrant)
167{
Victor Stinner2ead3d22013-11-26 01:08:53 +0100168 assert(reentrant == 0 || reentrant == 1);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100169 if (reentrant) {
170 assert(PyThread_get_key_value(tracemalloc_reentrant_key) == NULL);
Victor Stinner590cebe2013-12-13 11:08:56 +0100171 PyThread_set_key_value(tracemalloc_reentrant_key, REENTRANT);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100172 }
173 else {
Victor Stinner590cebe2013-12-13 11:08:56 +0100174 assert(PyThread_get_key_value(tracemalloc_reentrant_key) == REENTRANT);
175 PyThread_set_key_value(tracemalloc_reentrant_key, NULL);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100176 }
177}
178
179#else
180
181/* WITH_THREAD not defined: Python compiled without threads,
182 or TRACE_RAW_MALLOC not defined: variable protected by the GIL */
183static int tracemalloc_reentrant = 0;
184
185static int
186get_reentrant(void)
187{
188 return tracemalloc_reentrant;
189}
190
191static void
192set_reentrant(int reentrant)
193{
194 assert(!reentrant || !get_reentrant());
195 tracemalloc_reentrant = reentrant;
196}
197#endif
198
199static int
200hashtable_compare_unicode(const void *key, const _Py_hashtable_entry_t *entry)
201{
202 if (key != NULL && entry->key != NULL)
203 return (PyUnicode_Compare((PyObject *)key, (PyObject *)entry->key) == 0);
204 else
205 return key == entry->key;
206}
207
208static _Py_hashtable_allocator_t hashtable_alloc = {malloc, free};
209
210static _Py_hashtable_t *
211hashtable_new(size_t data_size,
212 _Py_hashtable_hash_func hash_func,
213 _Py_hashtable_compare_func compare_func)
214{
215 return _Py_hashtable_new_full(data_size, 0,
216 hash_func, compare_func,
217 NULL, NULL, NULL, &hashtable_alloc);
218}
219
220static void*
221raw_malloc(size_t size)
222{
223 return allocators.raw.malloc(allocators.raw.ctx, size);
224}
225
226static void
227raw_free(void *ptr)
228{
229 allocators.raw.free(allocators.raw.ctx, ptr);
230}
231
232static Py_uhash_t
233hashtable_hash_traceback(const void *key)
234{
235 const traceback_t *traceback = key;
236 return traceback->hash;
237}
238
239static int
240hashtable_compare_traceback(const traceback_t *traceback1,
241 const _Py_hashtable_entry_t *he)
242{
243 const traceback_t *traceback2 = he->key;
244 const frame_t *frame1, *frame2;
245 int i;
246
247 if (traceback1->nframe != traceback2->nframe)
248 return 0;
249
250 for (i=0; i < traceback1->nframe; i++) {
251 frame1 = &traceback1->frames[i];
252 frame2 = &traceback2->frames[i];
253
254 if (frame1->lineno != frame2->lineno)
255 return 0;
256
257 if (frame1->filename != frame2->filename) {
258 assert(PyUnicode_Compare(frame1->filename, frame2->filename) != 0);
259 return 0;
260 }
261 }
262 return 1;
263}
264
265static void
266tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame)
267{
268 PyCodeObject *code;
269 PyObject *filename;
270 _Py_hashtable_entry_t *entry;
Victor Stinner95283342016-03-15 21:57:02 +0100271 int lineno;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100272
273 frame->filename = unknown_filename;
Victor Stinner95283342016-03-15 21:57:02 +0100274 lineno = PyFrame_GetLineNumber(pyframe);
275 if (lineno < 0)
276 lineno = 0;
277 frame->lineno = (unsigned int)lineno;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100278
279 code = pyframe->f_code;
280 if (code == NULL) {
281#ifdef TRACE_DEBUG
Victor Stinner4dc74202013-11-26 01:18:52 +0100282 tracemalloc_error("failed to get the code object of the frame");
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100283#endif
284 return;
285 }
286
287 if (code->co_filename == NULL) {
288#ifdef TRACE_DEBUG
289 tracemalloc_error("failed to get the filename of the code object");
290#endif
291 return;
292 }
293
294 filename = code->co_filename;
295 assert(filename != NULL);
296 if (filename == NULL)
297 return;
298
299 if (!PyUnicode_Check(filename)) {
300#ifdef TRACE_DEBUG
301 tracemalloc_error("filename is not an unicode string");
302#endif
303 return;
304 }
305 if (!PyUnicode_IS_READY(filename)) {
306 /* Don't make a Unicode string ready to avoid reentrant calls
307 to tracemalloc_malloc() or tracemalloc_realloc() */
308#ifdef TRACE_DEBUG
309 tracemalloc_error("filename is not a ready unicode string");
310#endif
311 return;
312 }
313
314 /* intern the filename */
315 entry = _Py_hashtable_get_entry(tracemalloc_filenames, filename);
316 if (entry != NULL) {
317 filename = (PyObject *)entry->key;
318 }
319 else {
320 /* tracemalloc_filenames is responsible to keep a reference
321 to the filename */
322 Py_INCREF(filename);
323 if (_Py_hashtable_set(tracemalloc_filenames, filename, NULL, 0) < 0) {
324 Py_DECREF(filename);
325#ifdef TRACE_DEBUG
326 tracemalloc_error("failed to intern the filename");
327#endif
328 return;
329 }
330 }
331
332 /* the tracemalloc_filenames table keeps a reference to the filename */
333 frame->filename = filename;
334}
335
336static Py_uhash_t
337traceback_hash(traceback_t *traceback)
338{
339 /* code based on tuplehash() of Objects/tupleobject.c */
Victor Stinner4d8c29c2013-12-16 23:05:13 +0100340 Py_uhash_t x, y; /* Unsigned for defined overflow behavior. */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100341 int len = traceback->nframe;
342 Py_uhash_t mult = _PyHASH_MULTIPLIER;
343 frame_t *frame;
344
345 x = 0x345678UL;
346 frame = traceback->frames;
347 while (--len >= 0) {
Victor Stinner4d8c29c2013-12-16 23:05:13 +0100348 y = (Py_uhash_t)PyObject_Hash(frame->filename);
349 y ^= (Py_uhash_t)frame->lineno;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100350 frame++;
351
352 x = (x ^ y) * mult;
353 /* the cast might truncate len; that doesn't change hash stability */
Victor Stinner4d8c29c2013-12-16 23:05:13 +0100354 mult += (Py_uhash_t)(82520UL + len + len);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100355 }
356 x += 97531UL;
357 return x;
358}
359
360static void
361traceback_get_frames(traceback_t *traceback)
362{
363 PyThreadState *tstate;
364 PyFrameObject *pyframe;
365
366#ifdef WITH_THREAD
367 tstate = PyGILState_GetThisThreadState();
368#else
369 tstate = PyThreadState_Get();
370#endif
371 if (tstate == NULL) {
372#ifdef TRACE_DEBUG
373 tracemalloc_error("failed to get the current thread state");
374#endif
375 return;
376 }
377
378 for (pyframe = tstate->frame; pyframe != NULL; pyframe = pyframe->f_back) {
379 tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]);
380 assert(traceback->frames[traceback->nframe].filename != NULL);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100381 traceback->nframe++;
382 if (traceback->nframe == tracemalloc_config.max_nframe)
383 break;
384 }
385}
386
387static traceback_t *
388traceback_new(void)
389{
Victor Stinnerf28ce602013-11-27 22:27:13 +0100390 traceback_t *traceback;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100391 _Py_hashtable_entry_t *entry;
392
393#ifdef WITH_THREAD
394 assert(PyGILState_Check());
395#endif
396
397 /* get frames */
Victor Stinnerf28ce602013-11-27 22:27:13 +0100398 traceback = tracemalloc_traceback;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100399 traceback->nframe = 0;
400 traceback_get_frames(traceback);
401 if (traceback->nframe == 0)
402 return &tracemalloc_empty_traceback;
403 traceback->hash = traceback_hash(traceback);
404
405 /* intern the traceback */
406 entry = _Py_hashtable_get_entry(tracemalloc_tracebacks, traceback);
407 if (entry != NULL) {
408 traceback = (traceback_t *)entry->key;
409 }
410 else {
411 traceback_t *copy;
412 size_t traceback_size;
413
414 traceback_size = TRACEBACK_SIZE(traceback->nframe);
415
416 copy = raw_malloc(traceback_size);
417 if (copy == NULL) {
418#ifdef TRACE_DEBUG
419 tracemalloc_error("failed to intern the traceback: malloc failed");
420#endif
421 return NULL;
422 }
423 memcpy(copy, traceback, traceback_size);
424
425 if (_Py_hashtable_set(tracemalloc_tracebacks, copy, NULL, 0) < 0) {
426 raw_free(copy);
427#ifdef TRACE_DEBUG
428 tracemalloc_error("failed to intern the traceback: putdata failed");
429#endif
430 return NULL;
431 }
432 traceback = copy;
433 }
434 return traceback;
435}
436
Victor Stinner52968672013-11-24 11:37:15 +0100437static int
Victor Stinner15116802013-12-04 01:29:35 +0100438tracemalloc_add_trace(void *ptr, size_t size)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100439{
440 traceback_t *traceback;
441 trace_t trace;
Victor Stinner52968672013-11-24 11:37:15 +0100442 int res;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100443
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100444 traceback = traceback_new();
Victor Stinner52968672013-11-24 11:37:15 +0100445 if (traceback == NULL)
446 return -1;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100447
448 trace.size = size;
449 trace.traceback = traceback;
450
Victor Stinner52968672013-11-24 11:37:15 +0100451 res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace);
452 if (res == 0) {
Victor Stinnerd606ba72013-11-24 11:28:20 +0100453 assert(tracemalloc_traced_memory <= PY_SIZE_MAX - size);
454 tracemalloc_traced_memory += size;
Victor Stinner3c0481d2013-11-27 21:39:49 +0100455 if (tracemalloc_traced_memory > tracemalloc_peak_traced_memory)
456 tracemalloc_peak_traced_memory = tracemalloc_traced_memory;
Victor Stinnerd606ba72013-11-24 11:28:20 +0100457 }
Victor Stinner52968672013-11-24 11:37:15 +0100458
459 return res;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100460}
461
462static void
Victor Stinner15116802013-12-04 01:29:35 +0100463tracemalloc_remove_trace(void *ptr)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100464{
465 trace_t trace;
466
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100467 if (_Py_hashtable_pop(tracemalloc_traces, ptr, &trace, sizeof(trace))) {
468 assert(tracemalloc_traced_memory >= trace.size);
469 tracemalloc_traced_memory -= trace.size;
470 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100471}
472
473static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200474tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100475{
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200476 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100477 void *ptr;
478
Victor Stinneraa0e7af2014-06-02 21:40:22 +0200479 assert(elsize == 0 || nelem <= PY_SIZE_MAX / elsize);
Victor Stinnerdb067af2014-05-02 22:31:14 +0200480
481 if (use_calloc)
482 ptr = alloc->calloc(alloc->ctx, nelem, elsize);
483 else
484 ptr = alloc->malloc(alloc->ctx, nelem * elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100485 if (ptr == NULL)
486 return NULL;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100487
Victor Stinner88c29872013-12-04 01:47:46 +0100488 TABLES_LOCK();
Victor Stinnerdb067af2014-05-02 22:31:14 +0200489 if (tracemalloc_add_trace(ptr, nelem * elsize) < 0) {
Victor Stinner15116802013-12-04 01:29:35 +0100490 /* Failed to allocate a trace for the new memory block */
Victor Stinner88c29872013-12-04 01:47:46 +0100491 TABLES_UNLOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100492 alloc->free(alloc->ctx, ptr);
493 return NULL;
Victor Stinner52968672013-11-24 11:37:15 +0100494 }
Victor Stinner88c29872013-12-04 01:47:46 +0100495 TABLES_UNLOCK();
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100496 return ptr;
497}
498
499static void*
Victor Stinner15116802013-12-04 01:29:35 +0100500tracemalloc_realloc(void *ctx, void *ptr, size_t new_size)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100501{
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200502 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100503 void *ptr2;
504
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100505 ptr2 = alloc->realloc(alloc->ctx, ptr, new_size);
Victor Stinner15116802013-12-04 01:29:35 +0100506 if (ptr2 == NULL)
507 return NULL;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100508
Victor Stinner15116802013-12-04 01:29:35 +0100509 if (ptr != NULL) {
510 /* an existing memory block has been resized */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100511
Victor Stinner88c29872013-12-04 01:47:46 +0100512 TABLES_LOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100513 tracemalloc_remove_trace(ptr);
Victor Stinner08facd22013-11-24 12:27:59 +0100514
Victor Stinner15116802013-12-04 01:29:35 +0100515 if (tracemalloc_add_trace(ptr2, new_size) < 0) {
516 /* Memory allocation failed. The error cannot be reported to
517 the caller, because realloc() may already have shrinked the
518 memory block and so removed bytes.
519
Victor Stinner88c29872013-12-04 01:47:46 +0100520 This case is very unlikely: an hash entry has just been
521 released, so the hash table should have at least one free entry.
522
523 The GIL and the table lock ensures that only one thread is
524 allocating memory. */
525 assert(0 && "should never happen");
Victor Stinner52968672013-11-24 11:37:15 +0100526 }
Victor Stinner88c29872013-12-04 01:47:46 +0100527 TABLES_UNLOCK();
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100528 }
Victor Stinner15116802013-12-04 01:29:35 +0100529 else {
530 /* new allocation */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100531
Victor Stinner88c29872013-12-04 01:47:46 +0100532 TABLES_LOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100533 if (tracemalloc_add_trace(ptr2, new_size) < 0) {
534 /* Failed to allocate a trace for the new memory block */
Victor Stinner88c29872013-12-04 01:47:46 +0100535 TABLES_UNLOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100536 alloc->free(alloc->ctx, ptr2);
537 return NULL;
538 }
Victor Stinner88c29872013-12-04 01:47:46 +0100539 TABLES_UNLOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100540 }
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100541 return ptr2;
542}
543
544static void
545tracemalloc_free(void *ctx, void *ptr)
546{
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200547 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100548
549 if (ptr == NULL)
550 return;
551
552 /* GIL cannot be locked in PyMem_RawFree() because it would introduce
553 a deadlock in PyThreadState_DeleteCurrent(). */
554
555 alloc->free(alloc->ctx, ptr);
Victor Stinner88c29872013-12-04 01:47:46 +0100556
557 TABLES_LOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100558 tracemalloc_remove_trace(ptr);
Victor Stinner88c29872013-12-04 01:47:46 +0100559 TABLES_UNLOCK();
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100560}
561
562static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200563tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100564{
Victor Stinner15116802013-12-04 01:29:35 +0100565 void *ptr;
566
567 if (get_reentrant()) {
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200568 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnerdb067af2014-05-02 22:31:14 +0200569 if (use_calloc)
570 return alloc->calloc(alloc->ctx, nelem, elsize);
571 else
572 return alloc->malloc(alloc->ctx, nelem * elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100573 }
574
575 /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() for
576 allocations larger than 512 bytes, don't trace the same memory
577 allocation twice. */
578 set_reentrant(1);
579
Victor Stinnerdb067af2014-05-02 22:31:14 +0200580 ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100581
582 set_reentrant(0);
583 return ptr;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100584}
585
586static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200587tracemalloc_malloc_gil(void *ctx, size_t size)
588{
589 return tracemalloc_alloc_gil(0, ctx, 1, size);
590}
591
592static void*
593tracemalloc_calloc_gil(void *ctx, size_t nelem, size_t elsize)
594{
595 return tracemalloc_alloc_gil(1, ctx, nelem, elsize);
596}
597
598static void*
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100599tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size)
600{
Victor Stinner15116802013-12-04 01:29:35 +0100601 void *ptr2;
602
603 if (get_reentrant()) {
604 /* Reentrant call to PyMem_Realloc() and PyMem_RawRealloc().
605 Example: PyMem_RawRealloc() is called internally by pymalloc
606 (_PyObject_Malloc() and _PyObject_Realloc()) to allocate a new
607 arena (new_arena()). */
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200608 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinner15116802013-12-04 01:29:35 +0100609
610 ptr2 = alloc->realloc(alloc->ctx, ptr, new_size);
Victor Stinner88c29872013-12-04 01:47:46 +0100611 if (ptr2 != NULL && ptr != NULL) {
612 TABLES_LOCK();
Victor Stinner15116802013-12-04 01:29:35 +0100613 tracemalloc_remove_trace(ptr);
Victor Stinner88c29872013-12-04 01:47:46 +0100614 TABLES_UNLOCK();
615 }
Victor Stinner15116802013-12-04 01:29:35 +0100616 return ptr2;
617 }
618
619 /* Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for
620 allocations larger than 512 bytes. Don't trace the same memory
621 allocation twice. */
622 set_reentrant(1);
623
624 ptr2 = tracemalloc_realloc(ctx, ptr, new_size);
625
626 set_reentrant(0);
627 return ptr2;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100628}
629
630#ifdef TRACE_RAW_MALLOC
631static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200632tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100633{
Victor Stinner15116802013-12-04 01:29:35 +0100634#ifdef WITH_THREAD
635 PyGILState_STATE gil_state;
636#endif
637 void *ptr;
638
639 if (get_reentrant()) {
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200640 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinnerdb067af2014-05-02 22:31:14 +0200641 if (use_calloc)
642 return alloc->calloc(alloc->ctx, nelem, elsize);
643 else
644 return alloc->malloc(alloc->ctx, nelem * elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100645 }
646
647 /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc()
648 indirectly which would call PyGILState_Ensure() if reentrant are not
649 disabled. */
650 set_reentrant(1);
651
652#ifdef WITH_THREAD
653 gil_state = PyGILState_Ensure();
Victor Stinnerdb067af2014-05-02 22:31:14 +0200654 ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100655 PyGILState_Release(gil_state);
656#else
Victor Stinnerdb067af2014-05-02 22:31:14 +0200657 ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize);
Victor Stinner15116802013-12-04 01:29:35 +0100658#endif
659
660 set_reentrant(0);
661 return ptr;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100662}
663
664static void*
Victor Stinnerdb067af2014-05-02 22:31:14 +0200665tracemalloc_raw_malloc(void *ctx, size_t size)
666{
667 return tracemalloc_raw_alloc(0, ctx, 1, size);
668}
669
670static void*
671tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize)
672{
673 return tracemalloc_raw_alloc(1, ctx, nelem, elsize);
674}
675
676static void*
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100677tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size)
678{
Victor Stinner15116802013-12-04 01:29:35 +0100679#ifdef WITH_THREAD
680 PyGILState_STATE gil_state;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100681#endif
Victor Stinner15116802013-12-04 01:29:35 +0100682 void *ptr2;
683
684 if (get_reentrant()) {
685 /* Reentrant call to PyMem_RawRealloc(). */
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200686 PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
Victor Stinner15116802013-12-04 01:29:35 +0100687
688 ptr2 = alloc->realloc(alloc->ctx, ptr, new_size);
Victor Stinner15116802013-12-04 01:29:35 +0100689
Victor Stinner88c29872013-12-04 01:47:46 +0100690 if (ptr2 != NULL && ptr != NULL) {
691 TABLES_LOCK();
692 tracemalloc_remove_trace(ptr);
693 TABLES_UNLOCK();
694 }
Victor Stinner15116802013-12-04 01:29:35 +0100695 return ptr2;
696 }
697
698 /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc()
699 indirectly which would call PyGILState_Ensure() if reentrant calls are
700 not disabled. */
701 set_reentrant(1);
702
703#ifdef WITH_THREAD
704 gil_state = PyGILState_Ensure();
705 ptr2 = tracemalloc_realloc(ctx, ptr, new_size);
706 PyGILState_Release(gil_state);
707#else
708 ptr2 = tracemalloc_realloc(ctx, ptr, new_size);
709#endif
710
711 set_reentrant(0);
712 return ptr2;
713}
714#endif /* TRACE_RAW_MALLOC */
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100715
716static int
717tracemalloc_clear_filename(_Py_hashtable_entry_t *entry, void *user_data)
718{
719 PyObject *filename = (PyObject *)entry->key;
720 Py_DECREF(filename);
721 return 0;
722}
723
724static int
725traceback_free_traceback(_Py_hashtable_entry_t *entry, void *user_data)
726{
727 traceback_t *traceback = (traceback_t *)entry->key;
728 raw_free(traceback);
729 return 0;
730}
731
732/* reentrant flag must be set to call this function and GIL must be held */
733static void
734tracemalloc_clear_traces(void)
735{
736#ifdef WITH_THREAD
737 /* The GIL protects variables againt concurrent access */
738 assert(PyGILState_Check());
739#endif
740
741 /* Disable also reentrant calls to tracemalloc_malloc() to not add a new
742 trace while we are clearing traces */
743 assert(get_reentrant());
744
745 TABLES_LOCK();
746 _Py_hashtable_clear(tracemalloc_traces);
747 tracemalloc_traced_memory = 0;
Victor Stinner3c0481d2013-11-27 21:39:49 +0100748 tracemalloc_peak_traced_memory = 0;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100749 TABLES_UNLOCK();
750
751 _Py_hashtable_foreach(tracemalloc_tracebacks, traceback_free_traceback, NULL);
752 _Py_hashtable_clear(tracemalloc_tracebacks);
753
754 _Py_hashtable_foreach(tracemalloc_filenames, tracemalloc_clear_filename, NULL);
755 _Py_hashtable_clear(tracemalloc_filenames);
756}
757
758static int
759tracemalloc_init(void)
760{
761 if (tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) {
762 PyErr_SetString(PyExc_RuntimeError,
763 "the tracemalloc module has been unloaded");
764 return -1;
765 }
766
767 if (tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED)
768 return 0;
769
770 PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
771
772#ifdef REENTRANT_THREADLOCAL
773 tracemalloc_reentrant_key = PyThread_create_key();
774 if (tracemalloc_reentrant_key == -1) {
775#ifdef MS_WINDOWS
776 PyErr_SetFromWindowsErr(0);
777#else
778 PyErr_SetFromErrno(PyExc_OSError);
779#endif
780 return -1;
781 }
782#endif
783
784#if defined(WITH_THREAD) && defined(TRACE_RAW_MALLOC)
785 if (tables_lock == NULL) {
786 tables_lock = PyThread_allocate_lock();
787 if (tables_lock == NULL) {
788 PyErr_SetString(PyExc_RuntimeError, "cannot allocate lock");
789 return -1;
790 }
791 }
792#endif
793
794 tracemalloc_filenames = hashtable_new(0,
795 (_Py_hashtable_hash_func)PyObject_Hash,
796 hashtable_compare_unicode);
797
798 tracemalloc_tracebacks = hashtable_new(0,
799 (_Py_hashtable_hash_func)hashtable_hash_traceback,
800 (_Py_hashtable_compare_func)hashtable_compare_traceback);
801
802 tracemalloc_traces = hashtable_new(sizeof(trace_t),
803 _Py_hashtable_hash_ptr,
804 _Py_hashtable_compare_direct);
805
806 if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL
807 || tracemalloc_traces == NULL)
808 {
809 PyErr_NoMemory();
810 return -1;
811 }
812
813 unknown_filename = PyUnicode_FromString("<unknown>");
814 if (unknown_filename == NULL)
815 return -1;
816 PyUnicode_InternInPlace(&unknown_filename);
817
818 tracemalloc_empty_traceback.nframe = 1;
819 /* borrowed reference */
820 tracemalloc_empty_traceback.frames[0].filename = unknown_filename;
821 tracemalloc_empty_traceback.frames[0].lineno = 0;
822 tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback);
823
824 /* Disable tracing allocations until hooks are installed. Set
825 also the reentrant flag to detect bugs: fail with an assertion error
826 if set_reentrant(1) is called while tracing is disabled. */
827 set_reentrant(1);
828
829 tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED;
830 return 0;
831}
832
833static void
834tracemalloc_deinit(void)
835{
836 if (tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED)
837 return;
838 tracemalloc_config.initialized = TRACEMALLOC_FINALIZED;
839
840 tracemalloc_stop();
841
842 /* destroy hash tables */
843 _Py_hashtable_destroy(tracemalloc_traces);
844 _Py_hashtable_destroy(tracemalloc_tracebacks);
845 _Py_hashtable_destroy(tracemalloc_filenames);
846
847#if defined(WITH_THREAD) && defined(TRACE_RAW_MALLOC)
848 if (tables_lock != NULL) {
849 PyThread_free_lock(tables_lock);
850 tables_lock = NULL;
851 }
852#endif
853
854#ifdef REENTRANT_THREADLOCAL
855 PyThread_delete_key(tracemalloc_reentrant_key);
856#endif
857
858 Py_XDECREF(unknown_filename);
859}
860
861static int
Victor Stinnerf28ce602013-11-27 22:27:13 +0100862tracemalloc_start(int max_nframe)
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100863{
Victor Stinnerd8f0d922014-06-02 21:57:10 +0200864 PyMemAllocatorEx alloc;
Victor Stinnerf28ce602013-11-27 22:27:13 +0100865 size_t size;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100866
867 if (tracemalloc_init() < 0)
868 return -1;
869
870 if (tracemalloc_config.tracing) {
871 /* hook already installed: do nothing */
872 return 0;
873 }
874
Victor Stinner52aee852014-08-16 15:44:02 +0200875 assert(1 <= max_nframe && max_nframe <= MAX_NFRAME);
Victor Stinnerf28ce602013-11-27 22:27:13 +0100876 tracemalloc_config.max_nframe = max_nframe;
877
878 /* allocate a buffer to store a new traceback */
879 size = TRACEBACK_SIZE(max_nframe);
880 assert(tracemalloc_traceback == NULL);
881 tracemalloc_traceback = raw_malloc(size);
882 if (tracemalloc_traceback == NULL) {
883 PyErr_NoMemory();
884 return -1;
885 }
886
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100887#ifdef TRACE_RAW_MALLOC
888 alloc.malloc = tracemalloc_raw_malloc;
Victor Stinnerdb067af2014-05-02 22:31:14 +0200889 alloc.calloc = tracemalloc_raw_calloc;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100890 alloc.realloc = tracemalloc_raw_realloc;
891 alloc.free = tracemalloc_free;
892
893 alloc.ctx = &allocators.raw;
894 PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
895 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc);
896#endif
897
898 alloc.malloc = tracemalloc_malloc_gil;
Victor Stinnerdb067af2014-05-02 22:31:14 +0200899 alloc.calloc = tracemalloc_calloc_gil;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100900 alloc.realloc = tracemalloc_realloc_gil;
901 alloc.free = tracemalloc_free;
902
903 alloc.ctx = &allocators.mem;
904 PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem);
905 PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc);
906
907 alloc.ctx = &allocators.obj;
908 PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj);
909 PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc);
910
911 /* everything is ready: start tracing Python memory allocations */
912 tracemalloc_config.tracing = 1;
913 set_reentrant(0);
914
915 return 0;
916}
917
918static void
919tracemalloc_stop(void)
920{
921 if (!tracemalloc_config.tracing)
922 return;
923
924 /* stop tracing Python memory allocations */
925 tracemalloc_config.tracing = 0;
926
927 /* set the reentrant flag to detect bugs: fail with an assertion error if
928 set_reentrant(1) is called while tracing is disabled. */
929 set_reentrant(1);
930
931 /* unregister the hook on memory allocators */
932#ifdef TRACE_RAW_MALLOC
933 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
934#endif
935 PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem);
936 PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj);
937
938 /* release memory */
939 tracemalloc_clear_traces();
Victor Stinnerf28ce602013-11-27 22:27:13 +0100940 raw_free(tracemalloc_traceback);
941 tracemalloc_traceback = NULL;
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100942}
943
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100944PyDoc_STRVAR(tracemalloc_is_tracing_doc,
945 "is_tracing()->bool\n"
946 "\n"
947 "True if the tracemalloc module is tracing Python memory allocations,\n"
948 "False otherwise.");
949
950static PyObject*
951py_tracemalloc_is_tracing(PyObject *self)
952{
953 return PyBool_FromLong(tracemalloc_config.tracing);
954}
955
956PyDoc_STRVAR(tracemalloc_clear_traces_doc,
957 "clear_traces()\n"
958 "\n"
959 "Clear traces of memory blocks allocated by Python.");
960
961static PyObject*
962py_tracemalloc_clear_traces(PyObject *self)
963{
964 if (!tracemalloc_config.tracing)
965 Py_RETURN_NONE;
966
967 set_reentrant(1);
968 tracemalloc_clear_traces();
969 set_reentrant(0);
970
971 Py_RETURN_NONE;
972}
973
974static PyObject*
975frame_to_pyobject(frame_t *frame)
976{
977 PyObject *frame_obj, *lineno_obj;
978
979 frame_obj = PyTuple_New(2);
980 if (frame_obj == NULL)
981 return NULL;
982
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100983 Py_INCREF(frame->filename);
984 PyTuple_SET_ITEM(frame_obj, 0, frame->filename);
985
Victor Stinner95283342016-03-15 21:57:02 +0100986 lineno_obj = PyLong_FromUnsignedLong(frame->lineno);
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100987 if (lineno_obj == NULL) {
988 Py_DECREF(frame_obj);
989 return NULL;
990 }
991 PyTuple_SET_ITEM(frame_obj, 1, lineno_obj);
992
993 return frame_obj;
994}
995
996static PyObject*
997traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table)
998{
999 int i;
1000 PyObject *frames, *frame;
1001
1002 if (intern_table != NULL) {
1003 if (_Py_HASHTABLE_GET(intern_table, traceback, frames)) {
1004 Py_INCREF(frames);
1005 return frames;
1006 }
1007 }
1008
1009 frames = PyTuple_New(traceback->nframe);
1010 if (frames == NULL)
1011 return NULL;
1012
1013 for (i=0; i < traceback->nframe; i++) {
1014 frame = frame_to_pyobject(&traceback->frames[i]);
1015 if (frame == NULL) {
1016 Py_DECREF(frames);
1017 return NULL;
1018 }
1019 PyTuple_SET_ITEM(frames, i, frame);
1020 }
1021
1022 if (intern_table != NULL) {
1023 if (_Py_HASHTABLE_SET(intern_table, traceback, frames) < 0) {
1024 Py_DECREF(frames);
1025 PyErr_NoMemory();
1026 return NULL;
1027 }
1028 /* intern_table keeps a new reference to frames */
1029 Py_INCREF(frames);
1030 }
1031 return frames;
1032}
1033
1034static PyObject*
1035trace_to_pyobject(trace_t *trace, _Py_hashtable_t *intern_tracebacks)
1036{
1037 PyObject *trace_obj = NULL;
1038 PyObject *size, *traceback;
1039
1040 trace_obj = PyTuple_New(2);
1041 if (trace_obj == NULL)
1042 return NULL;
1043
1044 size = PyLong_FromSize_t(trace->size);
1045 if (size == NULL) {
1046 Py_DECREF(trace_obj);
1047 return NULL;
1048 }
1049 PyTuple_SET_ITEM(trace_obj, 0, size);
1050
1051 traceback = traceback_to_pyobject(trace->traceback, intern_tracebacks);
1052 if (traceback == NULL) {
1053 Py_DECREF(trace_obj);
1054 return NULL;
1055 }
1056 PyTuple_SET_ITEM(trace_obj, 1, traceback);
1057
1058 return trace_obj;
1059}
1060
1061typedef struct {
1062 _Py_hashtable_t *traces;
1063 _Py_hashtable_t *tracebacks;
1064 PyObject *list;
1065} get_traces_t;
1066
1067static int
1068tracemalloc_get_traces_fill(_Py_hashtable_entry_t *entry, void *user_data)
1069{
1070 get_traces_t *get_traces = user_data;
1071 trace_t *trace;
1072 PyObject *tracemalloc_obj;
1073 int res;
1074
Victor Stinnerd9a73522014-03-24 22:34:34 +01001075 trace = (trace_t *)_Py_HASHTABLE_ENTRY_DATA(entry);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001076
1077 tracemalloc_obj = trace_to_pyobject(trace, get_traces->tracebacks);
1078 if (tracemalloc_obj == NULL)
1079 return 1;
1080
1081 res = PyList_Append(get_traces->list, tracemalloc_obj);
1082 Py_DECREF(tracemalloc_obj);
1083 if (res < 0)
1084 return 1;
1085
1086 return 0;
1087}
1088
1089static int
1090tracemalloc_pyobject_decref_cb(_Py_hashtable_entry_t *entry, void *user_data)
1091{
1092 PyObject *obj = (PyObject *)_Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry);
1093 Py_DECREF(obj);
1094 return 0;
1095}
1096
1097PyDoc_STRVAR(tracemalloc_get_traces_doc,
Victor Stinner4fbefdb2013-11-25 09:33:18 +01001098 "_get_traces() -> list\n"
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001099 "\n"
1100 "Get traces of all memory blocks allocated by Python.\n"
1101 "Return a list of (size: int, traceback: tuple) tuples.\n"
1102 "traceback is a tuple of (filename: str, lineno: int) tuples.\n"
1103 "\n"
1104 "Return an empty list if the tracemalloc module is disabled.");
1105
1106static PyObject*
1107py_tracemalloc_get_traces(PyObject *self, PyObject *obj)
1108{
1109 get_traces_t get_traces;
1110 int err;
1111
1112 get_traces.traces = NULL;
1113 get_traces.tracebacks = NULL;
1114 get_traces.list = PyList_New(0);
1115 if (get_traces.list == NULL)
1116 goto error;
1117
1118 if (!tracemalloc_config.tracing)
1119 return get_traces.list;
1120
Victor Stinnerde2f1322013-11-26 00:26:23 +01001121 /* the traceback hash table is used temporarily to intern traceback tuple
1122 of (filename, lineno) tuples */
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001123 get_traces.tracebacks = hashtable_new(sizeof(PyObject *),
1124 _Py_hashtable_hash_ptr,
1125 _Py_hashtable_compare_direct);
1126 if (get_traces.tracebacks == NULL) {
1127 PyErr_NoMemory();
1128 goto error;
1129 }
1130
1131 TABLES_LOCK();
1132 get_traces.traces = _Py_hashtable_copy(tracemalloc_traces);
1133 TABLES_UNLOCK();
1134
1135 if (get_traces.traces == NULL) {
1136 PyErr_NoMemory();
1137 goto error;
1138 }
1139
1140 set_reentrant(1);
1141 err = _Py_hashtable_foreach(get_traces.traces,
1142 tracemalloc_get_traces_fill, &get_traces);
1143 set_reentrant(0);
1144 if (err)
1145 goto error;
1146
1147 goto finally;
1148
1149error:
1150 Py_CLEAR(get_traces.list);
1151
1152finally:
1153 if (get_traces.tracebacks != NULL) {
1154 _Py_hashtable_foreach(get_traces.tracebacks,
1155 tracemalloc_pyobject_decref_cb, NULL);
1156 _Py_hashtable_destroy(get_traces.tracebacks);
1157 }
1158 if (get_traces.traces != NULL)
1159 _Py_hashtable_destroy(get_traces.traces);
1160
1161 return get_traces.list;
1162}
1163
Victor Stinner0611c262016-03-15 22:22:13 +01001164static traceback_t*
1165tracemalloc_get_traceback(const void *ptr)
1166{
1167 trace_t trace;
1168 int found;
1169
1170 if (!tracemalloc_config.tracing)
1171 return NULL;
1172
1173 TABLES_LOCK();
1174 found = _Py_HASHTABLE_GET(tracemalloc_traces, ptr, trace);
1175 TABLES_UNLOCK();
1176
1177 if (!found)
1178 return NULL;
1179
1180 return trace.traceback;
1181}
1182
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001183PyDoc_STRVAR(tracemalloc_get_object_traceback_doc,
Victor Stinner4fbefdb2013-11-25 09:33:18 +01001184 "_get_object_traceback(obj)\n"
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001185 "\n"
1186 "Get the traceback where the Python object obj was allocated.\n"
1187 "Return a tuple of (filename: str, lineno: int) tuples.\n"
1188 "\n"
1189 "Return None if the tracemalloc module is disabled or did not\n"
1190 "trace the allocation of the object.");
1191
1192static PyObject*
1193py_tracemalloc_get_object_traceback(PyObject *self, PyObject *obj)
1194{
1195 PyTypeObject *type;
1196 void *ptr;
Victor Stinner0611c262016-03-15 22:22:13 +01001197 traceback_t *traceback;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001198
1199 type = Py_TYPE(obj);
1200 if (PyType_IS_GC(type))
1201 ptr = (void *)((char *)obj - sizeof(PyGC_Head));
1202 else
1203 ptr = (void *)obj;
1204
Victor Stinner0611c262016-03-15 22:22:13 +01001205 traceback = tracemalloc_get_traceback(ptr);
1206 if (traceback == NULL)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001207 Py_RETURN_NONE;
1208
Victor Stinner0611c262016-03-15 22:22:13 +01001209 return traceback_to_pyobject(traceback, NULL);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001210}
1211
Victor Stinner0611c262016-03-15 22:22:13 +01001212#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str))
1213
1214static void
1215_PyMem_DumpFrame(int fd, frame_t * frame)
1216{
1217 PUTS(fd, " File \"");
1218 _Py_DumpASCII(fd, frame->filename);
1219 PUTS(fd, "\", line ");
1220 _Py_DumpDecimal(fd, frame->lineno);
1221 PUTS(fd, "\n");
1222}
1223
1224/* Dump the traceback where a memory block was allocated into file descriptor
1225 fd. The function may block on TABLES_LOCK() but it is unlikely. */
1226void
1227_PyMem_DumpTraceback(int fd, const void *ptr)
1228{
1229 traceback_t *traceback;
1230 int i;
1231
1232 traceback = tracemalloc_get_traceback(ptr);
1233 if (traceback == NULL)
1234 return;
1235
1236 PUTS(fd, "Memory block allocated at (most recent call first):\n");
1237 for (i=0; i < traceback->nframe; i++) {
1238 _PyMem_DumpFrame(fd, &traceback->frames[i]);
1239 }
1240 PUTS(fd, "\n");
1241}
1242
1243#undef PUTS
1244
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001245PyDoc_STRVAR(tracemalloc_start_doc,
Victor Stinner3728d6c2013-11-23 12:37:20 +01001246 "start(nframe: int=1)\n"
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001247 "\n"
Victor Stinner3728d6c2013-11-23 12:37:20 +01001248 "Start tracing Python memory allocations. Set also the maximum number \n"
1249 "of frames stored in the traceback of a trace to nframe.");
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001250
1251static PyObject*
Victor Stinner3728d6c2013-11-23 12:37:20 +01001252py_tracemalloc_start(PyObject *self, PyObject *args)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001253{
Victor Stinner3728d6c2013-11-23 12:37:20 +01001254 Py_ssize_t nframe = 1;
Victor Stinnerf28ce602013-11-27 22:27:13 +01001255 int nframe_int;
Victor Stinner3728d6c2013-11-23 12:37:20 +01001256
1257 if (!PyArg_ParseTuple(args, "|n:start", &nframe))
1258 return NULL;
1259
Victor Stinner52aee852014-08-16 15:44:02 +02001260 if (nframe < 1 || nframe > MAX_NFRAME) {
Victor Stinner3728d6c2013-11-23 12:37:20 +01001261 PyErr_Format(PyExc_ValueError,
1262 "the number of frames must be in range [1; %i]",
Victor Stinner52aee852014-08-16 15:44:02 +02001263 MAX_NFRAME);
Victor Stinner3728d6c2013-11-23 12:37:20 +01001264 return NULL;
1265 }
Victor Stinnerf28ce602013-11-27 22:27:13 +01001266 nframe_int = Py_SAFE_DOWNCAST(nframe, Py_ssize_t, int);
Victor Stinner3728d6c2013-11-23 12:37:20 +01001267
Victor Stinnerf28ce602013-11-27 22:27:13 +01001268 if (tracemalloc_start(nframe_int) < 0)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001269 return NULL;
1270
1271 Py_RETURN_NONE;
1272}
1273
1274PyDoc_STRVAR(tracemalloc_stop_doc,
1275 "stop()\n"
1276 "\n"
1277 "Stop tracing Python memory allocations and clear traces\n"
1278 "of memory blocks allocated by Python.");
1279
1280static PyObject*
1281py_tracemalloc_stop(PyObject *self)
1282{
1283 tracemalloc_stop();
1284 Py_RETURN_NONE;
1285}
1286
1287PyDoc_STRVAR(tracemalloc_get_traceback_limit_doc,
1288 "get_traceback_limit() -> int\n"
1289 "\n"
1290 "Get the maximum number of frames stored in the traceback\n"
1291 "of a trace.\n"
1292 "\n"
1293 "By default, a trace of an allocated memory block only stores\n"
1294 "the most recent frame: the limit is 1.");
1295
1296static PyObject*
1297py_tracemalloc_get_traceback_limit(PyObject *self)
1298{
1299 return PyLong_FromLong(tracemalloc_config.max_nframe);
1300}
1301
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001302PyDoc_STRVAR(tracemalloc_get_tracemalloc_memory_doc,
1303 "get_tracemalloc_memory() -> int\n"
1304 "\n"
1305 "Get the memory usage in bytes of the tracemalloc module\n"
1306 "used internally to trace memory allocations.");
1307
1308static PyObject*
1309tracemalloc_get_tracemalloc_memory(PyObject *self)
1310{
1311 size_t size;
1312 PyObject *size_obj;
1313
1314 size = _Py_hashtable_size(tracemalloc_tracebacks);
1315 size += _Py_hashtable_size(tracemalloc_filenames);
1316
1317 TABLES_LOCK();
1318 size += _Py_hashtable_size(tracemalloc_traces);
1319 TABLES_UNLOCK();
1320
1321 size_obj = PyLong_FromSize_t(size);
1322 return Py_BuildValue("N", size_obj);
1323}
1324
1325PyDoc_STRVAR(tracemalloc_get_traced_memory_doc,
Victor Stinner59463d82013-11-26 10:46:06 +01001326 "get_traced_memory() -> (int, int)\n"
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001327 "\n"
Victor Stinner3c0481d2013-11-27 21:39:49 +01001328 "Get the current size and peak size of memory blocks traced\n"
1329 "by the tracemalloc module as a tuple: (current: int, peak: int).");
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001330
1331static PyObject*
1332tracemalloc_get_traced_memory(PyObject *self)
1333{
Victor Stinner3c0481d2013-11-27 21:39:49 +01001334 Py_ssize_t size, peak_size;
1335 PyObject *size_obj, *peak_size_obj;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001336
1337 if (!tracemalloc_config.tracing)
1338 return Py_BuildValue("ii", 0, 0);
1339
1340 TABLES_LOCK();
1341 size = tracemalloc_traced_memory;
Victor Stinner3c0481d2013-11-27 21:39:49 +01001342 peak_size = tracemalloc_peak_traced_memory;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001343 TABLES_UNLOCK();
1344
1345 size_obj = PyLong_FromSize_t(size);
Victor Stinner3c0481d2013-11-27 21:39:49 +01001346 peak_size_obj = PyLong_FromSize_t(peak_size);
1347 return Py_BuildValue("NN", size_obj, peak_size_obj);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001348}
1349
1350static PyMethodDef module_methods[] = {
1351 {"is_tracing", (PyCFunction)py_tracemalloc_is_tracing,
1352 METH_NOARGS, tracemalloc_is_tracing_doc},
1353 {"clear_traces", (PyCFunction)py_tracemalloc_clear_traces,
1354 METH_NOARGS, tracemalloc_clear_traces_doc},
1355 {"_get_traces", (PyCFunction)py_tracemalloc_get_traces,
1356 METH_NOARGS, tracemalloc_get_traces_doc},
1357 {"_get_object_traceback", (PyCFunction)py_tracemalloc_get_object_traceback,
1358 METH_O, tracemalloc_get_object_traceback_doc},
1359 {"start", (PyCFunction)py_tracemalloc_start,
Victor Stinner3728d6c2013-11-23 12:37:20 +01001360 METH_VARARGS, tracemalloc_start_doc},
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001361 {"stop", (PyCFunction)py_tracemalloc_stop,
1362 METH_NOARGS, tracemalloc_stop_doc},
1363 {"get_traceback_limit", (PyCFunction)py_tracemalloc_get_traceback_limit,
1364 METH_NOARGS, tracemalloc_get_traceback_limit_doc},
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001365 {"get_tracemalloc_memory", (PyCFunction)tracemalloc_get_tracemalloc_memory,
1366 METH_NOARGS, tracemalloc_get_tracemalloc_memory_doc},
1367 {"get_traced_memory", (PyCFunction)tracemalloc_get_traced_memory,
1368 METH_NOARGS, tracemalloc_get_traced_memory_doc},
1369
1370 /* sentinel */
1371 {NULL, NULL}
1372};
1373
1374PyDoc_STRVAR(module_doc,
1375"Debug module to trace memory blocks allocated by Python.");
1376
1377static struct PyModuleDef module_def = {
1378 PyModuleDef_HEAD_INIT,
1379 "_tracemalloc",
1380 module_doc,
1381 0, /* non-negative size to be able to unload the module */
1382 module_methods,
1383 NULL,
1384};
1385
1386PyMODINIT_FUNC
1387PyInit__tracemalloc(void)
1388{
1389 PyObject *m;
1390 m = PyModule_Create(&module_def);
1391 if (m == NULL)
1392 return NULL;
1393
1394 if (tracemalloc_init() < 0)
1395 return NULL;
1396
1397 return m;
1398}
1399
1400static int
1401parse_sys_xoptions(PyObject *value)
1402{
1403 PyObject *valuelong;
1404 long nframe;
1405
1406 if (value == Py_True)
1407 return 1;
1408
1409 assert(PyUnicode_Check(value));
1410 if (PyUnicode_GetLength(value) == 0)
1411 return -1;
1412
1413 valuelong = PyLong_FromUnicodeObject(value, 10);
1414 if (valuelong == NULL)
1415 return -1;
1416
1417 nframe = PyLong_AsLong(valuelong);
1418 Py_DECREF(valuelong);
1419 if (nframe == -1 && PyErr_Occurred())
1420 return -1;
1421
Victor Stinner52aee852014-08-16 15:44:02 +02001422 if (nframe < 1 || nframe > MAX_NFRAME)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001423 return -1;
1424
1425 return Py_SAFE_DOWNCAST(nframe, long, int);
1426}
1427
1428int
1429_PyTraceMalloc_Init(void)
1430{
1431 char *p;
1432 int nframe;
1433
1434#ifdef WITH_THREAD
1435 assert(PyGILState_Check());
1436#endif
1437
1438 if ((p = Py_GETENV("PYTHONTRACEMALLOC")) && *p != '\0') {
1439 char *endptr = p;
Victor Stinnerf28ce602013-11-27 22:27:13 +01001440 long value;
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001441
Victor Stinner711e27c2013-12-16 23:06:19 +01001442 errno = 0;
Victor Stinnerf28ce602013-11-27 22:27:13 +01001443 value = strtol(p, &endptr, 10);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001444 if (*endptr != '\0'
1445 || value < 1
Victor Stinner52aee852014-08-16 15:44:02 +02001446 || value > MAX_NFRAME
Victor Stinner711e27c2013-12-16 23:06:19 +01001447 || errno == ERANGE)
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001448 {
Victor Stinnerf28ce602013-11-27 22:27:13 +01001449 Py_FatalError("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001450 return -1;
1451 }
1452
1453 nframe = (int)value;
1454 }
1455 else {
1456 PyObject *xoptions, *key, *value;
1457
1458 xoptions = PySys_GetXOptions();
1459 if (xoptions == NULL)
1460 return -1;
1461
1462 key = PyUnicode_FromString("tracemalloc");
1463 if (key == NULL)
1464 return -1;
1465
1466 value = PyDict_GetItemWithError(xoptions, key);
1467 Py_DECREF(key);
1468 if (value == NULL) {
1469 if (PyErr_Occurred())
1470 return -1;
1471
1472 /* -X tracemalloc is not used */
1473 return 0;
1474 }
1475
1476 nframe = parse_sys_xoptions(value);
1477 Py_DECREF(value);
1478 if (nframe < 0) {
Victor Stinnerf28ce602013-11-27 22:27:13 +01001479 Py_FatalError("-X tracemalloc=NFRAME: invalid number of frames");
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001480 }
1481 }
1482
Victor Stinnerf28ce602013-11-27 22:27:13 +01001483 return tracemalloc_start(nframe);
Victor Stinnered3b0bc2013-11-23 12:27:24 +01001484}
1485
Victor Stinnerbe0708f2013-12-01 10:03:26 +01001486void
1487_PyTraceMalloc_Fini(void)
1488{
1489#ifdef WITH_THREAD
1490 assert(PyGILState_Check());
1491#endif
1492 tracemalloc_deinit();
1493}
1494