Changeset 123 for trunk/src/helpers/memdebug.c
- Timestamp:
- Dec 14, 2001, 11:41:33 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/memdebug.c
r93 r123 32 32 * is executed, the system might be in a global memory 33 33 * lock, so DON'T display a message box while in that 34 * function. 34 * function, and DO NOT call malloc() or other memory 35 * functions in there. 35 36 * 36 37 * These debug functions have been added with V0.9.3 … … 38 39 * 39 40 * V0.9.6 added realloc() support and fixed a few bugs. 41 * 42 * With V0.9.16, most of this was rewritten to be much 43 * faster. This no longer slows down the system enormously. 40 44 * 41 45 * -- A PM heap debugging window which shows the status … … 49 53 * 50 54 * 2) Include memdebug.h AFTER those two. This will remap 51 * the malloc() etc. calls. 55 * the malloc() etc. calls to the debug functions in 56 * this file by defining macros for them. 52 57 * 53 58 * If you don't want those replaced, add … … 55 60 * before including memdebug.h. 56 61 * 62 * To avoid calling a debug function for a single call, 63 * place the malloc call (or whatever) in brackets. 64 * 57 65 * That's all. XWorkplace's setup.h does this automatically 58 66 * if XWorkplace is compiled with debug code. … … 60 68 * A couple of WARNINGS: 61 69 * 62 * 1) Memory debugging can greatly slow down the system 63 * after a while. When free() is invoked, the memory 64 * that was allocated is freed, but not the memory 65 * log entry (the HEAPITEM) to allow tracing what was 66 * freed. As a result, the linked list of memory items 67 * keeps growing longer, and free() becomes terribly 68 * slow after a while because it must traverse the 69 * entire list for each free() call. Use memdReleaseFreed 70 * from time to time. 70 * 1) When free() is invoked, the memory that was allocated 71 * is freed, but not the memory log entry (the HEAPITEM) 72 * to allow tracing what was freed. As a result, the tree 73 * of memory items keeps growing longer. Do not expect 74 * this to work forever, even though things have greatly 75 * improved with V0.9.16. 71 76 * 72 77 * 2) The replacement functions in this file allocate … … 76 81 * memory overwrites. Two magic strings are allocated, 77 82 * one before the actual buffer, and one behind it. 83 * The pointer returned is _not_ identical to the one 84 * that was internally allocated. 78 85 * 79 86 * As a result, YOU MUST NOT confuse the replacement … … 119 126 #include <setjmp.h> 120 127 128 #include "helpers\tree.h" 129 121 130 #define DONT_REPLACE_MALLOC // never do debug memory for this 122 131 #define MEMDEBUG_PRIVATE … … 125 134 #ifdef __XWPMEMDEBUG__ 126 135 136 #include "helpers\dosh.h" 127 137 #include "helpers\except.h" 138 128 139 #include "helpers\memdebug.h" // included by setup.h already 129 140 #include "helpers\stringh.h" … … 146 157 #define MEMBLOCKMAGIC_TAIL "\250\210&%/dfjsk%#,dlhf\223" 147 158 148 HMTX G_hmtxMallocList = NULLHANDLE;149 150 extern PHEAPITEMG_pHeapItemsRoot = NULL;151 PHEAPITEM G_pHeapItemsLast = NULL;152 153 PFNCBMEMDLOG G_pMemdLogFunc = NULL;154 155 extern ULONG G_ulItemsReleased = 0;156 extern ULONG G_ulBytesReleased = 0;159 HMTX G_hmtxMallocList = NULLHANDLE; 160 161 extern TREE *G_pHeapItemsRoot = NULL; 162 extern LONG G_cHeapItems = 0; 163 164 PFNCBMEMDLOG G_pMemdLogFunc = NULL; 165 166 extern ULONG G_ulItemsReleased = 0; 167 extern ULONG G_ulBytesReleased = 0; 157 168 158 169 /* ****************************************************************** … … 175 186 BOOL memdLock(VOID) 176 187 { 177 APIRET arc = NO_ERROR;178 if (G_hmtxMallocList == NULLHANDLE)188 if (!G_hmtxMallocList) 189 { 179 190 // first call: 180 arc = DosCreateMutexSem(NULL, 181 &G_hmtxMallocList, 182 0, // unshared 183 TRUE); // request now! 191 if (!DosCreateMutexSem(NULL, 192 &G_hmtxMallocList, 193 0, // unshared 194 TRUE)) // request now! 195 { 196 treeInit(&G_pHeapItemsRoot, &G_cHeapItems); 197 return TRUE; 198 } 199 } 184 200 else 185 arc =DosRequestMutexSem(G_hmtxMallocList,186 SEM_INDEFINITE_WAIT);187 188 return ( arc == NO_ERROR);201 return (!DosRequestMutexSem(G_hmtxMallocList, 202 SEM_INDEFINITE_WAIT)); 203 204 return (FALSE); 189 205 } 190 206 … … 199 215 { 200 216 DosReleaseMutexSem(G_hmtxMallocList); 217 } 218 219 /* 220 *@@ LogError: 221 * 222 *@@added V0.9.16 (2001-12-08) [umoeller] 223 */ 224 225 VOID LogError(const char *pcszFormat, // in: format string (like with printf) 226 ...) // in: additional stuff (like with printf) 227 { 228 if (G_pMemdLogFunc) 229 { 230 CHAR szMsg[1000]; 231 va_list args; 232 233 va_start(args, pcszFormat); 234 vsprintf(szMsg, pcszFormat, args); 235 va_end(args); 236 G_pMemdLogFunc(szMsg); 237 } 238 } 239 240 /* 241 *@@ FindHeapItem: 242 * 243 *@@added V0.9.16 (2001-12-08) [umoeller] 244 */ 245 246 PHEAPITEM FindHeapItem(void *p) 247 { 248 return ((PHEAPITEM)treeFind(G_pHeapItemsRoot, 249 (ULONG)p, 250 treeCompareKeys)); 251 } 252 253 /* 254 *@@ FillHeapItem: 255 * 256 *@@added V0.9.16 (2001-12-08) [umoeller] 257 */ 258 259 VOID FillHeapItem(PHEAPITEM pHeapItem, 260 void *prc, 261 size_t stSize, 262 const char *pcszSourceFile, // in: source file name 263 unsigned long ulLine, // in: source line 264 const char *pcszFunction) // in: function name 265 { 266 pHeapItem->ulSize = stSize; 267 268 pHeapItem->pcszSourceFile = pcszSourceFile; 269 pHeapItem->ulLine = ulLine; 270 pHeapItem->pcszFunction = pcszFunction; 271 272 DosGetDateTime(&pHeapItem->dtAllocated); 273 274 pHeapItem->ulTID = doshMyTID(); 275 276 pHeapItem->fFreed = FALSE; 277 278 // use the return pointer as the tree sort key 279 // V0.9.16 (2001-12-08) [umoeller] 280 pHeapItem->Tree.ulKey = (ULONG)prc; 281 } 282 283 /* 284 *@@ CheckMagics: 285 * 286 *@@added V0.9.16 (2001-12-08) [umoeller] 287 */ 288 289 VOID CheckMagics(const char *pcszParentFunc, 290 PHEAPITEM pHeapItem, 291 PBYTE p, 292 const char *pcszSourceFile, // in: source file name 293 unsigned long ulLine, // in: source line 294 const char *pcszFunction) // in: function name 295 { 296 void *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD); 297 ULONG ulError = 0; 298 299 // check magic string 300 if (memcmp(pBeforeMagic, 301 MEMBLOCKMAGIC_HEAD, 302 sizeof(MEMBLOCKMAGIC_HEAD))) 303 ulError = 1; 304 else if (memcmp(((PBYTE)p) + pHeapItem->ulSize, 305 MEMBLOCKMAGIC_TAIL, 306 sizeof(MEMBLOCKMAGIC_TAIL))) 307 ulError = 2; 308 309 if (ulError) 310 { 311 LogError("%s: Magic string %s memory block at 0x%lX has been overwritten.\n" 312 "This was detected by the free() call at %s (%s, line %d).\n" 313 "The block was allocated by %s (%s, line %d).", 314 pcszParentFunc, 315 (ulError == 1) ? "before" : "after", 316 p, 317 pcszFunction, 318 pcszSourceFile, 319 ulLine, // free 320 pHeapItem->pcszFunction, 321 pHeapItem->pcszSourceFile, 322 pHeapItem->ulLine); 323 } 201 324 } 202 325 … … 217 340 * 218 341 *@@added V0.9.3 (2000-04-11) [umoeller] 342 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster 219 343 */ 220 344 … … 228 352 if (stSize == 0) 229 353 // malloc(0) called: report error 230 if (G_pMemdLogFunc) 354 LogError(__FUNCTION__ ": Function %s (%s, line %d) called malloc(0).", 355 pcszFunction, 356 pcszSourceFile, 357 ulLine); 358 else 359 if (memdLock()) 231 360 { 232 CHAR szMsg[1000]; 233 sprintf(szMsg, 234 "Function %s (%s, line %d) called malloc(0).", 235 pcszFunction, 236 pcszSourceFile, 237 ulLine); 238 G_pMemdLogFunc(szMsg); 239 } 240 241 if (memdLock()) 242 { 243 // call default malloc(), but with the additional 244 // size of our MEMBLOCKMAGIC strings; we'll return 245 // the first byte after the "front" string so we can 246 // check for string overwrites 247 void *pObj = malloc(stSize 248 + sizeof(MEMBLOCKMAGIC_HEAD) 249 + sizeof(MEMBLOCKMAGIC_TAIL)); 250 if (pObj) 251 { 252 PHEAPITEM pHeapItem = (PHEAPITEM)malloc(sizeof(HEAPITEM)); 253 254 // store "front" magic string 255 memcpy(pObj, 256 MEMBLOCKMAGIC_HEAD, 257 sizeof(MEMBLOCKMAGIC_HEAD)); 258 // return address: first byte after "front" magic string 259 prc = ((PBYTE)pObj) + sizeof(MEMBLOCKMAGIC_HEAD); 260 // store "tail" magic string to block which 261 // will be returned plus the size which was requested 262 memcpy(((PBYTE)prc) + stSize, 263 MEMBLOCKMAGIC_TAIL, 264 sizeof(MEMBLOCKMAGIC_TAIL)); 265 266 if (pHeapItem) 361 // call default malloc(), but with the additional 362 // size of our MEMBLOCKMAGIC strings; we'll return 363 // the first byte after the "front" string so we can 364 // check for string overwrites 365 void *pObj; 366 367 if (pObj = malloc( sizeof(MEMBLOCKMAGIC_HEAD) 368 + stSize 369 + sizeof(MEMBLOCKMAGIC_TAIL))) 267 370 { 268 PTIB ptib; 269 PPIB ppib; 270 271 pHeapItem->pNext = 0; 272 273 pHeapItem->pAfterMagic = prc; 274 pHeapItem->ulSize = stSize; 275 pHeapItem->pcszSourceFile = pcszSourceFile; 276 pHeapItem->ulLine = ulLine; 277 pHeapItem->pcszFunction = pcszFunction; 278 279 DosGetDateTime(&pHeapItem->dtAllocated); 280 281 pHeapItem->ulTID = 0; 282 283 if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR) 284 if (ptib) 285 if (ptib->tib_ptib2) 286 pHeapItem->ulTID = ptib->tib_ptib2->tib2_ultid; 287 288 pHeapItem->fFreed = FALSE; 289 290 // append heap item to linked list 291 if (G_pHeapItemsRoot == NULL) 292 // first item: 293 G_pHeapItemsRoot = pHeapItem; 371 PHEAPITEM pHeapItem; 372 BOOL fInsert = TRUE; 373 374 // store "front" magic string 375 memcpy(pObj, 376 MEMBLOCKMAGIC_HEAD, 377 sizeof(MEMBLOCKMAGIC_HEAD)); 378 // return address: first byte after "front" magic string 379 prc = ((PBYTE)pObj) + sizeof(MEMBLOCKMAGIC_HEAD); 380 // store "tail" magic string to block which 381 // will be returned plus the size which was requested 382 memcpy(((PBYTE)prc) + stSize, 383 MEMBLOCKMAGIC_TAIL, 384 sizeof(MEMBLOCKMAGIC_TAIL)); 385 386 if (!(pHeapItem = FindHeapItem(prc))) 387 // not re-using old address: 388 // create a new heap item 389 pHeapItem = (PHEAPITEM)malloc(sizeof(HEAPITEM)); 294 390 else 295 // we have items already: 296 if (G_pHeapItemsLast) 391 fInsert = FALSE; 392 393 FillHeapItem(pHeapItem, 394 prc, 395 stSize, 396 pcszSourceFile, 397 ulLine, 398 pcszFunction); 399 400 if (fInsert) 401 // append heap item to linked list 402 if (treeInsert(&G_pHeapItemsRoot, 403 &G_cHeapItems, 404 (TREE*)pHeapItem, 405 treeCompareKeys)) 297 406 { 298 // last item cached: 299 G_pHeapItemsLast->pNext = pHeapItem; 300 G_pHeapItemsLast = pHeapItem; 301 } 302 else 303 { 304 // not cached: find end of list 305 PHEAPITEM phi = G_pHeapItemsRoot; 306 while (phi->pNext) 307 phi = phi->pNext; 308 309 phi->pNext = pHeapItem; 310 G_pHeapItemsLast = pHeapItem; 407 LogError(__FUNCTION__ ": treeInsert failed for memory block at 0x%lX.\n" 408 "The block was allocated by %s (%s, line %d).", 409 prc, 410 pcszFunction, 411 pcszSourceFile, 412 ulLine); 311 413 } 312 414 } 415 416 memdUnlock(); 313 417 } 314 315 memdUnlock();316 }317 418 318 419 return (prc); … … 361 462 * 362 463 *@@added V0.9.3 (2000-04-10) [umoeller] 464 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster 363 465 */ 364 466 … … 368 470 const char *pcszFunction) 369 471 { 370 BOOL fFound = FALSE;371 472 if (memdLock()) 372 473 { 373 // PLISTNODE pNode = lstQueryFirstNode(&G_llHeapItems); 374 PHEAPITEM pHeapItem = G_pHeapItemsRoot; 474 PHEAPITEM pHeapItem; 375 475 376 476 // search the list with the pointer which was 377 477 // really returned by the original malloc(), 378 // that is, the byte before the magic string 379 void *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD); 380 381 while (pHeapItem) 478 // that is, the byte after the magic string 479 if (pHeapItem = FindHeapItem(p)) 382 480 { 383 if (pHeapItem->pAfterMagic == p) 481 // the same address may be allocated and freed 482 // several times, so check 483 if (!pHeapItem->fFreed) 384 484 { 385 // the same address may be allocated and freed 386 // several times, so if this address has been 387 // freed, search on 388 if (!pHeapItem->fFreed) 389 { 390 // found: 391 ULONG ulError = 0; 392 // check magic string 393 if (memcmp(pBeforeMagic, 394 MEMBLOCKMAGIC_HEAD, 395 sizeof(MEMBLOCKMAGIC_HEAD)) 396 != 0) 397 ulError = 1; 398 else if (memcmp(((PBYTE)pHeapItem->pAfterMagic) + pHeapItem->ulSize, 399 MEMBLOCKMAGIC_TAIL, 400 sizeof(MEMBLOCKMAGIC_TAIL)) 401 != 0) 402 ulError = 2; 403 404 if (ulError) 405 { 406 // magic block has been overwritten: 407 if (G_pMemdLogFunc) 408 { 409 CHAR szMsg[1000]; 410 sprintf(szMsg, 411 "Magic string %s memory block at 0x%lX has been overwritten.\n" 412 "This was detected by the free() call at %s (%s, line %d).\n" 413 "The block was allocated by %s (%s, line %d).", 414 (ulError == 1) ? "before" : "after", 415 p, 416 pcszFunction, 417 pcszSourceFile, 418 ulLine, // free 419 pHeapItem->pcszFunction, 420 pHeapItem->pcszSourceFile, 421 pHeapItem->ulLine); 422 G_pMemdLogFunc(szMsg); 423 } 424 } 425 426 free(pBeforeMagic); 427 pHeapItem->fFreed = TRUE; 428 429 fFound = TRUE; 430 break; 431 } // if (!pHeapItem->fFreed) 432 } 433 434 pHeapItem = pHeapItem->pNext; 485 // found: 486 void *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD); 487 488 CheckMagics(__FUNCTION__, 489 pHeapItem, 490 p, 491 pcszSourceFile, 492 ulLine, 493 pcszFunction); 494 495 // free the real memory item 496 free(pBeforeMagic); 497 498 // mark the heap item as freed, but 499 // keep it in the list 500 pHeapItem->fFreed = TRUE; 501 502 } // if (!pHeapItem->fFreed) 503 else 504 // memory block has been freed twice: 505 LogError(__FUNCTION__ ": Memory block at 0x%lX has been freed twice.\n" 506 "This was detected by the free() call at %s (%s, line %d).\n" 507 "The block was originally allocated by %s (%s, line %d).", 508 p, 509 pcszFunction, 510 pcszSourceFile, 511 ulLine, // free 512 pHeapItem->pcszFunction, 513 pHeapItem->pcszSourceFile, 514 pHeapItem->ulLine); 435 515 } 516 else 517 // not found: 518 LogError(__FUNCTION__ ": free() called with invalid object 0x%lX from %s (%s, line %d).", 519 p, 520 pcszFunction, 521 pcszSourceFile, 522 ulLine); 436 523 437 524 memdUnlock(); 438 525 } 439 440 if (!fFound)441 if (G_pMemdLogFunc)442 {443 CHAR szMsg[1000];444 sprintf(szMsg,445 "free() called with invalid object from %s (%s, line %d) for object 0x%lX.",446 pcszFunction,447 pcszSourceFile,448 ulLine,449 p);450 G_pMemdLogFunc(szMsg);451 }452 526 } 453 527 … … 459 533 *@@added V0.9.6 (2000-11-12) [umoeller] 460 534 *@@changed V0.9.12 (2001-05-21) [umoeller]: this reported errors on realloc(0), which is a valid call, fixed 535 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster 461 536 */ 462 537 … … 468 543 { 469 544 void *prc = NULL; 470 BOOL fFound = FALSE;471 545 472 546 if (!p) … … 477 551 if (memdLock()) 478 552 { 479 PHEAPITEM pHeapItem = G_pHeapItemsRoot;480 481 553 // search the list with the pointer which was 482 554 // really returned by the original malloc(), 483 // that is, the byte before the magic string 484 void *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD); 485 486 while (pHeapItem) 555 // that is, the byte after the magic string 556 PHEAPITEM pHeapItem, pExisting; 557 if (pHeapItem = FindHeapItem(p)) 487 558 { 488 if (pHeapItem->pAfterMagic == p) 489 // the same address may be allocated and freed 490 // several times, so if this address has been 491 // freed, search on 492 if (!pHeapItem->fFreed) 559 // found: 560 if (pHeapItem->fFreed) 561 { 562 LogError(__FUNCTION__ ": realloc() called with memory block at 0x%lX that was already freed.\n" 563 "This was detected by the realloc() call at %s (%s, line %d).\n" 564 "The block was originally allocated by %s (%s, line %d).", 565 p, 566 pcszFunction, 567 pcszSourceFile, 568 ulLine, // free 569 pHeapItem->pcszFunction, 570 pHeapItem->pcszSourceFile, 571 pHeapItem->ulLine); 572 } 573 else 574 { 575 // block is valid: 576 void *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD); 577 PVOID pObjNew = 0; 578 ULONG ulError = 0; 579 ULONG cbCopy = 0; 580 581 CheckMagics(__FUNCTION__, 582 pHeapItem, 583 p, 584 pcszSourceFile, 585 ulLine, 586 pcszFunction); 587 588 // now reallocate! 589 pObjNew = malloc( sizeof(MEMBLOCKMAGIC_HEAD) 590 + stSize // new size 591 + sizeof(MEMBLOCKMAGIC_TAIL)); 592 593 // store "front" magic string 594 memcpy(pObjNew, 595 MEMBLOCKMAGIC_HEAD, 596 sizeof(MEMBLOCKMAGIC_HEAD)); 597 // return address: first byte after "front" magic string 598 prc = ((PBYTE)pObjNew) + sizeof(MEMBLOCKMAGIC_HEAD); 599 600 // bytes to copy: the smaller of the old and the new size 601 cbCopy = pHeapItem->ulSize; 602 if (stSize < pHeapItem->ulSize) 603 cbCopy = stSize; 604 605 // copy buffer from old memory object 606 memcpy(prc, // after "front" magic 607 p, 608 cbCopy); 609 610 // store "tail" magic string to block which 611 // will be returned plus the size which was requested 612 memcpy(((PBYTE)prc) + stSize, 613 MEMBLOCKMAGIC_TAIL, 614 sizeof(MEMBLOCKMAGIC_TAIL)); 615 616 // free the old buffer 617 free(pBeforeMagic); 618 619 // update the tree, since prc has changed 620 treeDelete(&G_pHeapItemsRoot, 621 &G_cHeapItems, 622 (TREE*)pHeapItem); 623 // append heap item to linked list 624 if (pExisting = FindHeapItem(prc)) 493 625 { 494 // found:495 PVOID pObjNew = 0;496 ULONG ulError = 0;497 ULONG cbCopy = 0;498 PTIB ptib;499 PPIB ppib;500 501 // check magic string502 if (memcmp(pBeforeMagic,503 MEMBLOCKMAGIC_HEAD,504 sizeof(MEMBLOCKMAGIC_HEAD))505 != 0)506 ulError = 1;507 else if (memcmp(((PBYTE)pHeapItem->pAfterMagic) + pHeapItem->ulSize, 508 MEMBLOCKMAGIC_TAIL,509 sizeof(MEMBLOCKMAGIC_TAIL))510 != 0)511 ulError = 2;512 513 if (ulError)626 // a different heap item exists for this address: 627 // delete this one and use that instead; there's 628 // no need to re-insert either 629 free(pHeapItem); 630 pHeapItem = pExisting; 631 } 632 633 FillHeapItem(pHeapItem, 634 prc, 635 stSize, 636 pcszSourceFile, 637 ulLine, 638 pcszFunction); 639 640 // insert only if we didn't use an existing item 641 if (!pExisting) 642 if (treeInsert(&G_pHeapItemsRoot, 643 &G_cHeapItems, 644 (TREE*)pHeapItem, 645 treeCompareKeys)) 514 646 { 515 // magic block has been overwritten: 516 if (G_pMemdLogFunc) 517 { 518 CHAR szMsg[1000]; 519 sprintf(szMsg, 520 "Magic string %s memory block at 0x%lX has been overwritten.\n" 521 "This was detected by the realloc() call at %s (%s, line %d).\n" 522 "The block was allocated by %s (%s, line %d).", 523 (ulError == 1) ? "before" : "after", 524 p, 525 pcszFunction, 526 pcszSourceFile, 527 ulLine, // free 528 pHeapItem->pcszFunction, 529 pHeapItem->pcszSourceFile, 530 pHeapItem->ulLine); 531 G_pMemdLogFunc(szMsg); 532 } 647 LogError(__FUNCTION__ ": treeInsert failed for memory block at 0x%lX.\n" 648 "The block was allocated by %s (%s, line %d).", 649 prc, 650 pcszFunction, 651 pcszSourceFile, 652 ulLine); 533 653 } 534 654 535 // now reallocate! 536 pObjNew = malloc(stSize // new size 537 + sizeof(MEMBLOCKMAGIC_HEAD) 538 + sizeof(MEMBLOCKMAGIC_TAIL)); 539 540 // store "front" magic string 541 memcpy(pObjNew, 542 MEMBLOCKMAGIC_HEAD, 543 sizeof(MEMBLOCKMAGIC_HEAD)); 544 // return address: first byte after "front" magic string 545 prc = ((PBYTE)pObjNew) + sizeof(MEMBLOCKMAGIC_HEAD); 546 547 // bytes to copy: the smaller of the old and the new size 548 cbCopy = pHeapItem->ulSize; 549 if (stSize < pHeapItem->ulSize) 550 cbCopy = stSize; 551 552 // copy buffer from old memory object 553 memcpy(prc, // after "front" magic 554 pHeapItem->pAfterMagic, 555 cbCopy); 556 557 // store "tail" magic string to block which 558 // will be returned plus the size which was requested 559 memcpy(((PBYTE)prc) + stSize, 560 MEMBLOCKMAGIC_TAIL, 561 sizeof(MEMBLOCKMAGIC_TAIL)); 562 563 // free the old buffer 564 free(pBeforeMagic); 565 566 // update the HEAPITEM 567 pHeapItem->pAfterMagic = prc; // new pointer! 568 pHeapItem->ulSize = stSize; // new size! 569 pHeapItem->pcszSourceFile = pcszSourceFile; 570 pHeapItem->ulLine = ulLine; 571 pHeapItem->pcszFunction = pcszFunction; 572 573 // update date, time, TID 574 DosGetDateTime(&pHeapItem->dtAllocated); 575 pHeapItem->ulTID = 0; 576 if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR) 577 if (ptib) 578 if (ptib->tib_ptib2) 579 pHeapItem->ulTID = ptib->tib_ptib2->tib2_ultid; 580 581 fFound = TRUE; 582 break; 583 } // if (!pHeapItem->fFreed) 584 585 pHeapItem = pHeapItem->pNext; 655 } // if (!pHeapItem->fFreed) 586 656 } 657 else 658 LogError(__FUNCTION__ ": realloc() called with invalid object from %s (%s, line %d) for object 0x%lX.", 659 pcszFunction, 660 pcszSourceFile, 661 ulLine, 662 p); 587 663 588 664 memdUnlock(); 589 665 } 590 591 if (!fFound)592 if (G_pMemdLogFunc)593 {594 CHAR szMsg[1000];595 sprintf(szMsg,596 "realloc() called with invalid object from %s (%s, line %d) for object 0x%lX.",597 pcszFunction,598 pcszSourceFile,599 ulLine,600 p);601 G_pMemdLogFunc(szMsg);602 }603 666 604 667 return (prc); … … 624 687 if (memdLock()) 625 688 { 626 PHEAPITEM pHeapItem = G_pHeapItemsRoot, 627 pPrevious = NULL; 689 /* PHEAPITEM pHeapItem = treeFirst(G_pHeapItemsRoot); 628 690 629 691 while (pHeapItem) 630 692 { 631 693 // store next first, because we can change the "next" pointer 632 PHEAPITEM pNext = pHeapItem->pNext; // can be NULL694 PHEAPITEM pNext = treeNext(pHeapItem); 633 695 634 696 if (pHeapItem->fFreed) … … 658 720 pHeapItem = pNext; 659 721 } 660 722 */ 661 723 G_ulItemsReleased += ulItemsReleased; 662 724 G_ulBytesReleased += ulBytesReleased;
Note:
See TracChangeset
for help on using the changeset viewer.