📄 memory.c
字号:
* @addr: address
* @filen: new filename
* @line: new allocation line
*
* Coerces information in allocation table about allocation file and
* line to be @filen and @line. This is used by the evil
* block_alloc() and should probably not be used anywhere else ever.
**/
void
xclaim(void *addr, const char *filen, int line)
{
alloc_blk *m;
chk_header *ch;
ch = ((chk_header *)addr) - 1;
m = mem_item_find(ch->key);
if (chk_header_okay(ch) == FALSE) {
fprintf(stderr, "xclaim: memory corrupted\n");
abort();
}
if (m == NULL) {
fprintf(stderr, "xclaim: block not found\n");
abort();
}
free(m->filen);
m->filen = strdup(filen);
m->length = strlen(filen);
m->line = line;
m->est = tick++;
}
/**
* xmemdist:
* @fp: file pointer
*
* Dumps information on existing memory allocations to file.
**/
void
xmemdist(FILE *fp)
{
int i, last_line=-1, cnt=0, entry=0;
char *last_filen = NULL;
/* This is painful...I don't actually envisage running beyond this dump :-)
* 2 sorts are needed, one into order by file, and then back to key order.
*/
qsort(mem_item, naddr, sizeof(mem_item[0]), alloc_blk_cmp_origin);
fprintf(fp, "# Distribution of memory allocated\n# <idx> <file> <line> <allocations>\n");
for(i = 0; i < naddr; i++) {
if (last_filen == NULL ||
last_line != mem_item[i].line ||
strcmp(last_filen, mem_item[i].filen)) {
if (last_filen != NULL) {
fprintf(fp, "% 3d\n", cnt);
}
cnt = 0;
last_filen = mem_item[i].filen;
last_line = mem_item[i].line;
fprintf(fp, "% 3d %20s % 4d ", entry, last_filen, last_line);
entry++;
}
cnt++;
}
fprintf(fp, "% 3d\n", cnt);
/* Restore order */
qsort(mem_item, naddr, sizeof(mem_item[0]), mem_key_cmp);
}
/**
* xfree:
* @p: pointer to block to freed.
*
* Free block of memory. Semantically equivalent to free(), but
* checks for bounds overruns in @p and tidies up state associated
* additional functionality.
*
* Must be used to free memory allocated with xmalloc(), xrealloc(),
* and xstrdup().
**/
void
xfree(void *p)
{
alloc_blk *m;
chk_header *ch;
uint32_t size, delta, magic, idx;
if (p == NULL) {
printf("ERROR: Attempt to free NULL pointer!\n");
abort();
}
ch = ((chk_header*)p) - 1;
printf("free at %p\n", ch);
/* Validate entry */
if (chk_header_okay(ch) == FALSE) {
printf("ERROR: Freeing corrupted block\n");
abort();
}
/* Locate in table */
m = mem_item_find(ch->key);
if (m == NULL) {
printf("ERROR: Freeing unallocated or already free'd block\n");
abort();
}
/* Trash memory of allocated block, maybe noticed by apps when
* deref'ing free'd */
size = ch->size + sizeof(chk_header) + MAGIC_MEMORY_SIZE;
magic = MAGIC_MEMORY;
p = (uint8_t*)ch;
while (size > 0) {
delta = min(size, 4);
memcpy(p, &magic, delta);
(uint8_t*)p += delta;
size -= delta;
}
/* Free memory */
free(ch);
free(m->filen);
/* Remove from table */
idx = m - mem_item;
if (naddr - idx > 0) {
memmove(&mem_item[idx],
&mem_item[idx + 1],
(naddr - idx - 1) * sizeof(alloc_blk));
}
naddr--;
xmemchk();
}
void *
_xmalloc(unsigned size, const char *filen, int line)
{
uint32_t *data;
void *p;
chk_header *ch;
p = (void*) malloc (size + sizeof(chk_header) + MAGIC_MEMORY_SIZE);
ASSERT(p != NULL);
ASSERT(filen != NULL);
/* Fix block header */
ch = (chk_header*)p;
ch->key = tick++;
ch->size = size;
ch->magic = MAGIC_MEMORY;
data = (uint32_t*)((chk_header *)p + 1);
#if 0
memset((void*)data, 0xf0, size);
#else
memset((void*)data, 0, size);
#endif
/* Fix block tail */
memcpy(((uint8_t*)data) + size, &ch->magic, MAGIC_MEMORY_SIZE);
/* Check set up okay */
if (chk_header_okay(ch) == FALSE) {
fprintf(stderr, "Implementation Error\n");
abort();
}
/* Add table entry */
mem_item[naddr].key = ch->key;
mem_item[naddr].addr = p;
mem_item[naddr].filen = (char *)strdup(filen);
mem_item[naddr].line = line;
mem_item[naddr].length = strlen(filen);
mem_item[naddr].blen = 0; /* block_alloc'ed len when appropriate */
mem_item[naddr].est = ch->key; /* changes when block_alloc recycles block */
naddr ++;
if (naddr >= MAX_ADDRS) {
fprintf(stderr, "ERROR: Allocated too much! Table overflow in xmalloc()\n");
fprintf(stderr, " Do you really need to allocate more than %d items?\n", MAX_ADDRS);
abort();
}
if (chk_header_okay(ch) == FALSE) {
fprintf(stderr, "Implementation Error\n");
abort();
}
printf("malloc at %p\n", p);
return (uint8_t*)p + sizeof(chk_header);
}
void *
_xrealloc(void *p, unsigned size, const char *filen, int line)
{
alloc_blk *m;
chk_header *ch;
uint8_t *t;
ASSERT(p != NULL);
ASSERT(filen != NULL);
ch = ((chk_header*) p) - 1;
m = mem_item_find(ch->key);
if (m != NULL) {
/* Attempt reallocation */
m->addr = realloc((void*)ch, size + sizeof(chk_header) + MAGIC_MEMORY_SIZE);
if (m->addr == NULL) {
debug_msg("realloc failed\n");
return NULL;
}
/* Update table */
free(m->filen);
m->filen = (char *) strdup(filen);
m->line = line;
m->length = strlen(filen);
m->est = tick++;
/* Fix chunk header */
ch->size = size;
/* Fix trailer */
t = (uint8_t*)p + size;
memcpy(t, &ch->magic, MAGIC_MEMORY_SIZE);
/* Check block is okay */
if (chk_header_okay(ch) == FALSE) {
fprintf(stderr, "Implementation Error\n");
abort();
}
return p;
}
debug_msg("Trying to xrealloc() memory not which is not allocated\n");
abort();
return 0;
}
char *_xstrdup(const char *s1, const char *filen, int line)
{
char *s2;
s2 = (char *) _xmalloc(strlen(s1)+1, filen, line);
if (s2 != NULL) {
strcpy(s2, s1);
}
return (s2);
}
#else
void xdoneinit (void) { return; }
void xmemchk (void) { return; }
void xmemdmp (void) { return; }
void xclaim (void *p, const char *filen, int line)
{
UNUSED(p);
UNUSED(filen);
UNUSED(line);
return;
}
void xmemdist (FILE *f) { UNUSED(f); }
void xfree (void *x) { free(x); }
void *_xmalloc(unsigned int size, const char *filen, int line) {
void *m;
m = malloc(size);
#ifdef DEBUG
/* This is just to check initialization errors in allocated structs */
memset(m, 0xf0, size);
#endif
UNUSED(filen);
UNUSED(line);
return m;
}
void *_xrealloc(void *p, unsigned int size,const char *filen,int line) {
UNUSED(filen);
UNUSED(line);
return realloc(p, size);
}
char *_xstrdup(const char *s1, const char *filen, int line) {
UNUSED(filen);
UNUSED(line);
return strdup(s1);
}
#endif /* DEBUG_MEM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -