Ignore:
Timestamp:
Dec 14, 2001, 11:41:33 PM (24 years ago)
Author:
umoeller
Message:

Lots of changes for icons and refresh.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/memdebug.c

    r93 r123  
    3232 *         is executed, the system might be in a global memory
    3333 *         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.
    3536 *
    3637 *         These debug functions have been added with V0.9.3
     
    3839 *
    3940 *         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.
    4044 *
    4145 *      -- A PM heap debugging window which shows the status
     
    4953 *
    5054 *      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.
    5257 *
    5358 *         If you don't want those replaced, add
     
    5560 *         before including memdebug.h.
    5661 *
     62 *         To avoid calling a debug function for a single call,
     63 *         place the malloc call (or whatever) in brackets.
     64 *
    5765 *      That's all. XWorkplace's setup.h does this automatically
    5866 *      if XWorkplace is compiled with debug code.
     
    6068 *      A couple of WARNINGS:
    6169 *
    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.
    7176 *
    7277 *      2)  The replacement functions in this file allocate
     
    7681 *          memory overwrites. Two magic strings are allocated,
    7782 *          one before the actual buffer, and one behind it.
     83 *          The pointer returned is _not_ identical to the one
     84 *          that was internally allocated.
    7885 *
    7986 *          As a result, YOU MUST NOT confuse the replacement
     
    119126#include <setjmp.h>
    120127
     128#include "helpers\tree.h"
     129
    121130#define DONT_REPLACE_MALLOC             // never do debug memory for this
    122131#define MEMDEBUG_PRIVATE
     
    125134#ifdef __XWPMEMDEBUG__
    126135
     136#include "helpers\dosh.h"
    127137#include "helpers\except.h"
     138
    128139#include "helpers\memdebug.h"        // included by setup.h already
    129140#include "helpers\stringh.h"
     
    146157#define MEMBLOCKMAGIC_TAIL     "\250\210&%/dfjsk%#,dlhf\223"
    147158
    148 HMTX            G_hmtxMallocList = NULLHANDLE;
    149 
    150 extern PHEAPITEM G_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;
     159HMTX                G_hmtxMallocList = NULLHANDLE;
     160
     161extern TREE         *G_pHeapItemsRoot = NULL;
     162extern LONG         G_cHeapItems = 0;
     163
     164PFNCBMEMDLOG        G_pMemdLogFunc = NULL;
     165
     166extern ULONG        G_ulItemsReleased = 0;
     167extern ULONG        G_ulBytesReleased = 0;
    157168
    158169/* ******************************************************************
     
    175186BOOL memdLock(VOID)
    176187{
    177     APIRET arc = NO_ERROR;
    178     if (G_hmtxMallocList == NULLHANDLE)
     188    if (!G_hmtxMallocList)
     189    {
    179190        // 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    }
    184200    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);
    189205}
    190206
     
    199215{
    200216    DosReleaseMutexSem(G_hmtxMallocList);
     217}
     218
     219/*
     220 *@@ LogError:
     221 *
     222 *@@added V0.9.16 (2001-12-08) [umoeller]
     223 */
     224
     225VOID 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
     246PHEAPITEM 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
     259VOID 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
     289VOID 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    }
    201324}
    202325
     
    217340 *
    218341 *@@added V0.9.3 (2000-04-11) [umoeller]
     342 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster
    219343 */
    220344
     
    228352    if (stSize == 0)
    229353        // 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())
    231360        {
    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)))
    267370            {
    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));
    294390                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))
    297406                    {
    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);
    311413                    }
    312414            }
     415
     416            memdUnlock();
    313417        }
    314 
    315         memdUnlock();
    316     }
    317418
    318419    return (prc);
     
    361462 *
    362463 *@@added V0.9.3 (2000-04-10) [umoeller]
     464 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster
    363465 */
    364466
     
    368470              const char *pcszFunction)
    369471{
    370     BOOL fFound = FALSE;
    371472    if (memdLock())
    372473    {
    373         // PLISTNODE   pNode = lstQueryFirstNode(&G_llHeapItems);
    374         PHEAPITEM pHeapItem = G_pHeapItemsRoot;
     474        PHEAPITEM pHeapItem;
    375475
    376476        // search the list with the pointer which was
    377477        // 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))
    382480        {
    383             if (pHeapItem->pAfterMagic == p)
     481            // the same address may be allocated and freed
     482            // several times, so check
     483            if (!pHeapItem->fFreed)
    384484            {
    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);
    435515        }
     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);
    436523
    437524        memdUnlock();
    438525    }
    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         }
    452526}
    453527
     
    459533 *@@added V0.9.6 (2000-11-12) [umoeller]
    460534 *@@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
    461536 */
    462537
     
    468543{
    469544    void *prc = NULL;
    470     BOOL fFound = FALSE;
    471545
    472546    if (!p)
     
    477551    if (memdLock())
    478552    {
    479         PHEAPITEM pHeapItem = G_pHeapItemsRoot;
    480 
    481553        // search the list with the pointer which was
    482554        // 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))
    487558        {
    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))
    493625                {
    494                     // found:
    495                     PVOID   pObjNew = 0;
    496                     ULONG   ulError = 0;
    497                     ULONG   cbCopy = 0;
    498                     PTIB    ptib;
    499                     PPIB    ppib;
    500 
    501                     // check magic string
    502                     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))
    514646                    {
    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);
    533653                    }
    534654
    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)
    586656        }
     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);
    587663
    588664        memdUnlock();
    589665    }
    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         }
    603666
    604667    return (prc);
     
    624687    if (memdLock())
    625688    {
    626         PHEAPITEM pHeapItem = G_pHeapItemsRoot,
    627                   pPrevious = NULL;
     689        /* PHEAPITEM pHeapItem = treeFirst(G_pHeapItemsRoot);
    628690
    629691        while (pHeapItem)
    630692        {
    631693            // store next first, because we can change the "next" pointer
    632             PHEAPITEM   pNext = pHeapItem->pNext;       // can be NULL
     694            PHEAPITEM   pNext = treeNext(pHeapItem);
    633695
    634696            if (pHeapItem->fFreed)
     
    658720            pHeapItem = pNext;
    659721        }
    660 
     722        */
    661723        G_ulItemsReleased += ulItemsReleased;
    662724        G_ulBytesReleased += ulBytesReleased;
Note: See TracChangeset for help on using the changeset viewer.