pocxxeci 0.30.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pocxxeci might be problematic. Click here for more details.
- package/LICENSE +19 -0
- package/Makefile +18 -0
- package/README.md +52 -0
- package/binding.gyp +81 -0
- package/index.d.ts +273 -0
- package/index.js +45 -0
- package/lib/bindings.js +1 -0
- package/lib/document.js +122 -0
- package/lib/element.js +82 -0
- package/lib/sax_parser.js +38 -0
- package/package.json +70 -0
- package/src/html_document.cc +7 -0
- package/src/html_document.h +18 -0
- package/src/libxmljs.cc +252 -0
- package/src/libxmljs.h +53 -0
- package/src/xml_attribute.cc +173 -0
- package/src/xml_attribute.h +40 -0
- package/src/xml_comment.cc +117 -0
- package/src/xml_comment.h +30 -0
- package/src/xml_document.cc +810 -0
- package/src/xml_document.h +67 -0
- package/src/xml_element.cc +565 -0
- package/src/xml_element.h +61 -0
- package/src/xml_namespace.cc +158 -0
- package/src/xml_namespace.h +39 -0
- package/src/xml_node.cc +761 -0
- package/src/xml_node.h +73 -0
- package/src/xml_pi.cc +161 -0
- package/src/xml_pi.h +34 -0
- package/src/xml_sax_parser.cc +424 -0
- package/src/xml_sax_parser.h +73 -0
- package/src/xml_syntax_error.cc +66 -0
- package/src/xml_syntax_error.h +25 -0
- package/src/xml_text.cc +320 -0
- package/src/xml_text.h +48 -0
- package/src/xml_textwriter.cc +315 -0
- package/src/xml_textwriter.h +62 -0
- package/src/xml_xpath_context.cc +70 -0
- package/src/xml_xpath_context.h +23 -0
- package/vendor/libxml/Copyright +23 -0
- package/vendor/libxml/DOCBparser.c +305 -0
- package/vendor/libxml/HTMLparser.c +7287 -0
- package/vendor/libxml/HTMLtree.c +1200 -0
- package/vendor/libxml/Makefile +2983 -0
- package/vendor/libxml/SAX.c +180 -0
- package/vendor/libxml/SAX2.c +3036 -0
- package/vendor/libxml/buf.c +1351 -0
- package/vendor/libxml/buf.h +72 -0
- package/vendor/libxml/c14n.c +2234 -0
- package/vendor/libxml/catalog.c +3828 -0
- package/vendor/libxml/chvalid.c +336 -0
- package/vendor/libxml/config.h +294 -0
- package/vendor/libxml/config.h.gch +0 -0
- package/vendor/libxml/debugXML.c +3423 -0
- package/vendor/libxml/dict.c +1298 -0
- package/vendor/libxml/elfgcchack.h +17818 -0
- package/vendor/libxml/enc.h +32 -0
- package/vendor/libxml/encoding.c +3975 -0
- package/vendor/libxml/entities.c +1163 -0
- package/vendor/libxml/error.c +998 -0
- package/vendor/libxml/globals.c +1126 -0
- package/vendor/libxml/hash.c +1146 -0
- package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
- package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
- package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
- package/vendor/libxml/include/libxml/Makefile +725 -0
- package/vendor/libxml/include/libxml/Makefile.am +54 -0
- package/vendor/libxml/include/libxml/Makefile.in +725 -0
- package/vendor/libxml/include/libxml/SAX.h +173 -0
- package/vendor/libxml/include/libxml/SAX2.h +178 -0
- package/vendor/libxml/include/libxml/c14n.h +128 -0
- package/vendor/libxml/include/libxml/catalog.h +182 -0
- package/vendor/libxml/include/libxml/chvalid.h +230 -0
- package/vendor/libxml/include/libxml/debugXML.h +217 -0
- package/vendor/libxml/include/libxml/dict.h +79 -0
- package/vendor/libxml/include/libxml/encoding.h +245 -0
- package/vendor/libxml/include/libxml/entities.h +151 -0
- package/vendor/libxml/include/libxml/globals.h +508 -0
- package/vendor/libxml/include/libxml/hash.h +236 -0
- package/vendor/libxml/include/libxml/list.h +137 -0
- package/vendor/libxml/include/libxml/nanoftp.h +163 -0
- package/vendor/libxml/include/libxml/nanohttp.h +81 -0
- package/vendor/libxml/include/libxml/parser.h +1243 -0
- package/vendor/libxml/include/libxml/parserInternals.h +644 -0
- package/vendor/libxml/include/libxml/pattern.h +100 -0
- package/vendor/libxml/include/libxml/relaxng.h +217 -0
- package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
- package/vendor/libxml/include/libxml/schematron.h +142 -0
- package/vendor/libxml/include/libxml/threads.h +89 -0
- package/vendor/libxml/include/libxml/tree.h +1311 -0
- package/vendor/libxml/include/libxml/uri.h +94 -0
- package/vendor/libxml/include/libxml/valid.h +458 -0
- package/vendor/libxml/include/libxml/xinclude.h +129 -0
- package/vendor/libxml/include/libxml/xlink.h +189 -0
- package/vendor/libxml/include/libxml/xmlIO.h +368 -0
- package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
- package/vendor/libxml/include/libxml/xmlerror.h +945 -0
- package/vendor/libxml/include/libxml/xmlexports.h +77 -0
- package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
- package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
- package/vendor/libxml/include/libxml/xmlreader.h +428 -0
- package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
- package/vendor/libxml/include/libxml/xmlsave.h +88 -0
- package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
- package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
- package/vendor/libxml/include/libxml/xmlstring.h +140 -0
- package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
- package/vendor/libxml/include/libxml/xmlversion.h +484 -0
- package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
- package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
- package/vendor/libxml/include/libxml/xpath.h +564 -0
- package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
- package/vendor/libxml/include/libxml/xpointer.h +114 -0
- package/vendor/libxml/include/win32config.h +122 -0
- package/vendor/libxml/include/wsockcompat.h +54 -0
- package/vendor/libxml/legacy.c +1343 -0
- package/vendor/libxml/libxml.h +134 -0
- package/vendor/libxml/list.c +779 -0
- package/vendor/libxml/nanoftp.c +2118 -0
- package/vendor/libxml/nanohttp.c +1899 -0
- package/vendor/libxml/parser.c +15553 -0
- package/vendor/libxml/parserInternals.c +2164 -0
- package/vendor/libxml/pattern.c +2621 -0
- package/vendor/libxml/relaxng.c +11101 -0
- package/vendor/libxml/rngparser.c +1595 -0
- package/vendor/libxml/runsuite.c +1157 -0
- package/vendor/libxml/save.h +36 -0
- package/vendor/libxml/schematron.c +1787 -0
- package/vendor/libxml/threads.c +1049 -0
- package/vendor/libxml/timsort.h +601 -0
- package/vendor/libxml/tree.c +10183 -0
- package/vendor/libxml/trio.c +6895 -0
- package/vendor/libxml/trio.h +230 -0
- package/vendor/libxml/triodef.h +228 -0
- package/vendor/libxml/trionan.c +914 -0
- package/vendor/libxml/trionan.h +84 -0
- package/vendor/libxml/triop.h +150 -0
- package/vendor/libxml/triostr.c +2112 -0
- package/vendor/libxml/triostr.h +144 -0
- package/vendor/libxml/uri.c +2561 -0
- package/vendor/libxml/valid.c +7138 -0
- package/vendor/libxml/xinclude.c +2657 -0
- package/vendor/libxml/xlink.c +183 -0
- package/vendor/libxml/xmlIO.c +4135 -0
- package/vendor/libxml/xmlcatalog.c +624 -0
- package/vendor/libxml/xmllint.c +3796 -0
- package/vendor/libxml/xmlmemory.c +1163 -0
- package/vendor/libxml/xmlmodule.c +468 -0
- package/vendor/libxml/xmlreader.c +6033 -0
- package/vendor/libxml/xmlregexp.c +8271 -0
- package/vendor/libxml/xmlsave.c +2735 -0
- package/vendor/libxml/xmlschemas.c +29173 -0
- package/vendor/libxml/xmlschemastypes.c +6276 -0
- package/vendor/libxml/xmlstring.c +1050 -0
- package/vendor/libxml/xmlunicode.c +3179 -0
- package/vendor/libxml/xmlwriter.c +4738 -0
- package/vendor/libxml/xpath.c +14734 -0
- package/vendor/libxml/xpointer.c +2969 -0
- package/vendor/libxml/xzlib.c +815 -0
- package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,1163 @@
|
|
1
|
+
/*
|
2
|
+
* xmlmemory.c: libxml memory allocator wrapper.
|
3
|
+
*
|
4
|
+
* daniel@veillard.com
|
5
|
+
*/
|
6
|
+
|
7
|
+
#define IN_LIBXML
|
8
|
+
#include "libxml.h"
|
9
|
+
|
10
|
+
#include <string.h>
|
11
|
+
|
12
|
+
#ifdef HAVE_SYS_TYPES_H
|
13
|
+
#include <sys/types.h>
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#ifdef HAVE_TIME_H
|
17
|
+
#include <time.h>
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#ifdef HAVE_STDLIB_H
|
21
|
+
#include <stdlib.h>
|
22
|
+
#else
|
23
|
+
#ifdef HAVE_MALLOC_H
|
24
|
+
#include <malloc.h>
|
25
|
+
#endif
|
26
|
+
#endif
|
27
|
+
|
28
|
+
#ifdef HAVE_CTYPE_H
|
29
|
+
#include <ctype.h>
|
30
|
+
#endif
|
31
|
+
|
32
|
+
/* #define DEBUG_MEMORY */
|
33
|
+
|
34
|
+
/**
|
35
|
+
* MEM_LIST:
|
36
|
+
*
|
37
|
+
* keep track of all allocated blocks for error reporting
|
38
|
+
* Always build the memory list !
|
39
|
+
*/
|
40
|
+
#ifdef DEBUG_MEMORY_LOCATION
|
41
|
+
#ifndef MEM_LIST
|
42
|
+
#define MEM_LIST /* keep a list of all the allocated memory blocks */
|
43
|
+
#endif
|
44
|
+
#endif
|
45
|
+
|
46
|
+
#include <libxml/globals.h> /* must come before xmlmemory.h */
|
47
|
+
#include <libxml/xmlmemory.h>
|
48
|
+
#include <libxml/xmlerror.h>
|
49
|
+
#include <libxml/threads.h>
|
50
|
+
|
51
|
+
static int xmlMemInitialized = 0;
|
52
|
+
static unsigned long debugMemSize = 0;
|
53
|
+
static unsigned long debugMemBlocks = 0;
|
54
|
+
static unsigned long debugMaxMemSize = 0;
|
55
|
+
static xmlMutexPtr xmlMemMutex = NULL;
|
56
|
+
|
57
|
+
void xmlMallocBreakpoint(void);
|
58
|
+
|
59
|
+
/************************************************************************
|
60
|
+
* *
|
61
|
+
* Macros, variables and associated types *
|
62
|
+
* *
|
63
|
+
************************************************************************/
|
64
|
+
|
65
|
+
#if !defined(LIBXML_THREAD_ENABLED) && !defined(LIBXML_THREAD_ALLOC_ENABLED)
|
66
|
+
#ifdef xmlMalloc
|
67
|
+
#undef xmlMalloc
|
68
|
+
#endif
|
69
|
+
#ifdef xmlRealloc
|
70
|
+
#undef xmlRealloc
|
71
|
+
#endif
|
72
|
+
#ifdef xmlMemStrdup
|
73
|
+
#undef xmlMemStrdup
|
74
|
+
#endif
|
75
|
+
#endif
|
76
|
+
|
77
|
+
/*
|
78
|
+
* Each of the blocks allocated begin with a header containing information
|
79
|
+
*/
|
80
|
+
|
81
|
+
#define MEMTAG 0x5aa5
|
82
|
+
|
83
|
+
#define MALLOC_TYPE 1
|
84
|
+
#define REALLOC_TYPE 2
|
85
|
+
#define STRDUP_TYPE 3
|
86
|
+
#define MALLOC_ATOMIC_TYPE 4
|
87
|
+
#define REALLOC_ATOMIC_TYPE 5
|
88
|
+
|
89
|
+
typedef struct memnod {
|
90
|
+
unsigned int mh_tag;
|
91
|
+
unsigned int mh_type;
|
92
|
+
unsigned long mh_number;
|
93
|
+
size_t mh_size;
|
94
|
+
#ifdef MEM_LIST
|
95
|
+
struct memnod *mh_next;
|
96
|
+
struct memnod *mh_prev;
|
97
|
+
#endif
|
98
|
+
const char *mh_file;
|
99
|
+
unsigned int mh_line;
|
100
|
+
} MEMHDR;
|
101
|
+
|
102
|
+
|
103
|
+
#ifdef SUN4
|
104
|
+
#define ALIGN_SIZE 16
|
105
|
+
#else
|
106
|
+
#define ALIGN_SIZE sizeof(double)
|
107
|
+
#endif
|
108
|
+
#define HDR_SIZE sizeof(MEMHDR)
|
109
|
+
#define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
|
110
|
+
/ ALIGN_SIZE ) * ALIGN_SIZE)
|
111
|
+
|
112
|
+
#define MAX_SIZE_T ((size_t)-1)
|
113
|
+
|
114
|
+
#define CLIENT_2_HDR(a) ((void *) (((char *) (a)) - RESERVE_SIZE))
|
115
|
+
#define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE))
|
116
|
+
|
117
|
+
|
118
|
+
static unsigned int block=0;
|
119
|
+
static unsigned int xmlMemStopAtBlock = 0;
|
120
|
+
static void *xmlMemTraceBlockAt = NULL;
|
121
|
+
#ifdef MEM_LIST
|
122
|
+
static MEMHDR *memlist = NULL;
|
123
|
+
#endif
|
124
|
+
|
125
|
+
static void debugmem_tag_error(void *addr);
|
126
|
+
#ifdef MEM_LIST
|
127
|
+
static void debugmem_list_add(MEMHDR *);
|
128
|
+
static void debugmem_list_delete(MEMHDR *);
|
129
|
+
#endif
|
130
|
+
#define Mem_Tag_Err(a) debugmem_tag_error(a);
|
131
|
+
|
132
|
+
#ifndef TEST_POINT
|
133
|
+
#define TEST_POINT
|
134
|
+
#endif
|
135
|
+
|
136
|
+
/**
|
137
|
+
* xmlMallocBreakpoint:
|
138
|
+
*
|
139
|
+
* Breakpoint to use in conjunction with xmlMemStopAtBlock. When the block
|
140
|
+
* number reaches the specified value this function is called. One need to add a breakpoint
|
141
|
+
* to it to get the context in which the given block is allocated.
|
142
|
+
*/
|
143
|
+
|
144
|
+
void
|
145
|
+
xmlMallocBreakpoint(void) {
|
146
|
+
xmlGenericError(xmlGenericErrorContext,
|
147
|
+
"xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock);
|
148
|
+
}
|
149
|
+
|
150
|
+
/**
|
151
|
+
* xmlMallocLoc:
|
152
|
+
* @size: an int specifying the size in byte to allocate.
|
153
|
+
* @file: the file name or NULL
|
154
|
+
* @line: the line number
|
155
|
+
*
|
156
|
+
* a malloc() equivalent, with logging of the allocation info.
|
157
|
+
*
|
158
|
+
* Returns a pointer to the allocated area or NULL in case of lack of memory.
|
159
|
+
*/
|
160
|
+
|
161
|
+
void *
|
162
|
+
xmlMallocLoc(size_t size, const char * file, int line)
|
163
|
+
{
|
164
|
+
MEMHDR *p;
|
165
|
+
void *ret;
|
166
|
+
|
167
|
+
if (!xmlMemInitialized) xmlInitMemory();
|
168
|
+
#ifdef DEBUG_MEMORY
|
169
|
+
xmlGenericError(xmlGenericErrorContext,
|
170
|
+
"Malloc(%d)\n",size);
|
171
|
+
#endif
|
172
|
+
|
173
|
+
TEST_POINT
|
174
|
+
|
175
|
+
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
|
176
|
+
xmlGenericError(xmlGenericErrorContext,
|
177
|
+
"xmlMallocLoc : Unsigned overflow\n");
|
178
|
+
xmlMemoryDump();
|
179
|
+
return(NULL);
|
180
|
+
}
|
181
|
+
|
182
|
+
p = (MEMHDR *) malloc(RESERVE_SIZE+size);
|
183
|
+
|
184
|
+
if (!p) {
|
185
|
+
xmlGenericError(xmlGenericErrorContext,
|
186
|
+
"xmlMallocLoc : Out of free space\n");
|
187
|
+
xmlMemoryDump();
|
188
|
+
return(NULL);
|
189
|
+
}
|
190
|
+
p->mh_tag = MEMTAG;
|
191
|
+
p->mh_size = size;
|
192
|
+
p->mh_type = MALLOC_TYPE;
|
193
|
+
p->mh_file = file;
|
194
|
+
p->mh_line = line;
|
195
|
+
xmlMutexLock(xmlMemMutex);
|
196
|
+
p->mh_number = ++block;
|
197
|
+
debugMemSize += size;
|
198
|
+
debugMemBlocks++;
|
199
|
+
if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
|
200
|
+
#ifdef MEM_LIST
|
201
|
+
debugmem_list_add(p);
|
202
|
+
#endif
|
203
|
+
xmlMutexUnlock(xmlMemMutex);
|
204
|
+
|
205
|
+
#ifdef DEBUG_MEMORY
|
206
|
+
xmlGenericError(xmlGenericErrorContext,
|
207
|
+
"Malloc(%d) Ok\n",size);
|
208
|
+
#endif
|
209
|
+
|
210
|
+
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
|
211
|
+
|
212
|
+
ret = HDR_2_CLIENT(p);
|
213
|
+
|
214
|
+
if (xmlMemTraceBlockAt == ret) {
|
215
|
+
xmlGenericError(xmlGenericErrorContext,
|
216
|
+
"%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
|
217
|
+
(long unsigned)size);
|
218
|
+
xmlMallocBreakpoint();
|
219
|
+
}
|
220
|
+
|
221
|
+
TEST_POINT
|
222
|
+
|
223
|
+
return(ret);
|
224
|
+
}
|
225
|
+
|
226
|
+
/**
|
227
|
+
* xmlMallocAtomicLoc:
|
228
|
+
* @size: an unsigned int specifying the size in byte to allocate.
|
229
|
+
* @file: the file name or NULL
|
230
|
+
* @line: the line number
|
231
|
+
*
|
232
|
+
* a malloc() equivalent, with logging of the allocation info.
|
233
|
+
*
|
234
|
+
* Returns a pointer to the allocated area or NULL in case of lack of memory.
|
235
|
+
*/
|
236
|
+
|
237
|
+
void *
|
238
|
+
xmlMallocAtomicLoc(size_t size, const char * file, int line)
|
239
|
+
{
|
240
|
+
MEMHDR *p;
|
241
|
+
void *ret;
|
242
|
+
|
243
|
+
if (!xmlMemInitialized) xmlInitMemory();
|
244
|
+
#ifdef DEBUG_MEMORY
|
245
|
+
xmlGenericError(xmlGenericErrorContext,
|
246
|
+
"Malloc(%d)\n",size);
|
247
|
+
#endif
|
248
|
+
|
249
|
+
TEST_POINT
|
250
|
+
|
251
|
+
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
|
252
|
+
xmlGenericError(xmlGenericErrorContext,
|
253
|
+
"xmlMallocAtomicLoc : Unsigned overflow\n");
|
254
|
+
xmlMemoryDump();
|
255
|
+
return(NULL);
|
256
|
+
}
|
257
|
+
|
258
|
+
p = (MEMHDR *) malloc(RESERVE_SIZE+size);
|
259
|
+
|
260
|
+
if (!p) {
|
261
|
+
xmlGenericError(xmlGenericErrorContext,
|
262
|
+
"xmlMallocAtomicLoc : Out of free space\n");
|
263
|
+
xmlMemoryDump();
|
264
|
+
return(NULL);
|
265
|
+
}
|
266
|
+
p->mh_tag = MEMTAG;
|
267
|
+
p->mh_size = size;
|
268
|
+
p->mh_type = MALLOC_ATOMIC_TYPE;
|
269
|
+
p->mh_file = file;
|
270
|
+
p->mh_line = line;
|
271
|
+
xmlMutexLock(xmlMemMutex);
|
272
|
+
p->mh_number = ++block;
|
273
|
+
debugMemSize += size;
|
274
|
+
debugMemBlocks++;
|
275
|
+
if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
|
276
|
+
#ifdef MEM_LIST
|
277
|
+
debugmem_list_add(p);
|
278
|
+
#endif
|
279
|
+
xmlMutexUnlock(xmlMemMutex);
|
280
|
+
|
281
|
+
#ifdef DEBUG_MEMORY
|
282
|
+
xmlGenericError(xmlGenericErrorContext,
|
283
|
+
"Malloc(%d) Ok\n",size);
|
284
|
+
#endif
|
285
|
+
|
286
|
+
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
|
287
|
+
|
288
|
+
ret = HDR_2_CLIENT(p);
|
289
|
+
|
290
|
+
if (xmlMemTraceBlockAt == ret) {
|
291
|
+
xmlGenericError(xmlGenericErrorContext,
|
292
|
+
"%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
|
293
|
+
(long unsigned)size);
|
294
|
+
xmlMallocBreakpoint();
|
295
|
+
}
|
296
|
+
|
297
|
+
TEST_POINT
|
298
|
+
|
299
|
+
return(ret);
|
300
|
+
}
|
301
|
+
/**
|
302
|
+
* xmlMemMalloc:
|
303
|
+
* @size: an int specifying the size in byte to allocate.
|
304
|
+
*
|
305
|
+
* a malloc() equivalent, with logging of the allocation info.
|
306
|
+
*
|
307
|
+
* Returns a pointer to the allocated area or NULL in case of lack of memory.
|
308
|
+
*/
|
309
|
+
|
310
|
+
void *
|
311
|
+
xmlMemMalloc(size_t size)
|
312
|
+
{
|
313
|
+
return(xmlMallocLoc(size, "none", 0));
|
314
|
+
}
|
315
|
+
|
316
|
+
/**
|
317
|
+
* xmlReallocLoc:
|
318
|
+
* @ptr: the initial memory block pointer
|
319
|
+
* @size: an int specifying the size in byte to allocate.
|
320
|
+
* @file: the file name or NULL
|
321
|
+
* @line: the line number
|
322
|
+
*
|
323
|
+
* a realloc() equivalent, with logging of the allocation info.
|
324
|
+
*
|
325
|
+
* Returns a pointer to the allocated area or NULL in case of lack of memory.
|
326
|
+
*/
|
327
|
+
|
328
|
+
void *
|
329
|
+
xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
|
330
|
+
{
|
331
|
+
MEMHDR *p, *tmp;
|
332
|
+
unsigned long number;
|
333
|
+
#ifdef DEBUG_MEMORY
|
334
|
+
size_t oldsize;
|
335
|
+
#endif
|
336
|
+
|
337
|
+
if (ptr == NULL)
|
338
|
+
return(xmlMallocLoc(size, file, line));
|
339
|
+
|
340
|
+
if (!xmlMemInitialized) xmlInitMemory();
|
341
|
+
TEST_POINT
|
342
|
+
|
343
|
+
p = CLIENT_2_HDR(ptr);
|
344
|
+
number = p->mh_number;
|
345
|
+
if (xmlMemStopAtBlock == number) xmlMallocBreakpoint();
|
346
|
+
if (p->mh_tag != MEMTAG) {
|
347
|
+
Mem_Tag_Err(p);
|
348
|
+
goto error;
|
349
|
+
}
|
350
|
+
p->mh_tag = ~MEMTAG;
|
351
|
+
xmlMutexLock(xmlMemMutex);
|
352
|
+
debugMemSize -= p->mh_size;
|
353
|
+
debugMemBlocks--;
|
354
|
+
#ifdef DEBUG_MEMORY
|
355
|
+
oldsize = p->mh_size;
|
356
|
+
#endif
|
357
|
+
#ifdef MEM_LIST
|
358
|
+
debugmem_list_delete(p);
|
359
|
+
#endif
|
360
|
+
xmlMutexUnlock(xmlMemMutex);
|
361
|
+
|
362
|
+
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
|
363
|
+
xmlGenericError(xmlGenericErrorContext,
|
364
|
+
"xmlReallocLoc : Unsigned overflow\n");
|
365
|
+
xmlMemoryDump();
|
366
|
+
return(NULL);
|
367
|
+
}
|
368
|
+
|
369
|
+
tmp = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
|
370
|
+
if (!tmp) {
|
371
|
+
free(p);
|
372
|
+
goto error;
|
373
|
+
}
|
374
|
+
p = tmp;
|
375
|
+
if (xmlMemTraceBlockAt == ptr) {
|
376
|
+
xmlGenericError(xmlGenericErrorContext,
|
377
|
+
"%p : Realloced(%lu -> %lu) Ok\n",
|
378
|
+
xmlMemTraceBlockAt, (long unsigned)p->mh_size,
|
379
|
+
(long unsigned)size);
|
380
|
+
xmlMallocBreakpoint();
|
381
|
+
}
|
382
|
+
p->mh_tag = MEMTAG;
|
383
|
+
p->mh_number = number;
|
384
|
+
p->mh_type = REALLOC_TYPE;
|
385
|
+
p->mh_size = size;
|
386
|
+
p->mh_file = file;
|
387
|
+
p->mh_line = line;
|
388
|
+
xmlMutexLock(xmlMemMutex);
|
389
|
+
debugMemSize += size;
|
390
|
+
debugMemBlocks++;
|
391
|
+
if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
|
392
|
+
#ifdef MEM_LIST
|
393
|
+
debugmem_list_add(p);
|
394
|
+
#endif
|
395
|
+
xmlMutexUnlock(xmlMemMutex);
|
396
|
+
|
397
|
+
TEST_POINT
|
398
|
+
|
399
|
+
#ifdef DEBUG_MEMORY
|
400
|
+
xmlGenericError(xmlGenericErrorContext,
|
401
|
+
"Realloced(%d to %d) Ok\n", oldsize, size);
|
402
|
+
#endif
|
403
|
+
return(HDR_2_CLIENT(p));
|
404
|
+
|
405
|
+
error:
|
406
|
+
return(NULL);
|
407
|
+
}
|
408
|
+
|
409
|
+
/**
|
410
|
+
* xmlMemRealloc:
|
411
|
+
* @ptr: the initial memory block pointer
|
412
|
+
* @size: an int specifying the size in byte to allocate.
|
413
|
+
*
|
414
|
+
* a realloc() equivalent, with logging of the allocation info.
|
415
|
+
*
|
416
|
+
* Returns a pointer to the allocated area or NULL in case of lack of memory.
|
417
|
+
*/
|
418
|
+
|
419
|
+
void *
|
420
|
+
xmlMemRealloc(void *ptr,size_t size) {
|
421
|
+
return(xmlReallocLoc(ptr, size, "none", 0));
|
422
|
+
}
|
423
|
+
|
424
|
+
/**
|
425
|
+
* xmlMemFree:
|
426
|
+
* @ptr: the memory block pointer
|
427
|
+
*
|
428
|
+
* a free() equivalent, with error checking.
|
429
|
+
*/
|
430
|
+
void
|
431
|
+
xmlMemFree(void *ptr)
|
432
|
+
{
|
433
|
+
MEMHDR *p;
|
434
|
+
char *target;
|
435
|
+
#ifdef DEBUG_MEMORY
|
436
|
+
size_t size;
|
437
|
+
#endif
|
438
|
+
|
439
|
+
if (ptr == NULL)
|
440
|
+
return;
|
441
|
+
|
442
|
+
if (ptr == (void *) -1) {
|
443
|
+
xmlGenericError(xmlGenericErrorContext,
|
444
|
+
"trying to free pointer from freed area\n");
|
445
|
+
goto error;
|
446
|
+
}
|
447
|
+
|
448
|
+
if (xmlMemTraceBlockAt == ptr) {
|
449
|
+
xmlGenericError(xmlGenericErrorContext,
|
450
|
+
"%p : Freed()\n", xmlMemTraceBlockAt);
|
451
|
+
xmlMallocBreakpoint();
|
452
|
+
}
|
453
|
+
|
454
|
+
TEST_POINT
|
455
|
+
|
456
|
+
target = (char *) ptr;
|
457
|
+
|
458
|
+
p = CLIENT_2_HDR(ptr);
|
459
|
+
if (p->mh_tag != MEMTAG) {
|
460
|
+
Mem_Tag_Err(p);
|
461
|
+
goto error;
|
462
|
+
}
|
463
|
+
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
|
464
|
+
p->mh_tag = ~MEMTAG;
|
465
|
+
memset(target, -1, p->mh_size);
|
466
|
+
xmlMutexLock(xmlMemMutex);
|
467
|
+
debugMemSize -= p->mh_size;
|
468
|
+
debugMemBlocks--;
|
469
|
+
#ifdef DEBUG_MEMORY
|
470
|
+
size = p->mh_size;
|
471
|
+
#endif
|
472
|
+
#ifdef MEM_LIST
|
473
|
+
debugmem_list_delete(p);
|
474
|
+
#endif
|
475
|
+
xmlMutexUnlock(xmlMemMutex);
|
476
|
+
|
477
|
+
free(p);
|
478
|
+
|
479
|
+
TEST_POINT
|
480
|
+
|
481
|
+
#ifdef DEBUG_MEMORY
|
482
|
+
xmlGenericError(xmlGenericErrorContext,
|
483
|
+
"Freed(%d) Ok\n", size);
|
484
|
+
#endif
|
485
|
+
|
486
|
+
return;
|
487
|
+
|
488
|
+
error:
|
489
|
+
xmlGenericError(xmlGenericErrorContext,
|
490
|
+
"xmlMemFree(%p) error\n", ptr);
|
491
|
+
xmlMallocBreakpoint();
|
492
|
+
return;
|
493
|
+
}
|
494
|
+
|
495
|
+
/**
|
496
|
+
* xmlMemStrdupLoc:
|
497
|
+
* @str: the initial string pointer
|
498
|
+
* @file: the file name or NULL
|
499
|
+
* @line: the line number
|
500
|
+
*
|
501
|
+
* a strdup() equivalent, with logging of the allocation info.
|
502
|
+
*
|
503
|
+
* Returns a pointer to the new string or NULL if allocation error occurred.
|
504
|
+
*/
|
505
|
+
|
506
|
+
char *
|
507
|
+
xmlMemStrdupLoc(const char *str, const char *file, int line)
|
508
|
+
{
|
509
|
+
char *s;
|
510
|
+
size_t size = strlen(str) + 1;
|
511
|
+
MEMHDR *p;
|
512
|
+
|
513
|
+
if (!xmlMemInitialized) xmlInitMemory();
|
514
|
+
TEST_POINT
|
515
|
+
|
516
|
+
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
|
517
|
+
xmlGenericError(xmlGenericErrorContext,
|
518
|
+
"xmlMemStrdupLoc : Unsigned overflow\n");
|
519
|
+
xmlMemoryDump();
|
520
|
+
return(NULL);
|
521
|
+
}
|
522
|
+
|
523
|
+
p = (MEMHDR *) malloc(RESERVE_SIZE+size);
|
524
|
+
if (!p) {
|
525
|
+
goto error;
|
526
|
+
}
|
527
|
+
p->mh_tag = MEMTAG;
|
528
|
+
p->mh_size = size;
|
529
|
+
p->mh_type = STRDUP_TYPE;
|
530
|
+
p->mh_file = file;
|
531
|
+
p->mh_line = line;
|
532
|
+
xmlMutexLock(xmlMemMutex);
|
533
|
+
p->mh_number = ++block;
|
534
|
+
debugMemSize += size;
|
535
|
+
debugMemBlocks++;
|
536
|
+
if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
|
537
|
+
#ifdef MEM_LIST
|
538
|
+
debugmem_list_add(p);
|
539
|
+
#endif
|
540
|
+
xmlMutexUnlock(xmlMemMutex);
|
541
|
+
|
542
|
+
s = (char *) HDR_2_CLIENT(p);
|
543
|
+
|
544
|
+
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
|
545
|
+
|
546
|
+
strcpy(s,str);
|
547
|
+
|
548
|
+
TEST_POINT
|
549
|
+
|
550
|
+
if (xmlMemTraceBlockAt == s) {
|
551
|
+
xmlGenericError(xmlGenericErrorContext,
|
552
|
+
"%p : Strdup() Ok\n", xmlMemTraceBlockAt);
|
553
|
+
xmlMallocBreakpoint();
|
554
|
+
}
|
555
|
+
|
556
|
+
return(s);
|
557
|
+
|
558
|
+
error:
|
559
|
+
return(NULL);
|
560
|
+
}
|
561
|
+
|
562
|
+
/**
|
563
|
+
* xmlMemoryStrdup:
|
564
|
+
* @str: the initial string pointer
|
565
|
+
*
|
566
|
+
* a strdup() equivalent, with logging of the allocation info.
|
567
|
+
*
|
568
|
+
* Returns a pointer to the new string or NULL if allocation error occurred.
|
569
|
+
*/
|
570
|
+
|
571
|
+
char *
|
572
|
+
xmlMemoryStrdup(const char *str) {
|
573
|
+
return(xmlMemStrdupLoc(str, "none", 0));
|
574
|
+
}
|
575
|
+
|
576
|
+
/**
|
577
|
+
* xmlMemUsed:
|
578
|
+
*
|
579
|
+
* Provides the amount of memory currently allocated
|
580
|
+
*
|
581
|
+
* Returns an int representing the amount of memory allocated.
|
582
|
+
*/
|
583
|
+
|
584
|
+
int
|
585
|
+
xmlMemUsed(void) {
|
586
|
+
int res;
|
587
|
+
|
588
|
+
xmlMutexLock(xmlMemMutex);
|
589
|
+
res = debugMemSize;
|
590
|
+
xmlMutexUnlock(xmlMemMutex);
|
591
|
+
return(res);
|
592
|
+
}
|
593
|
+
|
594
|
+
/**
|
595
|
+
* xmlMemBlocks:
|
596
|
+
*
|
597
|
+
* Provides the number of memory areas currently allocated
|
598
|
+
*
|
599
|
+
* Returns an int representing the number of blocks
|
600
|
+
*/
|
601
|
+
|
602
|
+
int
|
603
|
+
xmlMemBlocks(void) {
|
604
|
+
int res;
|
605
|
+
|
606
|
+
xmlMutexLock(xmlMemMutex);
|
607
|
+
res = debugMemBlocks;
|
608
|
+
xmlMutexUnlock(xmlMemMutex);
|
609
|
+
return(res);
|
610
|
+
}
|
611
|
+
|
612
|
+
#ifdef MEM_LIST
|
613
|
+
/**
|
614
|
+
* xmlMemContentShow:
|
615
|
+
* @fp: a FILE descriptor used as the output file
|
616
|
+
* @p: a memory block header
|
617
|
+
*
|
618
|
+
* tries to show some content from the memory block
|
619
|
+
*/
|
620
|
+
|
621
|
+
static void
|
622
|
+
xmlMemContentShow(FILE *fp, MEMHDR *p)
|
623
|
+
{
|
624
|
+
int i,j,k,len;
|
625
|
+
const char *buf;
|
626
|
+
|
627
|
+
if (p == NULL) {
|
628
|
+
fprintf(fp, " NULL");
|
629
|
+
return;
|
630
|
+
}
|
631
|
+
len = p->mh_size;
|
632
|
+
buf = (const char *) HDR_2_CLIENT(p);
|
633
|
+
|
634
|
+
for (i = 0;i < len;i++) {
|
635
|
+
if (buf[i] == 0) break;
|
636
|
+
if (!isprint((unsigned char) buf[i])) break;
|
637
|
+
}
|
638
|
+
if ((i < 4) && ((buf[i] != 0) || (i == 0))) {
|
639
|
+
if (len >= 4) {
|
640
|
+
MEMHDR *q;
|
641
|
+
void *cur;
|
642
|
+
|
643
|
+
for (j = 0;(j < len -3) && (j < 40);j += 4) {
|
644
|
+
cur = *((void **) &buf[j]);
|
645
|
+
q = CLIENT_2_HDR(cur);
|
646
|
+
p = memlist;
|
647
|
+
k = 0;
|
648
|
+
while (p != NULL) {
|
649
|
+
if (p == q) break;
|
650
|
+
p = p->mh_next;
|
651
|
+
if (k++ > 100) break;
|
652
|
+
}
|
653
|
+
if ((p != NULL) && (p == q)) {
|
654
|
+
fprintf(fp, " pointer to #%lu at index %d",
|
655
|
+
p->mh_number, j);
|
656
|
+
return;
|
657
|
+
}
|
658
|
+
}
|
659
|
+
}
|
660
|
+
} else if ((i == 0) && (buf[i] == 0)) {
|
661
|
+
fprintf(fp," null");
|
662
|
+
} else {
|
663
|
+
if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf);
|
664
|
+
else {
|
665
|
+
fprintf(fp," [");
|
666
|
+
for (j = 0;j < i;j++)
|
667
|
+
fprintf(fp,"%c", buf[j]);
|
668
|
+
fprintf(fp,"]");
|
669
|
+
}
|
670
|
+
}
|
671
|
+
}
|
672
|
+
#endif
|
673
|
+
|
674
|
+
/**
|
675
|
+
* xmlMemDisplayLast:
|
676
|
+
* @fp: a FILE descriptor used as the output file, if NULL, the result is
|
677
|
+
* written to the file .memorylist
|
678
|
+
* @nbBytes: the amount of memory to dump
|
679
|
+
*
|
680
|
+
* the last nbBytes of memory allocated and not freed, useful for dumping
|
681
|
+
* the memory left allocated between two places at runtime.
|
682
|
+
*/
|
683
|
+
|
684
|
+
void
|
685
|
+
xmlMemDisplayLast(FILE *fp, long nbBytes)
|
686
|
+
{
|
687
|
+
#ifdef MEM_LIST
|
688
|
+
MEMHDR *p;
|
689
|
+
unsigned idx;
|
690
|
+
int nb = 0;
|
691
|
+
#endif
|
692
|
+
FILE *old_fp = fp;
|
693
|
+
|
694
|
+
if (nbBytes <= 0)
|
695
|
+
return;
|
696
|
+
|
697
|
+
if (fp == NULL) {
|
698
|
+
fp = fopen(".memorylist", "w");
|
699
|
+
if (fp == NULL)
|
700
|
+
return;
|
701
|
+
}
|
702
|
+
|
703
|
+
#ifdef MEM_LIST
|
704
|
+
fprintf(fp," Last %li MEMORY ALLOCATED : %lu, MAX was %lu\n",
|
705
|
+
nbBytes, debugMemSize, debugMaxMemSize);
|
706
|
+
fprintf(fp,"BLOCK NUMBER SIZE TYPE\n");
|
707
|
+
idx = 0;
|
708
|
+
xmlMutexLock(xmlMemMutex);
|
709
|
+
p = memlist;
|
710
|
+
while ((p) && (nbBytes > 0)) {
|
711
|
+
fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number,
|
712
|
+
(unsigned long)p->mh_size);
|
713
|
+
switch (p->mh_type) {
|
714
|
+
case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
|
715
|
+
case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
|
716
|
+
case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
|
717
|
+
case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break;
|
718
|
+
case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
|
719
|
+
default:
|
720
|
+
fprintf(fp,"Unknown memory block, may be corrupted");
|
721
|
+
xmlMutexUnlock(xmlMemMutex);
|
722
|
+
if (old_fp == NULL)
|
723
|
+
fclose(fp);
|
724
|
+
return;
|
725
|
+
}
|
726
|
+
if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
|
727
|
+
if (p->mh_tag != MEMTAG)
|
728
|
+
fprintf(fp," INVALID");
|
729
|
+
nb++;
|
730
|
+
if (nb < 100)
|
731
|
+
xmlMemContentShow(fp, p);
|
732
|
+
else
|
733
|
+
fprintf(fp," skip");
|
734
|
+
|
735
|
+
fprintf(fp,"\n");
|
736
|
+
nbBytes -= (unsigned long)p->mh_size;
|
737
|
+
p = p->mh_next;
|
738
|
+
}
|
739
|
+
xmlMutexUnlock(xmlMemMutex);
|
740
|
+
#else
|
741
|
+
fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
|
742
|
+
#endif
|
743
|
+
if (old_fp == NULL)
|
744
|
+
fclose(fp);
|
745
|
+
}
|
746
|
+
|
747
|
+
/**
|
748
|
+
* xmlMemDisplay:
|
749
|
+
* @fp: a FILE descriptor used as the output file, if NULL, the result is
|
750
|
+
* written to the file .memorylist
|
751
|
+
*
|
752
|
+
* show in-extenso the memory blocks allocated
|
753
|
+
*/
|
754
|
+
|
755
|
+
void
|
756
|
+
xmlMemDisplay(FILE *fp)
|
757
|
+
{
|
758
|
+
#ifdef MEM_LIST
|
759
|
+
MEMHDR *p;
|
760
|
+
unsigned idx;
|
761
|
+
int nb = 0;
|
762
|
+
#if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME)
|
763
|
+
time_t currentTime;
|
764
|
+
char buf[500];
|
765
|
+
struct tm * tstruct;
|
766
|
+
#endif
|
767
|
+
#endif
|
768
|
+
FILE *old_fp = fp;
|
769
|
+
|
770
|
+
if (fp == NULL) {
|
771
|
+
fp = fopen(".memorylist", "w");
|
772
|
+
if (fp == NULL)
|
773
|
+
return;
|
774
|
+
}
|
775
|
+
|
776
|
+
#ifdef MEM_LIST
|
777
|
+
#if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME)
|
778
|
+
currentTime = time(NULL);
|
779
|
+
tstruct = localtime(¤tTime);
|
780
|
+
strftime(buf, sizeof(buf) - 1, "%I:%M:%S %p", tstruct);
|
781
|
+
fprintf(fp," %s\n\n", buf);
|
782
|
+
#endif
|
783
|
+
|
784
|
+
|
785
|
+
fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
|
786
|
+
debugMemSize, debugMaxMemSize);
|
787
|
+
fprintf(fp,"BLOCK NUMBER SIZE TYPE\n");
|
788
|
+
idx = 0;
|
789
|
+
xmlMutexLock(xmlMemMutex);
|
790
|
+
p = memlist;
|
791
|
+
while (p) {
|
792
|
+
fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number,
|
793
|
+
(unsigned long)p->mh_size);
|
794
|
+
switch (p->mh_type) {
|
795
|
+
case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
|
796
|
+
case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
|
797
|
+
case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
|
798
|
+
case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break;
|
799
|
+
case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
|
800
|
+
default:
|
801
|
+
fprintf(fp,"Unknown memory block, may be corrupted");
|
802
|
+
xmlMutexUnlock(xmlMemMutex);
|
803
|
+
if (old_fp == NULL)
|
804
|
+
fclose(fp);
|
805
|
+
return;
|
806
|
+
}
|
807
|
+
if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
|
808
|
+
if (p->mh_tag != MEMTAG)
|
809
|
+
fprintf(fp," INVALID");
|
810
|
+
nb++;
|
811
|
+
if (nb < 100)
|
812
|
+
xmlMemContentShow(fp, p);
|
813
|
+
else
|
814
|
+
fprintf(fp," skip");
|
815
|
+
|
816
|
+
fprintf(fp,"\n");
|
817
|
+
p = p->mh_next;
|
818
|
+
}
|
819
|
+
xmlMutexUnlock(xmlMemMutex);
|
820
|
+
#else
|
821
|
+
fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
|
822
|
+
#endif
|
823
|
+
if (old_fp == NULL)
|
824
|
+
fclose(fp);
|
825
|
+
}
|
826
|
+
|
827
|
+
#ifdef MEM_LIST
|
828
|
+
|
829
|
+
static void debugmem_list_add(MEMHDR *p)
|
830
|
+
{
|
831
|
+
p->mh_next = memlist;
|
832
|
+
p->mh_prev = NULL;
|
833
|
+
if (memlist) memlist->mh_prev = p;
|
834
|
+
memlist = p;
|
835
|
+
#ifdef MEM_LIST_DEBUG
|
836
|
+
if (stderr)
|
837
|
+
Mem_Display(stderr);
|
838
|
+
#endif
|
839
|
+
}
|
840
|
+
|
841
|
+
static void debugmem_list_delete(MEMHDR *p)
|
842
|
+
{
|
843
|
+
if (p->mh_next)
|
844
|
+
p->mh_next->mh_prev = p->mh_prev;
|
845
|
+
if (p->mh_prev)
|
846
|
+
p->mh_prev->mh_next = p->mh_next;
|
847
|
+
else memlist = p->mh_next;
|
848
|
+
#ifdef MEM_LIST_DEBUG
|
849
|
+
if (stderr)
|
850
|
+
Mem_Display(stderr);
|
851
|
+
#endif
|
852
|
+
}
|
853
|
+
|
854
|
+
#endif
|
855
|
+
|
856
|
+
/*
|
857
|
+
* debugmem_tag_error:
|
858
|
+
*
|
859
|
+
* internal error function.
|
860
|
+
*/
|
861
|
+
|
862
|
+
static void debugmem_tag_error(void *p)
|
863
|
+
{
|
864
|
+
xmlGenericError(xmlGenericErrorContext,
|
865
|
+
"Memory tag error occurs :%p \n\t bye\n", p);
|
866
|
+
#ifdef MEM_LIST
|
867
|
+
if (stderr)
|
868
|
+
xmlMemDisplay(stderr);
|
869
|
+
#endif
|
870
|
+
}
|
871
|
+
|
872
|
+
#ifdef MEM_LIST
|
873
|
+
static FILE *xmlMemoryDumpFile = NULL;
|
874
|
+
#endif
|
875
|
+
|
876
|
+
/**
|
877
|
+
* xmlMemShow:
|
878
|
+
* @fp: a FILE descriptor used as the output file
|
879
|
+
* @nr: number of entries to dump
|
880
|
+
*
|
881
|
+
* show a show display of the memory allocated, and dump
|
882
|
+
* the @nr last allocated areas which were not freed
|
883
|
+
*/
|
884
|
+
|
885
|
+
void
|
886
|
+
xmlMemShow(FILE *fp, int nr ATTRIBUTE_UNUSED)
|
887
|
+
{
|
888
|
+
#ifdef MEM_LIST
|
889
|
+
MEMHDR *p;
|
890
|
+
#endif
|
891
|
+
|
892
|
+
if (fp != NULL)
|
893
|
+
fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
|
894
|
+
debugMemSize, debugMaxMemSize);
|
895
|
+
#ifdef MEM_LIST
|
896
|
+
xmlMutexLock(xmlMemMutex);
|
897
|
+
if (nr > 0) {
|
898
|
+
fprintf(fp,"NUMBER SIZE TYPE WHERE\n");
|
899
|
+
p = memlist;
|
900
|
+
while ((p) && nr > 0) {
|
901
|
+
fprintf(fp,"%6lu %6lu ",p->mh_number,(unsigned long)p->mh_size);
|
902
|
+
switch (p->mh_type) {
|
903
|
+
case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
|
904
|
+
case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
|
905
|
+
case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break;
|
906
|
+
case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
|
907
|
+
case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
|
908
|
+
default:fprintf(fp," ??? in ");break;
|
909
|
+
}
|
910
|
+
if (p->mh_file != NULL)
|
911
|
+
fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
|
912
|
+
if (p->mh_tag != MEMTAG)
|
913
|
+
fprintf(fp," INVALID");
|
914
|
+
xmlMemContentShow(fp, p);
|
915
|
+
fprintf(fp,"\n");
|
916
|
+
nr--;
|
917
|
+
p = p->mh_next;
|
918
|
+
}
|
919
|
+
}
|
920
|
+
xmlMutexUnlock(xmlMemMutex);
|
921
|
+
#endif /* MEM_LIST */
|
922
|
+
}
|
923
|
+
|
924
|
+
/**
|
925
|
+
* xmlMemoryDump:
|
926
|
+
*
|
927
|
+
* Dump in-extenso the memory blocks allocated to the file .memorylist
|
928
|
+
*/
|
929
|
+
|
930
|
+
void
|
931
|
+
xmlMemoryDump(void)
|
932
|
+
{
|
933
|
+
#ifdef MEM_LIST
|
934
|
+
FILE *dump;
|
935
|
+
|
936
|
+
if (debugMaxMemSize == 0)
|
937
|
+
return;
|
938
|
+
dump = fopen(".memdump", "w");
|
939
|
+
if (dump == NULL)
|
940
|
+
xmlMemoryDumpFile = stderr;
|
941
|
+
else xmlMemoryDumpFile = dump;
|
942
|
+
|
943
|
+
xmlMemDisplay(xmlMemoryDumpFile);
|
944
|
+
|
945
|
+
if (dump != NULL) fclose(dump);
|
946
|
+
#endif /* MEM_LIST */
|
947
|
+
}
|
948
|
+
|
949
|
+
|
950
|
+
/****************************************************************
|
951
|
+
* *
|
952
|
+
* Initialization Routines *
|
953
|
+
* *
|
954
|
+
****************************************************************/
|
955
|
+
|
956
|
+
/**
|
957
|
+
* xmlInitMemory:
|
958
|
+
*
|
959
|
+
* Initialize the memory layer.
|
960
|
+
*
|
961
|
+
* Returns 0 on success
|
962
|
+
*/
|
963
|
+
int
|
964
|
+
xmlInitMemory(void)
|
965
|
+
{
|
966
|
+
#ifdef HAVE_STDLIB_H
|
967
|
+
char *breakpoint;
|
968
|
+
#endif
|
969
|
+
#ifdef DEBUG_MEMORY
|
970
|
+
xmlGenericError(xmlGenericErrorContext,
|
971
|
+
"xmlInitMemory()\n");
|
972
|
+
#endif
|
973
|
+
/*
|
974
|
+
This is really not good code (see Bug 130419). Suggestions for
|
975
|
+
improvement will be welcome!
|
976
|
+
*/
|
977
|
+
if (xmlMemInitialized) return(-1);
|
978
|
+
xmlMemInitialized = 1;
|
979
|
+
xmlMemMutex = xmlNewMutex();
|
980
|
+
|
981
|
+
#ifdef HAVE_STDLIB_H
|
982
|
+
breakpoint = getenv("XML_MEM_BREAKPOINT");
|
983
|
+
if (breakpoint != NULL) {
|
984
|
+
sscanf(breakpoint, "%ud", &xmlMemStopAtBlock);
|
985
|
+
}
|
986
|
+
#endif
|
987
|
+
#ifdef HAVE_STDLIB_H
|
988
|
+
breakpoint = getenv("XML_MEM_TRACE");
|
989
|
+
if (breakpoint != NULL) {
|
990
|
+
sscanf(breakpoint, "%p", &xmlMemTraceBlockAt);
|
991
|
+
}
|
992
|
+
#endif
|
993
|
+
|
994
|
+
#ifdef DEBUG_MEMORY
|
995
|
+
xmlGenericError(xmlGenericErrorContext,
|
996
|
+
"xmlInitMemory() Ok\n");
|
997
|
+
#endif
|
998
|
+
return(0);
|
999
|
+
}
|
1000
|
+
|
1001
|
+
/**
|
1002
|
+
* xmlCleanupMemory:
|
1003
|
+
*
|
1004
|
+
* Free up all the memory allocated by the library for its own
|
1005
|
+
* use. This should not be called by user level code.
|
1006
|
+
*/
|
1007
|
+
void
|
1008
|
+
xmlCleanupMemory(void) {
|
1009
|
+
#ifdef DEBUG_MEMORY
|
1010
|
+
xmlGenericError(xmlGenericErrorContext,
|
1011
|
+
"xmlCleanupMemory()\n");
|
1012
|
+
#endif
|
1013
|
+
if (xmlMemInitialized == 0)
|
1014
|
+
return;
|
1015
|
+
|
1016
|
+
xmlFreeMutex(xmlMemMutex);
|
1017
|
+
xmlMemMutex = NULL;
|
1018
|
+
xmlMemInitialized = 0;
|
1019
|
+
#ifdef DEBUG_MEMORY
|
1020
|
+
xmlGenericError(xmlGenericErrorContext,
|
1021
|
+
"xmlCleanupMemory() Ok\n");
|
1022
|
+
#endif
|
1023
|
+
}
|
1024
|
+
|
1025
|
+
/**
|
1026
|
+
* xmlMemSetup:
|
1027
|
+
* @freeFunc: the free() function to use
|
1028
|
+
* @mallocFunc: the malloc() function to use
|
1029
|
+
* @reallocFunc: the realloc() function to use
|
1030
|
+
* @strdupFunc: the strdup() function to use
|
1031
|
+
*
|
1032
|
+
* Override the default memory access functions with a new set
|
1033
|
+
* This has to be called before any other libxml routines !
|
1034
|
+
*
|
1035
|
+
* Should this be blocked if there was already some allocations
|
1036
|
+
* done ?
|
1037
|
+
*
|
1038
|
+
* Returns 0 on success
|
1039
|
+
*/
|
1040
|
+
int
|
1041
|
+
xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
|
1042
|
+
xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) {
|
1043
|
+
#ifdef DEBUG_MEMORY
|
1044
|
+
xmlGenericError(xmlGenericErrorContext,
|
1045
|
+
"xmlMemSetup()\n");
|
1046
|
+
#endif
|
1047
|
+
if (freeFunc == NULL)
|
1048
|
+
return(-1);
|
1049
|
+
if (mallocFunc == NULL)
|
1050
|
+
return(-1);
|
1051
|
+
if (reallocFunc == NULL)
|
1052
|
+
return(-1);
|
1053
|
+
if (strdupFunc == NULL)
|
1054
|
+
return(-1);
|
1055
|
+
xmlFree = freeFunc;
|
1056
|
+
xmlMalloc = mallocFunc;
|
1057
|
+
xmlMallocAtomic = mallocFunc;
|
1058
|
+
xmlRealloc = reallocFunc;
|
1059
|
+
xmlMemStrdup = strdupFunc;
|
1060
|
+
#ifdef DEBUG_MEMORY
|
1061
|
+
xmlGenericError(xmlGenericErrorContext,
|
1062
|
+
"xmlMemSetup() Ok\n");
|
1063
|
+
#endif
|
1064
|
+
return(0);
|
1065
|
+
}
|
1066
|
+
|
1067
|
+
/**
|
1068
|
+
* xmlMemGet:
|
1069
|
+
* @freeFunc: place to save the free() function in use
|
1070
|
+
* @mallocFunc: place to save the malloc() function in use
|
1071
|
+
* @reallocFunc: place to save the realloc() function in use
|
1072
|
+
* @strdupFunc: place to save the strdup() function in use
|
1073
|
+
*
|
1074
|
+
* Provides the memory access functions set currently in use
|
1075
|
+
*
|
1076
|
+
* Returns 0 on success
|
1077
|
+
*/
|
1078
|
+
int
|
1079
|
+
xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
|
1080
|
+
xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) {
|
1081
|
+
if (freeFunc != NULL) *freeFunc = xmlFree;
|
1082
|
+
if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
|
1083
|
+
if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
|
1084
|
+
if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
|
1085
|
+
return(0);
|
1086
|
+
}
|
1087
|
+
|
1088
|
+
/**
|
1089
|
+
* xmlGcMemSetup:
|
1090
|
+
* @freeFunc: the free() function to use
|
1091
|
+
* @mallocFunc: the malloc() function to use
|
1092
|
+
* @mallocAtomicFunc: the malloc() function to use for atomic allocations
|
1093
|
+
* @reallocFunc: the realloc() function to use
|
1094
|
+
* @strdupFunc: the strdup() function to use
|
1095
|
+
*
|
1096
|
+
* Override the default memory access functions with a new set
|
1097
|
+
* This has to be called before any other libxml routines !
|
1098
|
+
* The mallocAtomicFunc is specialized for atomic block
|
1099
|
+
* allocations (i.e. of areas useful for garbage collected memory allocators
|
1100
|
+
*
|
1101
|
+
* Should this be blocked if there was already some allocations
|
1102
|
+
* done ?
|
1103
|
+
*
|
1104
|
+
* Returns 0 on success
|
1105
|
+
*/
|
1106
|
+
int
|
1107
|
+
xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
|
1108
|
+
xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc,
|
1109
|
+
xmlStrdupFunc strdupFunc) {
|
1110
|
+
#ifdef DEBUG_MEMORY
|
1111
|
+
xmlGenericError(xmlGenericErrorContext,
|
1112
|
+
"xmlGcMemSetup()\n");
|
1113
|
+
#endif
|
1114
|
+
if (freeFunc == NULL)
|
1115
|
+
return(-1);
|
1116
|
+
if (mallocFunc == NULL)
|
1117
|
+
return(-1);
|
1118
|
+
if (mallocAtomicFunc == NULL)
|
1119
|
+
return(-1);
|
1120
|
+
if (reallocFunc == NULL)
|
1121
|
+
return(-1);
|
1122
|
+
if (strdupFunc == NULL)
|
1123
|
+
return(-1);
|
1124
|
+
xmlFree = freeFunc;
|
1125
|
+
xmlMalloc = mallocFunc;
|
1126
|
+
xmlMallocAtomic = mallocAtomicFunc;
|
1127
|
+
xmlRealloc = reallocFunc;
|
1128
|
+
xmlMemStrdup = strdupFunc;
|
1129
|
+
#ifdef DEBUG_MEMORY
|
1130
|
+
xmlGenericError(xmlGenericErrorContext,
|
1131
|
+
"xmlGcMemSetup() Ok\n");
|
1132
|
+
#endif
|
1133
|
+
return(0);
|
1134
|
+
}
|
1135
|
+
|
1136
|
+
/**
|
1137
|
+
* xmlGcMemGet:
|
1138
|
+
* @freeFunc: place to save the free() function in use
|
1139
|
+
* @mallocFunc: place to save the malloc() function in use
|
1140
|
+
* @mallocAtomicFunc: place to save the atomic malloc() function in use
|
1141
|
+
* @reallocFunc: place to save the realloc() function in use
|
1142
|
+
* @strdupFunc: place to save the strdup() function in use
|
1143
|
+
*
|
1144
|
+
* Provides the memory access functions set currently in use
|
1145
|
+
* The mallocAtomicFunc is specialized for atomic block
|
1146
|
+
* allocations (i.e. of areas useful for garbage collected memory allocators
|
1147
|
+
*
|
1148
|
+
* Returns 0 on success
|
1149
|
+
*/
|
1150
|
+
int
|
1151
|
+
xmlGcMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
|
1152
|
+
xmlMallocFunc *mallocAtomicFunc, xmlReallocFunc *reallocFunc,
|
1153
|
+
xmlStrdupFunc *strdupFunc) {
|
1154
|
+
if (freeFunc != NULL) *freeFunc = xmlFree;
|
1155
|
+
if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
|
1156
|
+
if (mallocAtomicFunc != NULL) *mallocAtomicFunc = xmlMallocAtomic;
|
1157
|
+
if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
|
1158
|
+
if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
|
1159
|
+
return(0);
|
1160
|
+
}
|
1161
|
+
|
1162
|
+
#define bottom_xmlmemory
|
1163
|
+
#include "elfgcchack.h"
|