void * mem_calloc_func(size_t count, size_t size #if defined(MEMDBG_ON) , char * file, int line #endif ) { void * res; if (!count || !size) return NULL; #if defined(MEMDBG_ON) size *= count; res = (char *) MEMDBG_alloc(size, file, line); memset(res, 0, size); #else res = calloc(count, size); #endif if (!res) { fprintf(stderr, "mem_calloc(): %s trying to allocate " Zu " bytes\n", strerror(ENOMEM), count * size); MEMDBG_PROGRAM_EXIT_CHECKS(stderr); perror("mem_calloc"); } return res; }
void * MEMDBG_calloc(size_t size, char *file, int line) { char *p; if ( ((signed long long)mem_size) < 0) fprintf(stderr, "MEMDBG_calloc %lld %s:%d mem:%lld\n", (unsigned long long)size, file, line, (unsigned long long)mem_size); p = (char*)MEMDBG_alloc(size,file,line); memset(p, 0, size); return p; }
/* * MEMDBG_strdup * Duplicate a ASCIIZ string in memory, with a protected call to strdup, * allocating extra data, and adding data to all required structures. */ char *MEMDBG_strdup(const char *str, char *file, int line) { char * s; if ( ((signed long long)mem_size) < 0) fprintf(stderr, "MEMDBG_strdup(%ld) %s:%d mem:%lld\n", strlen(str), file, line, (unsigned long long)mem_size); s = (char*)MEMDBG_alloc(strlen(str)+1, file, line); if (s != NULL) strcpy(s, str); return s; }
void * MEMDBG_calloc(size_t count, size_t size, char *file, int line) { char *p; size *= count; if ( ((signed long long)mem_size) < 0) fprintf(stderr, "MEMDBG_calloc "LLd" %s:%d mem:"LLd"\n", (unsigned long long)size, file, line, (unsigned long long)mem_size); p = (char*)MEMDBG_alloc(size,file,line); memset(p, 0, size); return p; }
/* * MEMDBG_realloc * Reallocate a memory block makes a protected call to realloc(), allocating * extra data, and adding data to all required structures. * *** realloc is a NASTY function. The code here has taken a few turns, * trying to handle all of the nuances of this function, and how we hook it, * and how we deal with trying to not free data (if in MEMDBG_EXTRA_CHECKS mode) */ void * MEMDBG_realloc(const void *ptr, size_t size, char *file, int line) { MEMDBG_HDR *p; int istiny=0; int err=0, i; if ( ((signed long long)mem_size) < 0) fprintf(stderr, "MEMDBG_realloc(%lld) %s:%d mem:%lld\n", (unsigned long long)size, file, line, (unsigned long long)mem_size); /* if ptr is null, this function works just like alloc, so simply use alloc */ if (!ptr) return MEMDBG_alloc(size, file, line); #ifdef _OPENMP #pragma omp critical #endif { p = CLIENT_2_HDR(ptr); if (p->mdbg_fpst == MEMFPOSTt) istiny = 1; else if (p->mdbg_fpst != MEMFPOST) err = 1; else { for (i = 0; i < 4; ++i) if (((char*)(p->mdbg_hdr2->mdbg_fpst))[i] != cpMEMFPOST[i]) { err = 1; break; } } if (err) { if (p->mdbg_fpst == MEMFPOSTd) err = 2; else { for (i = 0; i < 4; ++i) if (((char*)(p->mdbg_hdr2->mdbg_fpst))[i] != cpMEMFPOSTd[i]) { break; } if (i < 4) err = 2; } } } if (err) { if (err == 2) mem_fence_post_errd(p, file, line); else mem_fence_post_err(p, file, line); return NULL; } /* if size == 0, this function works exactly like free, so just use free */ if (!size) { /* NOTE, use ptr, and NOT p */ MEMDBG_free(ptr, file, line); return NULL; } p->mdbg_fpst = MEMFPOSTd; memcpy(p->mdbg_hdr2->mdbg_fpst, cpMEMFPOSTd, 4); #ifdef _OPENMP #pragma omp critical (memdbg_crit) #endif { if (istiny) mem_sizet -= p->mdbg_size; else mem_size -= p->mdbg_size; MEMDBG_LIST_delete(p); } #ifdef MEMDBG_EXTRA_CHECKS if (size > p->mdbg_size) { void *p2 = MEMDBG_alloc(size, file, line); if (p2) { if (istiny) MEMDBG_tag_mem_from_alloc_tiny(p); memcpy(p2, ((char*)p)+RESERVE_SZ, p->mdbg_size); /* we had to keep the original data 'clean' until now. * but Now, we can put it on free list (which smashes * the original memory block */ MEMDBG_FREEDLIST_add(p); return p2; } /* We have to undo the MEMDBG_LIST_delete(p); because realloc should * leave the ORIGINAL buffer alone, if we can not allocate more * memory. Thus we need to 'leave' the leak alone. This is a leak * unless the client code frees the original pointer. 'undoing' the * MEMDBG_LIST_delete(p) keeps our code knowing this is a lost pointer. */ p->mdbg_fpst = MEMFPOST; memcpy(p->mdbg_hdr2, cpMEMFPOST, 4); #ifdef _OPENMP #pragma omp critical (memdbg_crit) #endif { mem_size += p->mdbg_size; if (mem_size > max_mem_size) max_mem_size = mem_size; MEMDBG_LIST_add(p); } if (istiny) MEMDBG_tag_mem_from_alloc_tiny(p); return NULL; } /* NOTE, it is assumed that the memory will NOT be freed, so we simply drop through, and allow normal realloc to work, and DO NOT try to put anything onto the FREEDLIST, since it will just be the same block */ #endif p = (MEMDBG_HDR *) realloc(p, RESERVE_SZ + size + 4); #ifdef MEMDBG_EXTRA_CHECKS #ifdef _OPENMP { int i = 0; do { #pragma omp critical (memdbg_crit) { if (!p && freed_mem_size > (RESERVE_SZ + size + 4) && !p && freed_cnt) i = 1; } if (i) { release_oldest_freed_block(); p = (MEMDBG_HDR*)realloc(CLIENT_2_HDR(ptr), RESERVE_SZ + size + 4); } } while (i && !p); } #else /* this is the 'right' block, but hard to do with the restrictions of no branching out that omp critical places on us */ if (!p && freed_mem_size > (RESERVE_SZ + size + 4)) { while (!p && freed_cnt) { release_oldest_freed_block(); p = (MEMDBG_HDR*)realloc(CLIENT_2_HDR(ptr), RESERVE_SZ + size + 4); } } #endif #endif if (!p) { /* We have to undo the MEMDBG_LIST_delete(p); because realloc should * leave the ORIGINAL buffer alone, if we can not allocate more * memory. Thus we need to 'leave' the leak alone. */ p = CLIENT_2_HDR(ptr); /* we have to get 'original' pointer again */ p->mdbg_fpst = MEMFPOST; memcpy(p->mdbg_hdr2, cpMEMFPOST, 4); #ifdef _OPENMP #pragma omp critical (memdbg_crit) #endif { mem_size += p->mdbg_size; if (mem_size > max_mem_size) max_mem_size = mem_size; MEMDBG_LIST_add(p); } if (istiny) MEMDBG_tag_mem_from_alloc_tiny(p); return NULL; } p->mdbg_fpst = MEMFPOST; p->mdbg_size = size; p->mdbg_file = file; p->mdbg_line = line; p->mdbg_hdr2 = (MEMDBG_HDR2*)(((char*)p)+RESERVE_SZ + size); memcpy(p->mdbg_hdr2, cpMEMFPOST, 4); #ifdef _OPENMP #pragma omp critical (memdbg_crit) #endif { p->mdbg_cnt = ++alloc_cnt; mem_size += size; if (mem_size > max_mem_size) max_mem_size = mem_size; MEMDBG_LIST_add(p); } if (istiny) MEMDBG_tag_mem_from_alloc_tiny(p); return HDR_2_CLIENT(p); }