static int descCmp(const void* p1, const void* p2) { memTableEntry* m1 = *(memTableEntry**)p1; memTableEntry* m2 = *(memTableEntry**)p2; int val = strcmp(chpl_mem_descString(m1->description), chpl_mem_descString(m2->description)); if (val == 0 && m1->filename && m2->filename) val = strcmp(m1->filename, m2->filename); if (val == 0) val = (m1->lineno < m2->lineno) ? -1 : ((m1->lineno > m2->lineno) ? 1 : 0); return val; }
static chpl_mem_descInt_t find_desc(const char* descString) { const int numEntries = CHPL_RT_MD_NUM+chpl_mem_numDescs; for (chpl_mem_descInt_t i = 0; i < numEntries; ++i) if (! strcmp(descString, chpl_mem_descString(i))) return i; return -1; }
static void printMemAllocsByType(_Bool forLeaks, int32_t lineno, int32_t filename) { size_t* table; memTableEntry* me; int i; const int numberWidth = 9; const int numEntries = CHPL_RT_MD_NUM+chpl_mem_numDescs; if (!chpl_memTrack) { chpl_warning("invalid call to printMemAllocsByType(); rerun with " "--memTrack", lineno, filename); return; } table = (size_t*)sys_calloc(numEntries, 3*sizeof(size_t)); for (i = 0; i < hashSize; i++) { for (me = memTable[i]; me != NULL; me = me->nextInBucket) { table[3*me->description] += me->number*me->size; table[3*me->description+1] += 1; table[3*me->description+2] = me->description; } } qsort(table, numEntries, 3*sizeof(size_t), memTableEntryCmp); if (forLeaks) { fprintf(memLogFile, "====================\n"); fprintf(memLogFile, "Leaked Memory Report\n"); fprintf(memLogFile, "==============================================================\n"); fprintf(memLogFile, "Number of leaked allocations\n"); fprintf(memLogFile, " Total leaked memory (bytes)\n"); } else { fprintf(memLogFile, "================================\n"); fprintf(memLogFile, "Memory Allocation Report by Type\n"); fprintf(memLogFile, "==============================================================\n"); fprintf(memLogFile, "Number of allocations\n"); fprintf(memLogFile, " Total allocated bytes\n"); } fprintf(memLogFile, " Description of allocation\n"); fprintf(memLogFile, "==============================================================\n"); for (i = 0; i < 3*(CHPL_RT_MD_NUM+chpl_mem_numDescs); i += 3) { if (table[i] > 0) { fprintf(memLogFile, "%-*zu %-*zu %s\n", numberWidth, table[i+1], numberWidth, table[i], chpl_mem_descString(table[i+2])); } } fprintf(memLogFile, "==============================================================\n"); sys_free(table); }
void chpl_memhook_check_post(void* memAlloc, chpl_mem_descInt_t description, int32_t lineno, c_string filename) { if (memAlloc == NULL) { const int messageSize = 1024; char message[messageSize]; snprintf(message, messageSize, "Out of memory allocating \"%s\"", chpl_mem_descString(description)); chpl_error(message, lineno, filename); } }
void chpl_track_malloc(void* memAlloc, size_t number, size_t size, chpl_mem_descInt_t description, int32_t lineno, int32_t filename) { if (number * size > memThreshold) { if (chpl_memTrack && chpl_mem_descTrack(description)) { memTrack_lock(); addMemTableEntry(memAlloc, number, size, description, lineno, filename); memTrack_unlock(); } if (chpl_verbose_mem) { fprintf(memLogFile, "%" PRI_c_nodeid_t ": %s:%" PRId32 ": allocate %zuB of %s at %p\n", chpl_nodeID, (filename ? chpl_lookupFilename(filename) : "--"), lineno, number * size, chpl_mem_descString(description), memAlloc); } } }
void chpl_track_malloc(void* memAlloc, size_t number, size_t size, chpl_mem_descInt_t description, int32_t lineno, c_string filename) { if (number * size > memThreshold) { if (chpl_memTrack) { chpl_sync_lock(&memTrack_sync); addMemTableEntry(memAlloc, number, size, description, lineno, filename); chpl_sync_unlock(&memTrack_sync); } if (chpl_verbose_mem) { fprintf(memLogFile, "%" FORMAT_c_nodeid_t ": %s:%" PRId32 ": allocate %zuB of %s at %p\n", chpl_nodeID, (filename ? filename : "--"), lineno, number*size, chpl_mem_descString(description), memAlloc); } } }
void chpl_track_free(void* memAlloc, int32_t lineno, int32_t filename) { memTableEntry* memEntry = NULL; if (chpl_memTrack) { memTrack_lock(); memEntry = removeMemTableEntry(memAlloc); if (memEntry) { if (chpl_verbose_mem) { fprintf(memLogFile, "%" PRI_c_nodeid_t ": %s:%" PRId32 ": free %zuB of %s at %p\n", chpl_nodeID, (filename ? chpl_lookupFilename(filename) : "--"), lineno, memEntry->number * memEntry->size, chpl_mem_descString(memEntry->description), memAlloc); } sys_free(memEntry); } memTrack_unlock(); } else if (chpl_verbose_mem && !memEntry) { fprintf(memLogFile, "%" PRI_c_nodeid_t ": %s:%" PRId32 ": free at %p\n", chpl_nodeID, (filename ? chpl_lookupFilename(filename) : "--"), lineno, memAlloc); } }
void chpl_printLeakedMemTable(void) { size_t* table; memTableEntry* me; int i; const int numberWidth = 9; const int numEntries = CHPL_RT_MD_NUM+chpl_mem_numDescs; table = (size_t*)calloc(numEntries, 3*sizeof(size_t)); for (i = 0; i < hashSize; i++) { for (me = memTable[i]; me != NULL; me = me->nextInBucket) { table[3*me->description] += me->number*me->size; table[3*me->description+1] += 1; table[3*me->description+2] = me->description; } } qsort(table, numEntries, 3*sizeof(size_t), leakedMemTableEntryCmp); fprintf(memLogFile, "====================\n"); fprintf(memLogFile, "Leaked Memory Report\n"); fprintf(memLogFile, "==============================================================\n"); fprintf(memLogFile, "Number of leaked allocations\n"); fprintf(memLogFile, " Total leaked memory (bytes)\n"); fprintf(memLogFile, " Description of allocation\n"); fprintf(memLogFile, "==============================================================\n"); for (i = 0; i < 3*(CHPL_RT_MD_NUM+chpl_mem_numDescs); i += 3) { if (table[i] > 0) { fprintf(memLogFile, "%-*zu %-*zu %s\n", numberWidth, table[i+1], numberWidth, table[i], chpl_mem_descString(table[i+2])); } } fprintf(memLogFile, "==============================================================\n"); free(table); }
void chpl_track_free(void* memAlloc, int32_t lineno, c_string filename) { memTableEntry* memEntry = NULL; if (chpl_memTrack) { chpl_sync_lock(&memTrack_sync); memEntry = removeMemTableEntry(memAlloc); if (memEntry) { if (chpl_verbose_mem) { fprintf(memLogFile, "%" FORMAT_c_nodeid_t ": %s:%" PRId32 ": free %zuB of %s at %p\n", chpl_nodeID, (filename ? filename : "--"), lineno, memEntry->number*memEntry->size, chpl_mem_descString(memEntry->description), memAlloc); } free(memEntry); } chpl_sync_unlock(&memTrack_sync); } else if (chpl_verbose_mem && !memEntry) { fprintf(memLogFile, "%" FORMAT_c_nodeid_t ": %s:%" PRId32 ": free at %p\n", chpl_nodeID, (filename ? filename : "--"), lineno, memAlloc); } }
static void printMemAllocs(chpl_mem_descInt_t description, int64_t threshold, int32_t lineno, int32_t filename) { const int numberWidth = 9; const int precision = sizeof(uintptr_t) * 2; const int addressWidth = precision+4; const int descWidth = 33; int filenameWidth = strlen("Allocated Memory (Bytes)"); int totalWidth; int filenameLength; memTableEntry* memEntry; c_string memEntryFilename; int n, i; char* loc; memTableEntry** table; if (!chpl_memTrack) { chpl_warning("invalid call to printMemAllocs(); rerun with --memTrack", lineno, filename); return; } n = 0; filenameWidth = strlen("Allocated Memory (Bytes)"); for (i = 0; i < hashSize; i++) { for (memEntry = memTable[i]; memEntry != NULL; memEntry = memEntry->nextInBucket) { size_t chunk = memEntry->number * memEntry->size; if (chunk < threshold) continue; if (description != -1 && memEntry->description != description) continue; n += 1; if (memEntry->filename) { memEntryFilename = chpl_lookupFilename(memEntry->filename); filenameLength = strlen(memEntryFilename); if (filenameLength > filenameWidth) filenameWidth = filenameLength; } } } totalWidth = filenameWidth+numberWidth*4+descWidth+20; for (i = 0; i < totalWidth; i++) fprintf(memLogFile, "="); fprintf(memLogFile, "\n"); fprintf(memLogFile, "%-*s%-*s%-*s%-*s%-*s%-*s\n", filenameWidth+numberWidth, "Allocated Memory (Bytes)", numberWidth, "Number", numberWidth, "Size", numberWidth, "Total", descWidth, "Description", 20, "Address"); for (i = 0; i < totalWidth; i++) fprintf(memLogFile, "="); fprintf(memLogFile, "\n"); table = (memTableEntry**)sys_malloc(n*sizeof(memTableEntry*)); if (!table) chpl_error("out of memory printing memory table", lineno, filename); n = 0; for (i = 0; i < hashSize; i++) { for (memEntry = memTable[i]; memEntry != NULL; memEntry = memEntry->nextInBucket) { size_t chunk = memEntry->number * memEntry->size; if (chunk < threshold) continue; if (description != -1 && memEntry->description != description) continue; table[n++] = memEntry; } } qsort(table, n, sizeof(memTableEntry*), descCmp); loc = (char*)sys_malloc((filenameWidth+numberWidth+1)*sizeof(char)); for (i = 0; i < n; i++) { memEntry = table[i]; if (memEntry->filename) { memEntryFilename = chpl_lookupFilename(memEntry->filename); sprintf(loc, "%s:%" PRId32, memEntryFilename, memEntry->lineno); } else { sprintf(loc, "--"); } fprintf(memLogFile, "%-*s%-*zu%-*zu%-*zu%-*s%#-*.*" PRIxPTR "\n", filenameWidth+numberWidth, loc, numberWidth, memEntry->number, numberWidth, memEntry->size, numberWidth, memEntry->size*memEntry->number, descWidth, chpl_mem_descString(memEntry->description), addressWidth, precision, (uintptr_t)memEntry->memAlloc); } for (i = 0; i < totalWidth; i++) fprintf(memLogFile, "="); fprintf(memLogFile, "\n"); putchar('\n'); sys_free(table); sys_free(loc); }
void chpl_printMemTable(int64_t threshold, int32_t lineno, c_string filename) { const int numberWidth = 9; const int precision = sizeof(uintptr_t) * 2; const int addressWidth = precision+4; const int descWidth = 33; int filenameWidth = strlen("Allocated Memory (Bytes)"); int totalWidth; memTableEntry* memEntry; int n, i; char* loc; memTableEntry** table; if (!chpl_memTrack) chpl_error("The printMemTable function only works with the --memTrack flag", lineno, filename); n = 0; filenameWidth = strlen("Allocated Memory (Bytes)"); for (i = 0; i < hashSize; i++) { for (memEntry = memTable[i]; memEntry != NULL; memEntry = memEntry->nextInBucket) { size_t chunk = memEntry->number * memEntry->size; if (chunk >= threshold) { n += 1; if (memEntry->filename) { int filenameLength = strlen(memEntry->filename); if (filenameLength > filenameWidth) filenameWidth = filenameLength; } } } } totalWidth = filenameWidth+numberWidth*4+descWidth+20; for (i = 0; i < totalWidth; i++) fprintf(memLogFile, "="); fprintf(memLogFile, "\n"); fprintf(memLogFile, "%-*s%-*s%-*s%-*s%-*s%-*s\n", filenameWidth+numberWidth, "Allocated Memory (Bytes)", numberWidth, "Number", numberWidth, "Size", numberWidth, "Total", descWidth, "Description", 20, "Address"); for (i = 0; i < totalWidth; i++) fprintf(memLogFile, "="); fprintf(memLogFile, "\n"); table = (memTableEntry**)malloc(n*sizeof(memTableEntry*)); if (!table) chpl_error("out of memory printing memory table", lineno, filename); n = 0; for (i = 0; i < hashSize; i++) { for (memEntry = memTable[i]; memEntry != NULL; memEntry = memEntry->nextInBucket) { size_t chunk = memEntry->number * memEntry->size; if (chunk >= threshold) { table[n++] = memEntry; } } } qsort(table, n, sizeof(memTableEntry*), descCmp); loc = (char*)malloc((filenameWidth+numberWidth+1)*sizeof(char)); for (i = 0; i < n; i++) { memEntry = table[i]; if (memEntry->filename) sprintf(loc, "%s:%"PRId32, memEntry->filename, memEntry->lineno); else sprintf(loc, "--"); fprintf(memLogFile, "%-*s%-*zu%-*zu%-*zu%-*s%#-*.*" PRIxPTR "\n", filenameWidth+numberWidth, loc, numberWidth, memEntry->number, numberWidth, memEntry->size, numberWidth, memEntry->size*memEntry->number, descWidth, chpl_mem_descString(memEntry->description), addressWidth, precision, (uintptr_t)memEntry->memAlloc); } for (i = 0; i < totalWidth; i++) fprintf(memLogFile, "="); fprintf(memLogFile, "\n"); putchar('\n'); free(table); free(loc); }