OLD | NEW |
1 /* | 1 /* |
2 * xmlmemory.c: libxml memory allocator wrapper. | 2 * xmlmemory.c: libxml memory allocator wrapper. |
3 * | 3 * |
4 * daniel@veillard.com | 4 * daniel@veillard.com |
5 */ | 5 */ |
6 | 6 |
7 #define IN_LIBXML | 7 #define IN_LIBXML |
8 #include "libxml.h" | 8 #include "libxml.h" |
9 | 9 |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #ifdef HAVE_CTYPE_H | 28 #ifdef HAVE_CTYPE_H |
29 #include <ctype.h> | 29 #include <ctype.h> |
30 #endif | 30 #endif |
31 | 31 |
32 /* #define DEBUG_MEMORY */ | 32 /* #define DEBUG_MEMORY */ |
33 | 33 |
34 /** | 34 /** |
35 * MEM_LIST: | 35 * MEM_LIST: |
36 * | 36 * |
37 * keep track of all allocated blocks for error reporting | 37 * keep track of all allocated blocks for error reporting |
38 * Always build the memory list ! | 38 * Always build the memory list ! |
39 */ | 39 */ |
40 #ifdef DEBUG_MEMORY_LOCATION | 40 #ifdef DEBUG_MEMORY_LOCATION |
41 #ifndef MEM_LIST | 41 #ifndef MEM_LIST |
42 #define MEM_LIST /* keep a list of all the allocated memory blocks */ | 42 #define MEM_LIST /* keep a list of all the allocated memory blocks */ |
43 #endif | 43 #endif |
44 #endif | 44 #endif |
45 | 45 |
46 #include <libxml/globals.h> /* must come before xmlmemory.h */ | 46 #include <libxml/globals.h> /* must come before xmlmemory.h */ |
47 #include <libxml/xmlmemory.h> | 47 #include <libxml/xmlmemory.h> |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 * a malloc() equivalent, with logging of the allocation info. | 155 * a malloc() equivalent, with logging of the allocation info. |
156 * | 156 * |
157 * Returns a pointer to the allocated area or NULL in case of lack of memory. | 157 * Returns a pointer to the allocated area or NULL in case of lack of memory. |
158 */ | 158 */ |
159 | 159 |
160 void * | 160 void * |
161 xmlMallocLoc(size_t size, const char * file, int line) | 161 xmlMallocLoc(size_t size, const char * file, int line) |
162 { | 162 { |
163 MEMHDR *p; | 163 MEMHDR *p; |
164 void *ret; | 164 void *ret; |
165 | 165 |
166 if (!xmlMemInitialized) xmlInitMemory(); | 166 if (!xmlMemInitialized) xmlInitMemory(); |
167 #ifdef DEBUG_MEMORY | 167 #ifdef DEBUG_MEMORY |
168 xmlGenericError(xmlGenericErrorContext, | 168 xmlGenericError(xmlGenericErrorContext, |
169 "Malloc(%d)\n",size); | 169 "Malloc(%d)\n",size); |
170 #endif | 170 #endif |
171 | 171 |
172 TEST_POINT | 172 TEST_POINT |
173 | 173 |
174 p = (MEMHDR *) malloc(RESERVE_SIZE+size); | 174 p = (MEMHDR *) malloc(RESERVE_SIZE+size); |
175 | 175 |
176 if (!p) { | 176 if (!p) { |
177 xmlGenericError(xmlGenericErrorContext, | 177 xmlGenericError(xmlGenericErrorContext, |
178 "xmlMallocLoc : Out of free space\n"); | 178 "xmlMallocLoc : Out of free space\n"); |
179 xmlMemoryDump(); | 179 xmlMemoryDump(); |
180 return(NULL); | 180 return(NULL); |
181 } | 181 } |
182 p->mh_tag = MEMTAG; | 182 p->mh_tag = MEMTAG; |
183 p->mh_size = size; | 183 p->mh_size = size; |
184 p->mh_type = MALLOC_TYPE; | 184 p->mh_type = MALLOC_TYPE; |
185 p->mh_file = file; | 185 p->mh_file = file; |
186 p->mh_line = line; | 186 p->mh_line = line; |
187 xmlMutexLock(xmlMemMutex); | 187 xmlMutexLock(xmlMemMutex); |
188 p->mh_number = ++block; | 188 p->mh_number = ++block; |
189 debugMemSize += size; | 189 debugMemSize += size; |
190 debugMemBlocks++; | 190 debugMemBlocks++; |
191 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; | 191 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; |
192 #ifdef MEM_LIST | 192 #ifdef MEM_LIST |
193 debugmem_list_add(p); | 193 debugmem_list_add(p); |
194 #endif | 194 #endif |
195 xmlMutexUnlock(xmlMemMutex); | 195 xmlMutexUnlock(xmlMemMutex); |
196 | 196 |
197 #ifdef DEBUG_MEMORY | 197 #ifdef DEBUG_MEMORY |
198 xmlGenericError(xmlGenericErrorContext, | 198 xmlGenericError(xmlGenericErrorContext, |
199 "Malloc(%d) Ok\n",size); | 199 "Malloc(%d) Ok\n",size); |
200 #endif | 200 #endif |
201 | 201 |
202 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); | 202 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); |
203 | 203 |
204 ret = HDR_2_CLIENT(p); | 204 ret = HDR_2_CLIENT(p); |
205 | 205 |
206 if (xmlMemTraceBlockAt == ret) { | 206 if (xmlMemTraceBlockAt == ret) { |
207 xmlGenericError(xmlGenericErrorContext, | 207 xmlGenericError(xmlGenericErrorContext, |
208 » » » "%p : Malloc(%d) Ok\n", xmlMemTraceBlockAt, size); | 208 » » » "%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size); |
209 xmlMallocBreakpoint(); | 209 xmlMallocBreakpoint(); |
210 } | 210 } |
211 | 211 |
212 TEST_POINT | 212 TEST_POINT |
213 | 213 |
214 return(ret); | 214 return(ret); |
215 } | 215 } |
216 | 216 |
217 /** | 217 /** |
218 * xmlMallocAtomicLoc: | 218 * xmlMallocAtomicLoc: |
219 * @size: an int specifying the size in byte to allocate. | 219 * @size: an int specifying the size in byte to allocate. |
220 * @file: the file name or NULL | 220 * @file: the file name or NULL |
221 * @line: the line number | 221 * @line: the line number |
222 * | 222 * |
223 * a malloc() equivalent, with logging of the allocation info. | 223 * a malloc() equivalent, with logging of the allocation info. |
224 * | 224 * |
225 * Returns a pointer to the allocated area or NULL in case of lack of memory. | 225 * Returns a pointer to the allocated area or NULL in case of lack of memory. |
226 */ | 226 */ |
227 | 227 |
228 void * | 228 void * |
229 xmlMallocAtomicLoc(size_t size, const char * file, int line) | 229 xmlMallocAtomicLoc(size_t size, const char * file, int line) |
230 { | 230 { |
231 MEMHDR *p; | 231 MEMHDR *p; |
232 void *ret; | 232 void *ret; |
233 | 233 |
234 if (!xmlMemInitialized) xmlInitMemory(); | 234 if (!xmlMemInitialized) xmlInitMemory(); |
235 #ifdef DEBUG_MEMORY | 235 #ifdef DEBUG_MEMORY |
236 xmlGenericError(xmlGenericErrorContext, | 236 xmlGenericError(xmlGenericErrorContext, |
237 "Malloc(%d)\n",size); | 237 "Malloc(%d)\n",size); |
238 #endif | 238 #endif |
239 | 239 |
240 TEST_POINT | 240 TEST_POINT |
241 | 241 |
242 p = (MEMHDR *) malloc(RESERVE_SIZE+size); | 242 p = (MEMHDR *) malloc(RESERVE_SIZE+size); |
243 | 243 |
244 if (!p) { | 244 if (!p) { |
245 xmlGenericError(xmlGenericErrorContext, | 245 xmlGenericError(xmlGenericErrorContext, |
246 "xmlMallocLoc : Out of free space\n"); | 246 "xmlMallocLoc : Out of free space\n"); |
247 xmlMemoryDump(); | 247 xmlMemoryDump(); |
248 return(NULL); | 248 return(NULL); |
249 } | 249 } |
250 p->mh_tag = MEMTAG; | 250 p->mh_tag = MEMTAG; |
251 p->mh_size = size; | 251 p->mh_size = size; |
252 p->mh_type = MALLOC_ATOMIC_TYPE; | 252 p->mh_type = MALLOC_ATOMIC_TYPE; |
253 p->mh_file = file; | 253 p->mh_file = file; |
254 p->mh_line = line; | 254 p->mh_line = line; |
255 xmlMutexLock(xmlMemMutex); | 255 xmlMutexLock(xmlMemMutex); |
256 p->mh_number = ++block; | 256 p->mh_number = ++block; |
257 debugMemSize += size; | 257 debugMemSize += size; |
258 debugMemBlocks++; | 258 debugMemBlocks++; |
259 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; | 259 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; |
260 #ifdef MEM_LIST | 260 #ifdef MEM_LIST |
261 debugmem_list_add(p); | 261 debugmem_list_add(p); |
262 #endif | 262 #endif |
263 xmlMutexUnlock(xmlMemMutex); | 263 xmlMutexUnlock(xmlMemMutex); |
264 | 264 |
265 #ifdef DEBUG_MEMORY | 265 #ifdef DEBUG_MEMORY |
266 xmlGenericError(xmlGenericErrorContext, | 266 xmlGenericError(xmlGenericErrorContext, |
267 "Malloc(%d) Ok\n",size); | 267 "Malloc(%d) Ok\n",size); |
268 #endif | 268 #endif |
269 | 269 |
270 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); | 270 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); |
271 | 271 |
272 ret = HDR_2_CLIENT(p); | 272 ret = HDR_2_CLIENT(p); |
273 | 273 |
274 if (xmlMemTraceBlockAt == ret) { | 274 if (xmlMemTraceBlockAt == ret) { |
275 xmlGenericError(xmlGenericErrorContext, | 275 xmlGenericError(xmlGenericErrorContext, |
276 » » » "%p : Malloc(%d) Ok\n", xmlMemTraceBlockAt, size); | 276 » » » "%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size); |
277 xmlMallocBreakpoint(); | 277 xmlMallocBreakpoint(); |
278 } | 278 } |
279 | 279 |
280 TEST_POINT | 280 TEST_POINT |
281 | 281 |
282 return(ret); | 282 return(ret); |
283 } | 283 } |
284 /** | 284 /** |
285 * xmlMemMalloc: | 285 * xmlMemMalloc: |
286 * @size: an int specifying the size in byte to allocate. | 286 * @size: an int specifying the size in byte to allocate. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 xmlMutexLock(xmlMemMutex); | 334 xmlMutexLock(xmlMemMutex); |
335 debugMemSize -= p->mh_size; | 335 debugMemSize -= p->mh_size; |
336 debugMemBlocks--; | 336 debugMemBlocks--; |
337 #ifdef DEBUG_MEMORY | 337 #ifdef DEBUG_MEMORY |
338 oldsize = p->mh_size; | 338 oldsize = p->mh_size; |
339 #endif | 339 #endif |
340 #ifdef MEM_LIST | 340 #ifdef MEM_LIST |
341 debugmem_list_delete(p); | 341 debugmem_list_delete(p); |
342 #endif | 342 #endif |
343 xmlMutexUnlock(xmlMemMutex); | 343 xmlMutexUnlock(xmlMemMutex); |
344 | 344 |
345 p = (MEMHDR *) realloc(p,RESERVE_SIZE+size); | 345 p = (MEMHDR *) realloc(p,RESERVE_SIZE+size); |
346 if (!p) { | 346 if (!p) { |
347 goto error; | 347 goto error; |
348 } | 348 } |
349 if (xmlMemTraceBlockAt == ptr) { | 349 if (xmlMemTraceBlockAt == ptr) { |
350 xmlGenericError(xmlGenericErrorContext, | 350 xmlGenericError(xmlGenericErrorContext, |
351 » » » "%p : Realloced(%d -> %d) Ok\n", | 351 » » » "%p : Realloced(%ld -> %ld) Ok\n", |
352 xmlMemTraceBlockAt, p->mh_size, size); | 352 xmlMemTraceBlockAt, p->mh_size, size); |
353 xmlMallocBreakpoint(); | 353 xmlMallocBreakpoint(); |
354 } | 354 } |
355 p->mh_tag = MEMTAG; | 355 p->mh_tag = MEMTAG; |
356 p->mh_number = number; | 356 p->mh_number = number; |
357 p->mh_type = REALLOC_TYPE; | 357 p->mh_type = REALLOC_TYPE; |
358 p->mh_size = size; | 358 p->mh_size = size; |
359 p->mh_file = file; | 359 p->mh_file = file; |
360 p->mh_line = line; | 360 p->mh_line = line; |
361 xmlMutexLock(xmlMemMutex); | 361 xmlMutexLock(xmlMemMutex); |
362 debugMemSize += size; | 362 debugMemSize += size; |
363 debugMemBlocks++; | 363 debugMemBlocks++; |
364 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; | 364 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; |
365 #ifdef MEM_LIST | 365 #ifdef MEM_LIST |
366 debugmem_list_add(p); | 366 debugmem_list_add(p); |
367 #endif | 367 #endif |
368 xmlMutexUnlock(xmlMemMutex); | 368 xmlMutexUnlock(xmlMemMutex); |
369 | 369 |
370 TEST_POINT | 370 TEST_POINT |
371 | 371 |
372 #ifdef DEBUG_MEMORY | 372 #ifdef DEBUG_MEMORY |
373 xmlGenericError(xmlGenericErrorContext, | 373 xmlGenericError(xmlGenericErrorContext, |
374 "Realloced(%d to %d) Ok\n", oldsize, size); | 374 "Realloced(%d to %d) Ok\n", oldsize, size); |
375 #endif | 375 #endif |
376 return(HDR_2_CLIENT(p)); | 376 return(HDR_2_CLIENT(p)); |
377 | 377 |
378 error: | 378 error: |
379 return(NULL); | 379 return(NULL); |
380 } | 380 } |
381 | 381 |
382 /** | 382 /** |
383 * xmlMemRealloc: | 383 * xmlMemRealloc: |
384 * @ptr: the initial memory block pointer | 384 * @ptr: the initial memory block pointer |
385 * @size: an int specifying the size in byte to allocate. | 385 * @size: an int specifying the size in byte to allocate. |
386 * | 386 * |
387 * a realloc() equivalent, with logging of the allocation info. | 387 * a realloc() equivalent, with logging of the allocation info. |
388 * | 388 * |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 xmlMutexUnlock(xmlMemMutex); | 448 xmlMutexUnlock(xmlMemMutex); |
449 | 449 |
450 free(p); | 450 free(p); |
451 | 451 |
452 TEST_POINT | 452 TEST_POINT |
453 | 453 |
454 #ifdef DEBUG_MEMORY | 454 #ifdef DEBUG_MEMORY |
455 xmlGenericError(xmlGenericErrorContext, | 455 xmlGenericError(xmlGenericErrorContext, |
456 "Freed(%d) Ok\n", size); | 456 "Freed(%d) Ok\n", size); |
457 #endif | 457 #endif |
458 | 458 |
459 return; | 459 return; |
460 | 460 |
461 error: | 461 error: |
462 xmlGenericError(xmlGenericErrorContext, | 462 xmlGenericError(xmlGenericErrorContext, |
463 "xmlMemFree(%lX) error\n", (unsigned long) ptr); | 463 "xmlMemFree(%lX) error\n", (unsigned long) ptr); |
464 xmlMallocBreakpoint(); | 464 xmlMallocBreakpoint(); |
465 return; | 465 return; |
466 } | 466 } |
467 | 467 |
468 /** | 468 /** |
469 * xmlMemStrdupLoc: | 469 * xmlMemStrdupLoc: |
470 * @str: the initial string pointer | 470 * @str: the initial string pointer |
471 * @file: the file name or NULL | 471 * @file: the file name or NULL |
(...skipping 25 matching lines...) Expand all Loading... |
497 p->mh_line = line; | 497 p->mh_line = line; |
498 xmlMutexLock(xmlMemMutex); | 498 xmlMutexLock(xmlMemMutex); |
499 p->mh_number = ++block; | 499 p->mh_number = ++block; |
500 debugMemSize += size; | 500 debugMemSize += size; |
501 debugMemBlocks++; | 501 debugMemBlocks++; |
502 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; | 502 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; |
503 #ifdef MEM_LIST | 503 #ifdef MEM_LIST |
504 debugmem_list_add(p); | 504 debugmem_list_add(p); |
505 #endif | 505 #endif |
506 xmlMutexUnlock(xmlMemMutex); | 506 xmlMutexUnlock(xmlMemMutex); |
507 | 507 |
508 s = (char *) HDR_2_CLIENT(p); | 508 s = (char *) HDR_2_CLIENT(p); |
509 | 509 |
510 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); | 510 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); |
511 | 511 |
512 if (s != NULL) | 512 if (s != NULL) |
513 strcpy(s,str); | 513 strcpy(s,str); |
514 else | 514 else |
515 goto error; | 515 goto error; |
516 | 516 |
517 TEST_POINT | 517 TEST_POINT |
518 | 518 |
519 if (xmlMemTraceBlockAt == s) { | 519 if (xmlMemTraceBlockAt == s) { |
520 xmlGenericError(xmlGenericErrorContext, | 520 xmlGenericError(xmlGenericErrorContext, |
521 "%p : Strdup() Ok\n", xmlMemTraceBlockAt); | 521 "%p : Strdup() Ok\n", xmlMemTraceBlockAt); |
522 xmlMallocBreakpoint(); | 522 xmlMallocBreakpoint(); |
523 } | 523 } |
524 | 524 |
525 return(s); | 525 return(s); |
526 | 526 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 if ((p != NULL) && (p == q)) { | 610 if ((p != NULL) && (p == q)) { |
611 fprintf(fp, " pointer to #%lu at index %d", | 611 fprintf(fp, " pointer to #%lu at index %d", |
612 p->mh_number, j); | 612 p->mh_number, j); |
613 return; | 613 return; |
614 } | 614 } |
615 } | 615 } |
616 } | 616 } |
617 } else if ((i == 0) && (buf[i] == 0)) { | 617 } else if ((i == 0) && (buf[i] == 0)) { |
618 fprintf(fp," null"); | 618 fprintf(fp," null"); |
619 } else { | 619 } else { |
620 if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf); | 620 if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf); |
621 else { | 621 else { |
622 fprintf(fp," ["); | 622 fprintf(fp," ["); |
623 for (j = 0;j < i;j++) | 623 for (j = 0;j < i;j++) |
624 fprintf(fp,"%c", buf[j]); | 624 fprintf(fp,"%c", buf[j]); |
625 fprintf(fp,"]"); | 625 fprintf(fp,"]"); |
626 } | 626 } |
627 } | 627 } |
628 } | 628 } |
629 #endif | 629 #endif |
630 | 630 |
631 /** | 631 /** |
| 632 * xmlMemDisplayLast: |
| 633 * @fp: a FILE descriptor used as the output file, if NULL, the result is |
| 634 * written to the file .memorylist |
| 635 * @nbBytes: the amount of memory to dump |
| 636 * |
| 637 * the last nbBytes of memory allocated and not freed, useful for dumping |
| 638 * the memory left allocated between two places at runtime. |
| 639 */ |
| 640 |
| 641 void |
| 642 xmlMemDisplayLast(FILE *fp, long nbBytes) |
| 643 { |
| 644 #ifdef MEM_LIST |
| 645 MEMHDR *p; |
| 646 unsigned idx; |
| 647 int nb = 0; |
| 648 #endif |
| 649 FILE *old_fp = fp; |
| 650 |
| 651 if (nbBytes <= 0) |
| 652 return; |
| 653 |
| 654 if (fp == NULL) { |
| 655 fp = fopen(".memorylist", "w"); |
| 656 if (fp == NULL) |
| 657 return; |
| 658 } |
| 659 |
| 660 #ifdef MEM_LIST |
| 661 fprintf(fp," Last %li MEMORY ALLOCATED : %lu, MAX was %lu\n", |
| 662 nbBytes, debugMemSize, debugMaxMemSize); |
| 663 fprintf(fp,"BLOCK NUMBER SIZE TYPE\n"); |
| 664 idx = 0; |
| 665 xmlMutexLock(xmlMemMutex); |
| 666 p = memlist; |
| 667 while ((p) && (nbBytes > 0)) { |
| 668 fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number, |
| 669 (unsigned long)p->mh_size); |
| 670 switch (p->mh_type) { |
| 671 case STRDUP_TYPE:fprintf(fp,"strdup() in ");break; |
| 672 case MALLOC_TYPE:fprintf(fp,"malloc() in ");break; |
| 673 case REALLOC_TYPE:fprintf(fp,"realloc() in ");break; |
| 674 case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break; |
| 675 case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break; |
| 676 default: |
| 677 fprintf(fp,"Unknown memory block, may be corrupted"); |
| 678 xmlMutexUnlock(xmlMemMutex); |
| 679 if (old_fp == NULL) |
| 680 fclose(fp); |
| 681 return; |
| 682 } |
| 683 if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line); |
| 684 if (p->mh_tag != MEMTAG) |
| 685 fprintf(fp," INVALID"); |
| 686 nb++; |
| 687 if (nb < 100) |
| 688 xmlMemContentShow(fp, p); |
| 689 else |
| 690 fprintf(fp," skip"); |
| 691 |
| 692 fprintf(fp,"\n"); |
| 693 nbBytes -= (unsigned long)p->mh_size; |
| 694 p = p->mh_next; |
| 695 } |
| 696 xmlMutexUnlock(xmlMemMutex); |
| 697 #else |
| 698 fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n"); |
| 699 #endif |
| 700 if (old_fp == NULL) |
| 701 fclose(fp); |
| 702 } |
| 703 |
| 704 /** |
632 * xmlMemDisplay: | 705 * xmlMemDisplay: |
633 * @fp: a FILE descriptor used as the output file, if NULL, the result is | 706 * @fp: a FILE descriptor used as the output file, if NULL, the result is |
634 * written to the file .memorylist | 707 * written to the file .memorylist |
635 * | 708 * |
636 * show in-extenso the memory blocks allocated | 709 * show in-extenso the memory blocks allocated |
637 */ | 710 */ |
638 | 711 |
639 void | 712 void |
640 xmlMemDisplay(FILE *fp) | 713 xmlMemDisplay(FILE *fp) |
641 { | 714 { |
(...skipping 16 matching lines...) Expand all Loading... |
658 } | 731 } |
659 | 732 |
660 #ifdef MEM_LIST | 733 #ifdef MEM_LIST |
661 #if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME) | 734 #if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME) |
662 currentTime = time(NULL); | 735 currentTime = time(NULL); |
663 tstruct = localtime(¤tTime); | 736 tstruct = localtime(¤tTime); |
664 strftime(buf, sizeof(buf) - 1, "%I:%M:%S %p", tstruct); | 737 strftime(buf, sizeof(buf) - 1, "%I:%M:%S %p", tstruct); |
665 fprintf(fp," %s\n\n", buf); | 738 fprintf(fp," %s\n\n", buf); |
666 #endif | 739 #endif |
667 | 740 |
668 | 741 |
669 fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n", | 742 fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n", |
670 debugMemSize, debugMaxMemSize); | 743 debugMemSize, debugMaxMemSize); |
671 fprintf(fp,"BLOCK NUMBER SIZE TYPE\n"); | 744 fprintf(fp,"BLOCK NUMBER SIZE TYPE\n"); |
672 idx = 0; | 745 idx = 0; |
673 xmlMutexLock(xmlMemMutex); | 746 xmlMutexLock(xmlMemMutex); |
674 p = memlist; | 747 p = memlist; |
675 while (p) { | 748 while (p) { |
676 fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number, | 749 fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number, |
677 (unsigned long)p->mh_size); | 750 (unsigned long)p->mh_size); |
678 switch (p->mh_type) { | 751 switch (p->mh_type) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 #endif | 808 #endif |
736 } | 809 } |
737 | 810 |
738 #endif | 811 #endif |
739 | 812 |
740 /* | 813 /* |
741 * debugmem_tag_error: | 814 * debugmem_tag_error: |
742 * | 815 * |
743 * internal error function. | 816 * internal error function. |
744 */ | 817 */ |
745 | 818 |
746 static void debugmem_tag_error(void *p) | 819 static void debugmem_tag_error(void *p) |
747 { | 820 { |
748 xmlGenericError(xmlGenericErrorContext, | 821 xmlGenericError(xmlGenericErrorContext, |
749 "Memory tag error occurs :%p \n\t bye\n", p); | 822 "Memory tag error occurs :%p \n\t bye\n", p); |
750 #ifdef MEM_LIST | 823 #ifdef MEM_LIST |
751 if (stderr) | 824 if (stderr) |
752 xmlMemDisplay(stderr); | 825 xmlMemDisplay(stderr); |
753 #endif | 826 #endif |
754 } | 827 } |
755 | 828 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 fprintf(fp,"%s(%u)", p->mh_file, p->mh_line); | 868 fprintf(fp,"%s(%u)", p->mh_file, p->mh_line); |
796 if (p->mh_tag != MEMTAG) | 869 if (p->mh_tag != MEMTAG) |
797 fprintf(fp," INVALID"); | 870 fprintf(fp," INVALID"); |
798 xmlMemContentShow(fp, p); | 871 xmlMemContentShow(fp, p); |
799 fprintf(fp,"\n"); | 872 fprintf(fp,"\n"); |
800 nr--; | 873 nr--; |
801 p = p->mh_next; | 874 p = p->mh_next; |
802 } | 875 } |
803 } | 876 } |
804 xmlMutexUnlock(xmlMemMutex); | 877 xmlMutexUnlock(xmlMemMutex); |
805 #endif /* MEM_LIST */ | 878 #endif /* MEM_LIST */ |
806 } | 879 } |
807 | 880 |
808 /** | 881 /** |
809 * xmlMemoryDump: | 882 * xmlMemoryDump: |
810 * | 883 * |
811 * Dump in-extenso the memory blocks allocated to the file .memorylist | 884 * Dump in-extenso the memory blocks allocated to the file .memorylist |
812 */ | 885 */ |
813 | 886 |
814 void | 887 void |
815 xmlMemoryDump(void) | 888 xmlMemoryDump(void) |
(...skipping 26 matching lines...) Expand all Loading... |
842 * | 915 * |
843 * Initialize the memory layer. | 916 * Initialize the memory layer. |
844 * | 917 * |
845 * Returns 0 on success | 918 * Returns 0 on success |
846 */ | 919 */ |
847 int | 920 int |
848 xmlInitMemory(void) | 921 xmlInitMemory(void) |
849 { | 922 { |
850 #ifdef HAVE_STDLIB_H | 923 #ifdef HAVE_STDLIB_H |
851 char *breakpoint; | 924 char *breakpoint; |
852 #endif | 925 #endif |
853 #ifdef DEBUG_MEMORY | 926 #ifdef DEBUG_MEMORY |
854 xmlGenericError(xmlGenericErrorContext, | 927 xmlGenericError(xmlGenericErrorContext, |
855 "xmlInitMemory()\n"); | 928 "xmlInitMemory()\n"); |
856 #endif | 929 #endif |
857 /* | 930 /* |
858 This is really not good code (see Bug 130419). Suggestions for | 931 This is really not good code (see Bug 130419). Suggestions for |
859 improvement will be welcome! | 932 improvement will be welcome! |
860 */ | 933 */ |
861 if (xmlMemInitialized) return(-1); | 934 if (xmlMemInitialized) return(-1); |
862 xmlMemInitialized = 1; | 935 xmlMemInitialized = 1; |
863 xmlMemMutex = xmlNewMutex(); | 936 xmlMemMutex = xmlNewMutex(); |
864 | 937 |
865 #ifdef HAVE_STDLIB_H | 938 #ifdef HAVE_STDLIB_H |
866 breakpoint = getenv("XML_MEM_BREAKPOINT"); | 939 breakpoint = getenv("XML_MEM_BREAKPOINT"); |
867 if (breakpoint != NULL) { | 940 if (breakpoint != NULL) { |
868 sscanf(breakpoint, "%ud", &xmlMemStopAtBlock); | 941 sscanf(breakpoint, "%ud", &xmlMemStopAtBlock); |
869 } | 942 } |
870 #endif | 943 #endif |
871 #ifdef HAVE_STDLIB_H | 944 #ifdef HAVE_STDLIB_H |
872 breakpoint = getenv("XML_MEM_TRACE"); | 945 breakpoint = getenv("XML_MEM_TRACE"); |
873 if (breakpoint != NULL) { | 946 if (breakpoint != NULL) { |
874 sscanf(breakpoint, "%p", &xmlMemTraceBlockAt); | 947 sscanf(breakpoint, "%p", &xmlMemTraceBlockAt); |
875 } | 948 } |
876 #endif | 949 #endif |
877 | 950 |
878 #ifdef DEBUG_MEMORY | 951 #ifdef DEBUG_MEMORY |
879 xmlGenericError(xmlGenericErrorContext, | 952 xmlGenericError(xmlGenericErrorContext, |
880 "xmlInitMemory() Ok\n"); | 953 "xmlInitMemory() Ok\n"); |
881 #endif | 954 #endif |
882 return(0); | 955 return(0); |
883 } | 956 } |
884 | 957 |
885 /** | 958 /** |
886 * xmlCleanupMemory: | 959 * xmlCleanupMemory: |
887 * | 960 * |
888 * Free up all the memory allocated by the library for its own | 961 * Free up all the memory allocated by the library for its own |
889 * use. This should not be called by user level code. | 962 * use. This should not be called by user level code. |
890 */ | 963 */ |
891 void | 964 void |
892 xmlCleanupMemory(void) { | 965 xmlCleanupMemory(void) { |
893 #ifdef DEBUG_MEMORY | 966 #ifdef DEBUG_MEMORY |
894 xmlGenericError(xmlGenericErrorContext, | 967 xmlGenericError(xmlGenericErrorContext, |
895 "xmlCleanupMemory()\n"); | 968 "xmlCleanupMemory()\n"); |
896 #endif | 969 #endif |
897 if (xmlMemInitialized == 0) | 970 if (xmlMemInitialized == 0) |
898 return; | 971 return; |
899 | 972 |
900 xmlFreeMutex(xmlMemMutex); | 973 xmlFreeMutex(xmlMemMutex); |
901 xmlMemMutex = NULL; | 974 xmlMemMutex = NULL; |
902 xmlMemInitialized = 0; | 975 xmlMemInitialized = 0; |
903 #ifdef DEBUG_MEMORY | 976 #ifdef DEBUG_MEMORY |
904 xmlGenericError(xmlGenericErrorContext, | 977 xmlGenericError(xmlGenericErrorContext, |
905 "xmlCleanupMemory() Ok\n"); | 978 "xmlCleanupMemory() Ok\n"); |
906 #endif | 979 #endif |
907 } | 980 } |
908 | 981 |
909 /** | 982 /** |
910 * xmlMemSetup: | 983 * xmlMemSetup: |
911 * @freeFunc: the free() function to use | 984 * @freeFunc: the free() function to use |
912 * @mallocFunc: the malloc() function to use | 985 * @mallocFunc: the malloc() function to use |
913 * @reallocFunc: the realloc() function to use | 986 * @reallocFunc: the realloc() function to use |
914 * @strdupFunc: the strdup() function to use | 987 * @strdupFunc: the strdup() function to use |
915 * | 988 * |
916 * Override the default memory access functions with a new set | 989 * Override the default memory access functions with a new set |
917 * This has to be called before any other libxml routines ! | 990 * This has to be called before any other libxml routines ! |
918 * | 991 * |
919 * Should this be blocked if there was already some allocations | 992 * Should this be blocked if there was already some allocations |
920 * done ? | 993 * done ? |
921 * | 994 * |
922 * Returns 0 on success | 995 * Returns 0 on success |
923 */ | 996 */ |
924 int | 997 int |
925 xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, | 998 xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, |
926 xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) { | 999 xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) { |
927 #ifdef DEBUG_MEMORY | 1000 #ifdef DEBUG_MEMORY |
928 xmlGenericError(xmlGenericErrorContext, | 1001 xmlGenericError(xmlGenericErrorContext, |
929 "xmlMemSetup()\n"); | 1002 "xmlMemSetup()\n"); |
930 #endif | 1003 #endif |
931 if (freeFunc == NULL) | 1004 if (freeFunc == NULL) |
932 return(-1); | 1005 return(-1); |
933 if (mallocFunc == NULL) | 1006 if (mallocFunc == NULL) |
934 return(-1); | 1007 return(-1); |
935 if (reallocFunc == NULL) | 1008 if (reallocFunc == NULL) |
936 return(-1); | 1009 return(-1); |
937 if (strdupFunc == NULL) | 1010 if (strdupFunc == NULL) |
938 return(-1); | 1011 return(-1); |
939 xmlFree = freeFunc; | 1012 xmlFree = freeFunc; |
940 xmlMalloc = mallocFunc; | 1013 xmlMalloc = mallocFunc; |
941 xmlMallocAtomic = mallocFunc; | 1014 xmlMallocAtomic = mallocFunc; |
942 xmlRealloc = reallocFunc; | 1015 xmlRealloc = reallocFunc; |
943 xmlMemStrdup = strdupFunc; | 1016 xmlMemStrdup = strdupFunc; |
944 #ifdef DEBUG_MEMORY | 1017 #ifdef DEBUG_MEMORY |
945 xmlGenericError(xmlGenericErrorContext, | 1018 xmlGenericError(xmlGenericErrorContext, |
946 "xmlMemSetup() Ok\n"); | 1019 "xmlMemSetup() Ok\n"); |
947 #endif | 1020 #endif |
948 return(0); | 1021 return(0); |
949 } | 1022 } |
950 | 1023 |
951 /** | 1024 /** |
952 * xmlMemGet: | 1025 * xmlMemGet: |
953 * @freeFunc: place to save the free() function in use | 1026 * @freeFunc: place to save the free() function in use |
954 * @mallocFunc: place to save the malloc() function in use | 1027 * @mallocFunc: place to save the malloc() function in use |
955 * @reallocFunc: place to save the realloc() function in use | 1028 * @reallocFunc: place to save the realloc() function in use |
956 * @strdupFunc: place to save the strdup() function in use | 1029 * @strdupFunc: place to save the strdup() function in use |
957 * | 1030 * |
(...skipping 29 matching lines...) Expand all Loading... |
987 * | 1060 * |
988 * Returns 0 on success | 1061 * Returns 0 on success |
989 */ | 1062 */ |
990 int | 1063 int |
991 xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, | 1064 xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, |
992 xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc, | 1065 xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc, |
993 xmlStrdupFunc strdupFunc) { | 1066 xmlStrdupFunc strdupFunc) { |
994 #ifdef DEBUG_MEMORY | 1067 #ifdef DEBUG_MEMORY |
995 xmlGenericError(xmlGenericErrorContext, | 1068 xmlGenericError(xmlGenericErrorContext, |
996 "xmlGcMemSetup()\n"); | 1069 "xmlGcMemSetup()\n"); |
997 #endif | 1070 #endif |
998 if (freeFunc == NULL) | 1071 if (freeFunc == NULL) |
999 return(-1); | 1072 return(-1); |
1000 if (mallocFunc == NULL) | 1073 if (mallocFunc == NULL) |
1001 return(-1); | 1074 return(-1); |
1002 if (mallocAtomicFunc == NULL) | 1075 if (mallocAtomicFunc == NULL) |
1003 return(-1); | 1076 return(-1); |
1004 if (reallocFunc == NULL) | 1077 if (reallocFunc == NULL) |
1005 return(-1); | 1078 return(-1); |
1006 if (strdupFunc == NULL) | 1079 if (strdupFunc == NULL) |
1007 return(-1); | 1080 return(-1); |
1008 xmlFree = freeFunc; | 1081 xmlFree = freeFunc; |
1009 xmlMalloc = mallocFunc; | 1082 xmlMalloc = mallocFunc; |
1010 xmlMallocAtomic = mallocAtomicFunc; | 1083 xmlMallocAtomic = mallocAtomicFunc; |
1011 xmlRealloc = reallocFunc; | 1084 xmlRealloc = reallocFunc; |
1012 xmlMemStrdup = strdupFunc; | 1085 xmlMemStrdup = strdupFunc; |
1013 #ifdef DEBUG_MEMORY | 1086 #ifdef DEBUG_MEMORY |
1014 xmlGenericError(xmlGenericErrorContext, | 1087 xmlGenericError(xmlGenericErrorContext, |
1015 "xmlGcMemSetup() Ok\n"); | 1088 "xmlGcMemSetup() Ok\n"); |
1016 #endif | 1089 #endif |
1017 return(0); | 1090 return(0); |
1018 } | 1091 } |
1019 | 1092 |
1020 /** | 1093 /** |
1021 * xmlGcMemGet: | 1094 * xmlGcMemGet: |
1022 * @freeFunc: place to save the free() function in use | 1095 * @freeFunc: place to save the free() function in use |
1023 * @mallocFunc: place to save the malloc() function in use | 1096 * @mallocFunc: place to save the malloc() function in use |
1024 * @mallocAtomicFunc: place to save the atomic malloc() function in use | 1097 * @mallocAtomicFunc: place to save the atomic malloc() function in use |
1025 * @reallocFunc: place to save the realloc() function in use | 1098 * @reallocFunc: place to save the realloc() function in use |
1026 * @strdupFunc: place to save the strdup() function in use | 1099 * @strdupFunc: place to save the strdup() function in use |
(...skipping 11 matching lines...) Expand all Loading... |
1038 if (freeFunc != NULL) *freeFunc = xmlFree; | 1111 if (freeFunc != NULL) *freeFunc = xmlFree; |
1039 if (mallocFunc != NULL) *mallocFunc = xmlMalloc; | 1112 if (mallocFunc != NULL) *mallocFunc = xmlMalloc; |
1040 if (mallocAtomicFunc != NULL) *mallocAtomicFunc = xmlMallocAtomic; | 1113 if (mallocAtomicFunc != NULL) *mallocAtomicFunc = xmlMallocAtomic; |
1041 if (reallocFunc != NULL) *reallocFunc = xmlRealloc; | 1114 if (reallocFunc != NULL) *reallocFunc = xmlRealloc; |
1042 if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup; | 1115 if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup; |
1043 return(0); | 1116 return(0); |
1044 } | 1117 } |
1045 | 1118 |
1046 #define bottom_xmlmemory | 1119 #define bottom_xmlmemory |
1047 #include "elfgcchack.h" | 1120 #include "elfgcchack.h" |
OLD | NEW |