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:
@@ -301,6 +301,7 @@ extern char *dupstr_n(const char *string, unsigned int *lenout);
|
|||||||
#ifdef MONITOR_HEAP
|
#ifdef MONITOR_HEAP
|
||||||
/* plain alloc() is not declared except in alloc.c */
|
/* plain alloc() is not declared except in alloc.c */
|
||||||
extern long *nhalloc(unsigned int, const char *, int);
|
extern long *nhalloc(unsigned int, const char *, int);
|
||||||
|
extern long *nhrealloc(long *, unsigned int, const char *, int);
|
||||||
extern void nhfree(genericptr_t, const char *, int);
|
extern void nhfree(genericptr_t, const char *, int);
|
||||||
extern char *nhdupstr(const char *, const char *, int);
|
extern char *nhdupstr(const char *, const char *, int);
|
||||||
/* this predates C99's __func__; that is trickier to use conditionally
|
/* this predates C99's __func__; that is trickier to use conditionally
|
||||||
@@ -314,11 +315,13 @@ extern char *nhdupstr(const char *, const char *, int);
|
|||||||
#define __LINE__ 0
|
#define __LINE__ 0
|
||||||
#endif
|
#endif
|
||||||
#define alloc(a) nhalloc(a, __FILE__, (int) __LINE__)
|
#define alloc(a) nhalloc(a, __FILE__, (int) __LINE__)
|
||||||
|
#define re_alloc(a,n) nhrealloc(a, n, __FILE__, (int) __LINE__)
|
||||||
#define free(a) nhfree(a, __FILE__, (int) __LINE__)
|
#define free(a) nhfree(a, __FILE__, (int) __LINE__)
|
||||||
#define dupstr(s) nhdupstr(s, __FILE__, (int) __LINE__)
|
#define dupstr(s) nhdupstr(s, __FILE__, (int) __LINE__)
|
||||||
#else /* !MONITOR_HEAP */
|
#else /* !MONITOR_HEAP */
|
||||||
/* declare alloc.c's alloc(); allocations made with it use ordinary free() */
|
/* declare alloc.c's alloc(); allocations made with it use ordinary free() */
|
||||||
extern long *alloc(unsigned int); /* alloc.c */
|
extern long *alloc(unsigned int); /* alloc.c */
|
||||||
|
extern long *re_alloc(long *, unsigned int);
|
||||||
#endif /* ?MONITOR_HEAP */
|
#endif /* ?MONITOR_HEAP */
|
||||||
|
|
||||||
/* Used for consistency checks of various data files; declare it here so
|
/* Used for consistency checks of various data files; declare it here so
|
||||||
|
|||||||
+82
-3
@@ -8,16 +8,22 @@
|
|||||||
/* since this file is also used in auxiliary programs, don't include all the
|
/* since this file is also used in auxiliary programs, don't include all the
|
||||||
function declarations for all of nethack */
|
function declarations for all of nethack */
|
||||||
#define EXTERN_H /* comment line for pre-compiled headers */
|
#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"
|
#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);
|
char *fmt_ptr(const genericptr);
|
||||||
|
|
||||||
#ifdef MONITOR_HEAP
|
#ifdef MONITOR_HEAP
|
||||||
#undef alloc
|
#undef alloc
|
||||||
|
#undef re_alloc
|
||||||
#undef free
|
#undef free
|
||||||
extern void free(genericptr_t);
|
extern void free(genericptr_t);
|
||||||
static void heapmon_init(void);
|
static void heapmon_init(void);
|
||||||
@@ -27,6 +33,7 @@ static boolean tried_heaplog = FALSE;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
long *alloc(unsigned int);
|
long *alloc(unsigned int);
|
||||||
|
long *re_alloc(long *, unsigned int);
|
||||||
extern void panic(const char *, ...);
|
extern void panic(const char *, ...);
|
||||||
|
|
||||||
long *
|
long *
|
||||||
@@ -55,6 +62,24 @@ alloc(unsigned int lth)
|
|||||||
#endif
|
#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
|
#ifdef HAS_PTR_FMT
|
||||||
#define PTR_FMT "%p"
|
#define PTR_FMT "%p"
|
||||||
#define PTR_TYP genericptr_t
|
#define PTR_TYP genericptr_t
|
||||||
@@ -122,6 +147,39 @@ nhalloc(unsigned int lth, const char *file, int line)
|
|||||||
return ptr;
|
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
|
void
|
||||||
nhfree(genericptr_t ptr, const char *file, int line)
|
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);
|
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*/
|
/*alloc.c*/
|
||||||
|
|||||||
@@ -1361,23 +1361,6 @@ nh_snprintf(
|
|||||||
|
|
||||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||||
|
|
||||||
/* cast to int or panic on overflow; use via macro */
|
|
||||||
int
|
|
||||||
FITSint_(lua_Integer i, const char *file, int line){
|
|
||||||
int ret = (int)i;
|
|
||||||
if (ret != i)
|
|
||||||
panic("Overflow at %s:%d", file, line);
|
|
||||||
return (int)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
FITSuint_(unsigned long long i, const char *file, int line){
|
|
||||||
unsigned ret = (unsigned)i;
|
|
||||||
if (ret != i)
|
|
||||||
panic("Overflow at %s:%d", file, line);
|
|
||||||
return (unsigned)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENHANCED_SYMBOLS
|
#ifdef ENHANCED_SYMBOLS
|
||||||
|
|
||||||
/* Unicode routines */
|
/* Unicode routines */
|
||||||
|
|||||||
+2
-5
@@ -2255,11 +2255,8 @@ nhl_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
|
|||||||
free(ptr);
|
free(ptr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* FIXME:
|
return re_alloc(ptr, nsize);
|
||||||
* Use of realloc() confuses MONITOR_HEAP.
|
|
||||||
*/
|
|
||||||
return realloc(ptr, nsize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
+6
-15
@@ -15,6 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void xexit(int) NORETURN;
|
static void xexit(int) NORETURN;
|
||||||
|
extern void panic(const char *, ...) NORETURN;
|
||||||
char *eos(char *); /* also used by dlb.c */
|
char *eos(char *); /* also used by dlb.c */
|
||||||
FILE *fopen_datafile(const char *, const char *);
|
FILE *fopen_datafile(const char *, const char *);
|
||||||
unsigned FITSuint_(unsigned long long, const char *, int);
|
unsigned FITSuint_(unsigned long long, const char *, int);
|
||||||
@@ -545,25 +546,15 @@ xexit(int retcd)
|
|||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In hacklib.c, but we don't have that and it calls panic() */
|
/* from hacklib.c */
|
||||||
unsigned
|
unsigned
|
||||||
FITSuint_(unsigned long long i, const char *file, int line){
|
Strlen_(const char *str, const char *file, int line)
|
||||||
unsigned ret = (unsigned)i;
|
{
|
||||||
if (ret != i) {
|
|
||||||
printf("Overflow at %s:%d\n", file, line);
|
|
||||||
xexit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return (unsigned)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ditto */
|
|
||||||
unsigned
|
|
||||||
Strlen_(const char *str, const char *file, int line){
|
|
||||||
size_t len = strnlen(str, LARGEST_INT);
|
size_t len = strnlen(str, LARGEST_INT);
|
||||||
|
|
||||||
if (len == LARGEST_INT) {
|
if (len == LARGEST_INT) {
|
||||||
printf("%s:%d string too long", file, line);
|
panic("%s:%d string too long", file, line);
|
||||||
xexit(EXIT_FAILURE);
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
return (unsigned) len;
|
return (unsigned) len;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2351,14 +2351,4 @@ struct attribs attrmax, attrmin;
|
|||||||
#endif
|
#endif
|
||||||
#endif /* STRICT_REF_DEF */
|
#endif /* STRICT_REF_DEF */
|
||||||
|
|
||||||
/* In hacklib.c, but we don't have that and it calls panic() */
|
|
||||||
unsigned
|
|
||||||
FITSuint_(unsigned long long i, const char *file, int line){
|
|
||||||
unsigned ret = (unsigned)i;
|
|
||||||
if (ret != i) {
|
|
||||||
Fprintf(stdout, "Overflow at %s:%d\n", file, line);
|
|
||||||
makedefs_exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return (unsigned)i;
|
|
||||||
}
|
|
||||||
/*makedefs.c*/
|
/*makedefs.c*/
|
||||||
|
|||||||
+1
-10
@@ -241,14 +241,5 @@ main(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we need a local copy of this for alloc.o and because we don't have panic() */
|
/*tile2X11.c*/
|
||||||
unsigned
|
|
||||||
FITSuint_(unsigned long long i, const char *file, int line){
|
|
||||||
unsigned ret = (unsigned)i;
|
|
||||||
if (ret != i) {
|
|
||||||
Fprintf(stderr, "Overflow at %s:%d", file, line);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return (unsigned)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
+1
-10
@@ -379,14 +379,5 @@ build_bmptile(pixel(*pixels)[TILE_X])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we need a local copy of this for alloc.o and because we don't have panic() */
|
/*tile2bmp.c*/
|
||||||
unsigned
|
|
||||||
FITSuint_(unsigned long long i, const char *file, int line){
|
|
||||||
unsigned ret = (unsigned)i;
|
|
||||||
if (ret != i) {
|
|
||||||
Fprintf(stderr, "Overflow at %s:%d", file, line);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return (unsigned)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user