#help_index "Debugging/Heap;Memory/Debugging" #help_file "::/Doc/HeapDbg" #define HL_CALLER_DEPTH 5 //Feel free to change this. #define HL_HASH_SIZE 0x1000 class CHeapLog { CHeapLog *next,*last; union { U8 *addr; I64 size; } I64 cnt; U8 *caller[HL_CALLER_DEPTH]; }; class CHeapLogHash { CHeapLog *next,*last; }; CHeapCtrl *heaplog_hc_watched,*heaplog_hc=NULL; CHeapLogHash *heaplog_head=NULL; U0 HeapLogMAlloc(U8 *addr) { CHeapLog *tmphl; I64 i; if (MHeapCtrl(addr)==heaplog_hc_watched) { tmphl=MAlloc(sizeof(CHeapLog),heaplog_hc); tmphl->addr=addr; for (i=0;icaller[i]=Caller(i+2); i=addr>>3 &(HL_HASH_SIZE-1); PUSHFD CLI while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0)) PAUSE QueIns(tmphl,heaplog_head[i].last); LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0); POPFD } } U0 HeapLogFree(U8 *addr) { I64 i; CHeapLog *tmphl; if (!addr) return; if (MHeapCtrl(addr)==heaplog_hc_watched) { i=addr>>3 &(HL_HASH_SIZE-1); PUSHFD CLI while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0)) PAUSE tmphl=heaplog_head[i].next; while (tmphl!=&heaplog_head[i]) { if (addr==tmphl->addr) { QueRem(tmphl); LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0); POPFD Free(tmphl); return; } tmphl=tmphl->next; } LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0); POPFD } } public Bool HeapLog(Bool val=ON,CTask *task=NULL) {//Turn on. Collect data. Call $LK,"HeapLogAddrRep",A="MN:HeapLogAddrRep"$() or $LK,"HeapLogSizeRep",A="MN:HeapLogSizeRep"$(). I64 i; if (val) { if (Bt(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) { "HeapLog Already Active\n"; return TRUE; } else { if (!task) task=Fs; if (TaskValidate(task)) heaplog_hc_watched=task->data_heap; else heaplog_hc_watched=task;//Actually, not a task, must be a HeapCtrl. PUSHFD CLI while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0)) PAUSE heaplog_hc=HeapCtrlInit(,,sys_data_bp); ext[EXT_HEAPLOG_MALLOC]=&HeapLogMAlloc; ext[EXT_HEAPLOG_FREE]=&HeapLogFree; heaplog_head=MAlloc(sizeof(CHeapLogHash)*HL_HASH_SIZE,heaplog_hc); for (i=0;i>3+hla.caller[0])&(HL_HASH_SIZE-1); tmphls=size_head[k].next; while (tmphls!=&size_head[k]) { if (MSize(hla.addr)==tmphls->size) { for (j=0;jcaller[j]) goto hl_next; tmphls->cnt++; goto hl_found; } hl_next: tmphls=tmphls->next; } tmphls=MAlloc(sizeof(CHeapLog),heaplog_hc); MemCpy(tmphls,&hla,sizeof(CHeapLog)); tmphls->cnt=1; tmphls->size=MSize(hla.addr); QueIns(tmphls,size_head[k].last); hl_found: tmphla=hla.next; } } LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0); for (i=0;inext; "%08X*%08X=%08X",tmphls->size,tmphls->cnt,tmphls->size*tmphls->cnt; for (j=0;jcaller[j]; '\n'; total+=tmphls->size*tmphls->cnt; Free(tmphls); tmphls=tmphls1; } } Free(size_head); "\n$$LTRED$$Total:%08X$$FG$$\n",total; LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0); if (!leave_it) HeapLog(OFF); }