| 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 |