1
# Copyright (C) 2009 Canonical Ltd
3
# This program is free software: you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License version 3 as
5
# published by the Free Software Foundation.
7
# This program is distributed in the hope that it will be useful, but
8
# WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
# General Public License for more details.
12
# You should have received a copy of the GNU General Public License
13
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
"""The core routines for scanning python references and dumping memory info."""
17
cdef extern from "stdio.h":
22
size_t fwrite(void *, size_t, size_t, FILE *)
23
size_t fprintf(FILE *, char *, ...)
25
cdef extern from "Python.h":
26
FILE *PyFile_AsFile(object)
28
ctypedef struct PyGC_Head:
30
object PyString_FromStringAndSize(char *, Py_ssize_t)
33
cdef extern from "_scanner_core.h":
34
Py_ssize_t _size_of(object c_obj)
35
ctypedef void (*write_callback)(void *callee_data, char *bytes, size_t len)
37
void _clear_last_dumped()
38
void _dump_object_info(write_callback write, void *callee_data,
39
object c_obj, object nodump, int recurse)
40
object _get_referents(object c_obj)
43
_word_size = sizeof(Py_ssize_t)
44
_gc_head_size = sizeof(PyGC_Head)
45
_unicode_size = Py_UNICODE_SIZE
49
"""Compute the size of the object.
51
This is the actual malloc() size for this object, so for dicts it is the
52
size of the dict object, plus the size of the array of references, but
53
*not* the size of each individual referenced object.
55
:param obj: The object to measure
56
:return: An integer of the number of bytes used by this object.
61
cdef void _file_io_callback(void *callee_data, char *bytes, size_t len):
64
file_cb = <FILE *>callee_data
65
fwrite(bytes, 1, len, file_cb)
68
cdef void _callable_callback(void *callee_data, char *bytes, size_t len):
69
callable = <object>callee_data
71
s = PyString_FromStringAndSize(bytes, len)
75
def dump_object_info(object out, object obj, object nodump=None,
77
"""Dump the object information to the given output.
79
:param out: Either a File object, or a callable.
80
If a File object, we will write bytes to the underlying FILE*
81
Otherwise, we will call(str) with bytes as we build up the state of the
82
object. Note that a single call will not be a complete description, but
83
potentially a single character of the final formatted string.
84
:param obj: The object to inspect
85
:param nodump: If supplied, this is a set() of objects that we want to
86
exclude from the dump file.
87
:param recurse_depth: 0 to only dump the supplied object
88
1 to dump the object and immediate neighbors that would not otherwise be
89
referenced (such as strings).
90
2 dump everything we find and continue recursing
94
fp_out = PyFile_AsFile(out)
96
# This must be a callable
97
_dump_object_info(<write_callback>_file_io_callback, fp_out, obj,
98
nodump, recurse_depth)
100
_dump_object_info(<write_callback>_callable_callback, <void *>out, obj,
101
nodump, recurse_depth)
105
def get_referents(object obj):
106
"""Similar to gc.get_referents()
108
The main different is that gc.get_referents() only includes items that are
109
in the garbage collector. However, we want anything referred to by
112
return _get_referents(obj)