/ lib / lxml / debug.pxi
debug.pxi
 1  
 2  @cython.final
 3  @cython.internal
 4  cdef class _MemDebug:
 5      """Debugging support for the memory allocation in libxml2.
 6      """
 7      def bytes_used(self):
 8          """bytes_used(self)
 9  
10          Returns the total amount of memory (in bytes) currently used by libxml2.
11          Note that libxml2 constrains this value to a C int, which limits
12          the accuracy on 64 bit systems.
13          """
14          return tree.xmlMemUsed()
15  
16      def blocks_used(self):
17          """blocks_used(self)
18  
19          Returns the total number of memory blocks currently allocated by libxml2.
20          Note that libxml2 constrains this value to a C int, which limits
21          the accuracy on 64 bit systems.
22          """
23          return tree.xmlMemBlocks()
24  
25      def dict_size(self):
26          """dict_size(self)
27  
28          Returns the current size of the global name dictionary used by libxml2
29          for the current thread.  Each thread has its own dictionary.
30          """
31          c_dict = __GLOBAL_PARSER_CONTEXT._getThreadDict(NULL)
32          if c_dict is NULL:
33              raise MemoryError()
34          return tree.xmlDictSize(c_dict)
35  
36      def dump(self, output_file=None, byte_count=None):
37          """dump(self, output_file=None, byte_count=None)
38  
39          Dumps the current memory blocks allocated by libxml2 to a file.
40  
41          The optional parameter 'output_file' specifies the file path.  It defaults
42          to the file ".memorylist" in the current directory.
43  
44          The optional parameter 'byte_count' limits the number of bytes in the dump.
45          Note that this parameter is ignored when lxml is compiled against a libxml2
46          version before 2.7.0.
47          """
48          cdef Py_ssize_t c_count
49          if output_file is None:
50              output_file = b'.memorylist'
51          elif isinstance(output_file, unicode):
52              output_file.encode(sys.getfilesystemencoding())
53  
54          f = stdio.fopen(output_file, "w")
55          if f is NULL:
56              raise IOError(f"Failed to create file {output_file.decode(sys.getfilesystemencoding())}")
57          try:
58              if byte_count is None:
59                  tree.xmlMemDisplay(f)
60              else:
61                  c_count = byte_count
62                  tree.xmlMemDisplayLast(f, c_count)
63          finally:
64              stdio.fclose(f)
65  
66      def show(self, output_file=None, block_count=None):
67          """show(self, output_file=None, block_count=None)
68  
69          Dumps the current memory blocks allocated by libxml2 to a file.
70          The output file format is suitable for line diffing.
71  
72          The optional parameter 'output_file' specifies the file path.  It defaults
73          to the file ".memorydump" in the current directory.
74  
75          The optional parameter 'block_count' limits the number of blocks
76          in the dump.
77          """
78          if output_file is None:
79              output_file = b'.memorydump'
80          elif isinstance(output_file, unicode):
81              output_file.encode(sys.getfilesystemencoding())
82  
83          f = stdio.fopen(output_file, "w")
84          if f is NULL:
85              raise IOError(f"Failed to create file {output_file.decode(sys.getfilesystemencoding())}")
86          try:
87              tree.xmlMemShow(f, block_count if block_count is not None else tree.xmlMemBlocks())
88          finally:
89              stdio.fclose(f)
90  
91  memory_debugger = _MemDebug()