home *** CD-ROM | disk | FTP | other *** search
- /* Resource tracking routines, by Karl Lehenbauer
- Lattice version by David Gay.
- This code is in the public domain
- */
-
- /* tracking memory allocator */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <stdio.h>
- #include <string.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- /* comment out the following line if you want locks freed twice reported
- * at the cost of getting spurious resource error messages when
- * reusing the lock */
- /* #define FORGET_LOCKS_WHEN_UNLOCKED */
-
- /* comment out the following line if you want memory freed twice reported
- * at the cost of getting spurious resource error messages when
- * freeing and reallocating memory */
- #define FORGET_MEMORY_WHEN_FREED
-
- /* make sure our invocations of the real routines on behalf of the user
- don't cause us to recurse */
-
- #ifdef AllocMem
- #undef AllocMem
- #undef FreeMem
- #undef AllocSignal
- #undef FreeSignal
- #undef Lock
- #undef UnLock
- #undef DupLock
- #undef ParentDir
- #endif
-
- /* my flags */
- #define FREED_IT 1
-
- struct TrackingAllocMemData
- {
- UBYTE *where; /* address returned by allocator */
- long amount; /* number of bytes allocated */
- long alloc_flags; /* flags passed to allocator */
- char *file; /* filename of caller from the macro */
- int line; /* line number of caller from macro */
- long my_flags; /* flags internal to tracker */
- struct TrackingAllocMemData *next; /* pointer to next entry */
- };
-
- struct TrackingAllocMemData *TrackingAllocMemList = NULL;
- long MemAllocCount = 0, MemFreeCount = 0;
-
- void *TrackingAllocMem(amount,flags,file,line)
- long amount;
- long flags;
- char *file;
- int line;
- {
- struct TrackingAllocMemData *rp;
- UBYTE *users_memory;
-
- /* perform the actual alloc */
- users_memory = AllocMem(amount,flags);
-
- /* if it succeeded, record tracking info */
- if (users_memory)
- {
- MemAllocCount++;
-
- if ((rp = AllocMem((long)sizeof(struct TrackingAllocMemData),0L)) == N
- ULL)
- fprintf(stderr, "tracker: can't alloc memory to record AllocMem da
- ta");
-
- /* add new alloc data entry to linked list */
- rp->next = TrackingAllocMemList;
- TrackingAllocMemList = rp;
-
- /* shove in save values */
- rp->amount = amount;
- rp->alloc_flags = flags;
- rp->where = users_memory;
- rp->file = file;
- rp->line = line;
- rp->my_flags = 0;
- }
- /* return pointer to the space allocated */
- return(users_memory);
- }
-
- void TrackingFreeMem(where,amount,file,line)
- UBYTE *where;
- long amount;
- char *file;
- int line;
- {
- struct TrackingAllocMemData *rp, *op, *freep;
-
- MemFreeCount++;
- /* scan the memory tracking list for a match */
- for (rp = TrackingAllocMemList, op = NULL; rp != NULL; op = rp, rp = rp->ne
- xt)
- {
- /* if we matched the address */
- if (rp->where == where)
- {
- /* if they got the amount wrong, tell them */
- if (rp->amount != amount)
- {
- fprintf(stderr,"freed addr %lx OK but length differs, talloc'e
- d %ld, freed %ld,\n\tallocated at file %s line %d, freed at file %s line %d\n",
- where,rp->amount,amount,rp->file,rp->line,file,line);
- }
- #ifndef FORGET_MEMORY_WHEN_FREED
- /* if it's already free, tell them they freed twice */
- if (rp->my_flags & FREED_IT)
- {
- fprintf(stderr,"freed memory twice at %lx, amount %ld,\n\tallo
- cated in file %s at line %d, freed in file %s at line %d\n",where,amount,rp->fil
- e,rp->line,file,line);
- return;
- }
- else
- {
- /* mark this entry as free */
- rp->my_flags |= FREED_IT;
- }
- #else
- /* remove entry from linked list and free it */
- if (op != NULL) op->next = rp->next;
- else
- TrackingAllocMemList = rp->next;
- freep = rp;
- rp = rp->next;
- FreeMem(freep,(long)sizeof(struct TrackingAllocMemData));
- #endif
- /* Munge memory block */
- memset((char *)where, amount, 3); /* Set to an odd number ... */
- FreeMem(where,(long)amount);
-
- return;
- }
- }
- fprintf(stderr,"Freed memory at %lx of amount %ld that wasn't allocated,\n\
- tfreed at file %s line %d\n",where,amount,file,line);
- FreeMem(where,amount);
- }
-
- void ReportUnfreedMemory()
- {
- struct TrackingAllocMemData *rp = TrackingAllocMemList, *freep;
-
- while (rp != NULL)
- {
- if (!(rp->my_flags & FREED_IT))
- {
- fprintf(stderr,"FreeMem was never called for memory at %lx, amount
- %ld,\n\tthe alloc was performed at file %s line %d\n",rp->where,rp->amount,rp->
- file,rp->line);
- }
- freep = rp;
- rp = rp->next;
- FreeMem(freep,(long)sizeof(struct TrackingAllocMemData));
- }
- printf("Total tracked AllocMem calls %ld, FreeMem calls %ld\n",MemAllocCoun
- t,MemFreeCount);
- }
-
-
- /* track signals */
- /* tracking AllocSignal doesn't currently track where it was called from */
-
- long TrackingSignalMask = 0;
- long SignalAllocCount = 0, SignalFreeCount = 0;
-
- long TrackingAllocSignal(signal_num,file,line)
- long signal_num;
- char *file;
- int line;
- {
- SignalAllocCount++;
-
- signal_num = AllocSignal(signal_num);
-
- if (signal_num != -1)
- TrackingSignalMask |= (1 << signal_num);
-
- return(signal_num);
- }
-
- void TrackingFreeSignal(signal_num,file,line)
- long signal_num;
- char *file;
- int line;
- {
- SignalFreeCount++;
-
- if (!(TrackingSignalMask & (1 << signal_num)))
- {
- fprintf(stderr, "freed a signal (%ld) that was never allocated, at fil
- e %s line %d\n",
- signal_num,file,line);
- }
- TrackingSignalMask &= ~(1 << signal_num);
- }
-
- void ReportUnfreedSignals()
- {
- if (TrackingSignalMask)
- fprintf(stderr, "failed to free signals indicated by this mask: %8lx\n
- ",
- TrackingSignalMask);
- printf("Total tracked AllocSignal calls %ld, FreeSignal calls %ld\n",Signal
- AllocCount,SignalFreeCount);
- }
-
- /* tracking lock and unlock */
-
- struct TrackingLockData
- {
- BPTR lock; /* lock returned by Lock */
- char *name; /* name of file that was locked */
- long accessMode; /* access mode of the file that was locked */
- char *file; /* ptr to file name of line of caller */
- int line; /* ptr to line number text of locker */
- long my_flags; /* flags internal to tracker */
- struct TrackingLockData *next; /* pointer to next entry */
- };
-
- /* flags */
- #define CREATED_BY_DUPLOCK 1
-
- struct TrackingLockData *TrackingLockList = NULL;
- long TrackerLockCount = 0, TrackerUnLockCount = 0;
-
- BPTR TheTrackingLock(name, accessMode, file, line)
- char *name;
- long accessMode;
- char *file;
- int line;
- {
- struct TrackingLockData *lp;
- BPTR users_lock;
-
- users_lock = Lock(name, (long)accessMode);
-
- if (users_lock)
- {
- TrackerLockCount++;
-
- if ((lp = AllocMem((long)sizeof(struct TrackingLockData),0L)) == NULL)
-
- fprintf(stderr, "tracker: can't alloc memory to record lock data")
- ;
-
- /* add new alloc data entry to linked list */
- lp->next = TrackingLockList;
- TrackingLockList = lp;
-
- /* shove in save values */
- lp->accessMode = accessMode;
- lp->file = file;
- lp->line = line;
- lp->my_flags = 0;
- lp->lock = users_lock;
-
- /* alloc space for filename and save */
- if ((lp->name = AllocMem((long)(strlen(name)+1),0L)) == NULL)
- fprintf(stderr, "tracker: can't alloc memory to record lock filena
- me");
- strcpy(lp->name,name);
- }
- return(users_lock);
- }
-
- BPTR TheTrackingDupLock(lock, file, line)
- BPTR lock;
- char *file;
- int line;
- {
- struct TrackingLockData *lp;
- BPTR users_lock;
-
- users_lock = DupLock(lock);
-
- if (users_lock)
- {
- TrackerLockCount++;
-
- if ((lp = AllocMem((long)sizeof(struct TrackingLockData),0L)) == NULL)
-
- fprintf(stderr, "tracker: can't alloc memory to record lock data")
- ;
-
- /* add new alloc data entry to linked list */
- lp->next = TrackingLockList;
- TrackingLockList = lp;
-
- lp->file = file;
- lp->line = line;
- lp->name = NULL;
- lp->lock = users_lock;
- lp->my_flags = CREATED_BY_DUPLOCK;
- }
- return(users_lock);
- }
-
- void TheTrackingUnLock(lock,file,line)
- BPTR lock;
- char *file;
- int line;
- {
- struct TrackingLockData *lp, *op, *freep;
-
- TrackerUnLockCount++;
-
- /* scan the lock tracking list for a match */
- for (lp = TrackingLockList, op = NULL; lp != NULL; op = lp, lp = lp->next)
- {
- /* if we matched the lock */
- if (lp->lock == lock)
- {
- #ifndef FORGET_LOCKS_WHEN_UNLOCKED
- /* if it's already free, tell them they freed twice */
- if (lp->my_flags & FREED_IT)
- {
- fprintf(stderr,"freed lock twice, lock %lx, filename %s\n\tloc
- ked at file %s line %d, freed at file %s line %d\n",lock,lp->name,lp->file,lp->l
- ine,file,line);
- return;
- }
- else
- {
- /* mark this entry as free */
- lp->my_flags |= FREED_IT;
- }
- #else
- if (op != NULL) op->next = lp->next;
- else TrackingLockList = lp->next;
- freep = lp;
- lp = lp->next;
- if (lp->name != NULL)
- FreeMem(lp->name,(long)(strlen(lp->name)+1));
- FreeMem(freep,(long)(sizeof(struct TrackingLockData)));
- #endif
- UnLock(lock);
- return;
- }
- }
- fprintf(stderr,"Freed lock %lx that hadn't been allocated at file %s line %
- d\n",lock,file,line);
- }
-
- BPTR TheTrackingParentDir(BPTR lock, char *file, int line)
- {
- struct TrackingLockData *lp;
- BPTR users_lock;
-
- users_lock = ParentDir(lock);
-
- if (users_lock)
- {
- TrackerLockCount++;
-
- if ((lp = AllocMem((long)sizeof(struct TrackingLockData),0L)) == NULL)
-
- fprintf(stderr, "tracker: can't alloc memory to record lock data")
- ;
-
- /* add new alloc data entry to linked list */
- lp->next = TrackingLockList;
- TrackingLockList = lp;
-
- /* shove in save values */
- lp->accessMode = 0;
- lp->file = file;
- lp->line = line;
- lp->my_flags = 0;
- lp->lock = users_lock;
- lp->name = NULL;
- }
- return(users_lock);
- }
-
- void ReportUnfreedLocks()
- {
- struct TrackingLockData *lp = TrackingLockList, *freep;
-
- while (lp != NULL)
- {
- if (!(lp->my_flags & FREED_IT))
- {
- if (lp->my_flags & CREATED_BY_DUPLOCK)
- {
- fprintf(stderr,"UnLock was never called for lock %lx,\n\It was
- created by DupLock at file %s line %d\n",lp->lock,lp->file,lp->line);
- }
- else
- {
- fprintf(stderr,"UnLock was never called for lock %lx,\n\It was
- created by a Lock of %s\nat file %s line %d\n",lp->lock,lp->name,lp->file,lp->l
- ine);
- }
- }
- if (lp->name != NULL)
- FreeMem(lp->name,(long)(strlen(lp->name)+1));
- freep = lp;
- lp = lp->next;
- FreeMem(freep,(long)sizeof(struct TrackingLockData));
- }
- printf("Total tracked Lock and DupLock calls %ld, UnLock calls %ld\n",Track
- erLockCount,TrackerUnLockCount);
- }
-
- void TrackerExitReport()
- {
- ReportUnfreedMemory();
- ReportUnfreedLocks();
- ReportUnfreedSignals();
- }
-