implement realloc() for MONITOR_HEAP or vice versa
Add new routine 're_alloc()' that functions as MONITOR_HEAP-aware libc realloc(). 'nhrealloc()' is the version that passes source file and line info if built with MONITOR_HEAP enabled. The heaplog data might now contain '<' (freed by realloc), '>' (replacement allocation by realloc), and '*' (resized by realloc) entries in addition to the previous '+' (allocated) and '-' (freed) entries. heaputil has already been updated in the NHinternal repository. Move FITSint_() and FITSuint_() from hacklib.c to alloc.c so that they can be accessed by miscellaneous utility programs. Remove three or four copies of FITSint_() that were duplicated in utility programs like dlb and tile2bmp due to those not having access to src/hacklib.o. They do have access to src/alloc.o (and util/panic.o).
This commit is contained in:
85
src/alloc.c
85
src/alloc.c
@@ -8,16 +8,22 @@
|
||||
/* since this file is also used in auxiliary programs, don't include all the
|
||||
function declarations for all of nethack */
|
||||
#define EXTERN_H /* comment line for pre-compiled headers */
|
||||
/* but we need this one */
|
||||
#define FITSuint(x) FITSuint_(x, __func__, __LINE__)
|
||||
extern unsigned FITSuint_(unsigned long long, const char *, int);
|
||||
|
||||
#include "config.h"
|
||||
#ifndef LUA_INTEGER
|
||||
#include "nhlua.h"
|
||||
#endif
|
||||
|
||||
#define FITSint(x) FITSint_(x, __func__, (int) __LINE__)
|
||||
extern int FITSint_(LUA_INTEGER, const char *, int);
|
||||
#define FITSuint(x) FITSuint_(x, __func__, (int) __LINE__)
|
||||
extern unsigned FITSuint_(unsigned long long, const char *, int);
|
||||
|
||||
char *fmt_ptr(const genericptr);
|
||||
|
||||
#ifdef MONITOR_HEAP
|
||||
#undef alloc
|
||||
#undef re_alloc
|
||||
#undef free
|
||||
extern void free(genericptr_t);
|
||||
static void heapmon_init(void);
|
||||
@@ -27,6 +33,7 @@ static boolean tried_heaplog = FALSE;
|
||||
#endif
|
||||
|
||||
long *alloc(unsigned int);
|
||||
long *re_alloc(long *, unsigned int);
|
||||
extern void panic(const char *, ...);
|
||||
|
||||
long *
|
||||
@@ -55,6 +62,24 @@ alloc(unsigned int lth)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* realloc() call that might get substituted by nhrealloc(p,l,file,line) */
|
||||
long *
|
||||
re_alloc(long *oldptr, unsigned int newlth)
|
||||
{
|
||||
/*
|
||||
* if LINT support ever gets resurrected,
|
||||
* we probably need some hackery here
|
||||
*/
|
||||
|
||||
long *newptr = (long *) realloc((genericptr_t) oldptr, (size_t) newlth);
|
||||
#ifndef MONITOR_HEAP
|
||||
/* "extend": assume if won't ever fail if asked to shrink */
|
||||
if (newlth && !newptr)
|
||||
panic("Memory allocation failure; cannot extend to %u bytes", newlth);
|
||||
#endif
|
||||
return newptr;
|
||||
}
|
||||
|
||||
#ifdef HAS_PTR_FMT
|
||||
#define PTR_FMT "%p"
|
||||
#define PTR_TYP genericptr_t
|
||||
@@ -122,6 +147,39 @@ nhalloc(unsigned int lth, const char *file, int line)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* re_alloc() with heap logging; we lack access to the old alloc size */
|
||||
long *
|
||||
nhrealloc(
|
||||
long *oldptr,
|
||||
unsigned int newlth,
|
||||
const char *file,
|
||||
int line)
|
||||
{
|
||||
long *newptr = re_alloc(oldptr, newlth);
|
||||
|
||||
if (!tried_heaplog)
|
||||
heapmon_init();
|
||||
if (heaplog) {
|
||||
char op = '*'; /* assume realloc() will change size of previous
|
||||
* allocation rather than make a new one */
|
||||
|
||||
if (newptr != oldptr) {
|
||||
/* realloc() freed oldptr */
|
||||
(void) fprintf(heaplog, "%c%5s %s %4d %s\n", '<', "",
|
||||
fmt_ptr((genericptr_t) oldptr), line, file);
|
||||
op = '>'; /* new allocation rather than size-change of old one */
|
||||
}
|
||||
(void) fprintf(heaplog, "%c%5u %s %4d %s\n", op, newlth,
|
||||
fmt_ptr((genericptr_t) newptr), line, file);
|
||||
}
|
||||
/* potential panic in re_alloc() was deferred til here */
|
||||
/* "extend to": assume if won't ever fail if asked to shrink */
|
||||
if (newlth && !newptr)
|
||||
panic("Cannot extend to %u bytes, line %d of %s", newlth, line, file);
|
||||
|
||||
return newptr;
|
||||
}
|
||||
|
||||
void
|
||||
nhfree(genericptr_t ptr, const char *file, int line)
|
||||
{
|
||||
@@ -166,4 +224,25 @@ dupstr_n(const char *string, unsigned int *lenout)
|
||||
return strcpy((char *) alloc(len + 1), string);
|
||||
}
|
||||
|
||||
/* cast to int or panic on overflow; use via macro */
|
||||
int
|
||||
FITSint_(LUA_INTEGER i, const char *file, int line)
|
||||
{
|
||||
int iret = (int) i;
|
||||
|
||||
if (iret != i)
|
||||
panic("Overflow at %s:%d", file, line);
|
||||
return iret;
|
||||
}
|
||||
|
||||
unsigned
|
||||
FITSuint_(unsigned long long ull, const char *file, int line)
|
||||
{
|
||||
unsigned uret = (unsigned) ull;
|
||||
|
||||
if (uret != ull)
|
||||
panic("Overflow at %s:%d", file, line);
|
||||
return uret;
|
||||
}
|
||||
|
||||
/*alloc.c*/
|
||||
|
||||
Reference in New Issue
Block a user