]> granicus.if.org Git - nethack/commitdiff
implement realloc() for MONITOR_HEAP or vice versa
authorPatR <rankin@nethack.org>
Tue, 31 May 2022 06:19:35 +0000 (23:19 -0700)
committerPatR <rankin@nethack.org>
Tue, 31 May 2022 06:19:35 +0000 (23:19 -0700)
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).

include/global.h
src/alloc.c
src/hacklib.c
src/nhlua.c
util/dlb_main.c
util/makedefs.c
win/X11/tile2x11.c
win/share/tile2bmp.c

index 41659e4dc724bf17389471aaaa21c3101989704a..358f66a12b0e4999e8c1a0ae84417d732faac0cd 100644 (file)
@@ -301,6 +301,7 @@ extern char *dupstr_n(const char *string, unsigned int *lenout);
 #ifdef MONITOR_HEAP
 /* plain alloc() is not declared except in alloc.c */
 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 char *nhdupstr(const char *, const char *, int);
 /* 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
 #endif
 #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 dupstr(s) nhdupstr(s, __FILE__, (int) __LINE__)
 #else /* !MONITOR_HEAP */
 /* declare alloc.c's alloc(); allocations made with it use ordinary free() */
 extern long *alloc(unsigned int);  /* alloc.c */
+extern long *re_alloc(long *, unsigned int);
 #endif /* ?MONITOR_HEAP */
 
 /* Used for consistency checks of various data files; declare it here so
index c4642d9ed4af9528db51a983f10c97c87183b4e8..f0fb41a71a1c3838d51a93b9bce320d9268749af 100644 (file)
@@ -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*/
index 532046c488ad671cc6059f631f30c90055a71654..98ca4e90a081e43c301a8b84896fad77372e7bc5 100644 (file)
@@ -1361,23 +1361,6 @@ nh_snprintf(
 
 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
 
 /* Unicode routines */
index 75ab9422dd8919cac832fe9d6613da8c92a298e3..5fc39a7e1ac8b95efbfdac0108825817a214cba4 100644 (file)
@@ -2255,11 +2255,8 @@ nhl_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
         free(ptr);
         return NULL;
     }
-    /*
-     * FIXME:
-     *  Use of realloc() confuses MONITOR_HEAP.
-     */
-    return realloc(ptr, nsize);
+
+    return re_alloc(ptr, nsize);
 }
 
 static int
index 5c886c25d2c11cd432460418fbbfb4f8fde570e8..e434b3a336277b924784caa28ac89eb13a1ecb85 100644 (file)
@@ -15,6 +15,7 @@
 #endif
 
 static void xexit(int) NORETURN;
+extern void panic(const char *, ...) NORETURN;
 char *eos(char *); /* also used by dlb.c */
 FILE *fopen_datafile(const char *, const char *);
 unsigned FITSuint_(unsigned long long, const char *, int);
@@ -545,25 +546,15 @@ xexit(int retcd)
     /*NOTREACHED*/
 }
 
-    /* In hacklib.c, but we don't have that and it calls panic() */
+/* from hacklib.c */
 unsigned
-FITSuint_(unsigned long long i, 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){
+Strlen_(const char *str, const char *file, int line)
+{
     size_t len = strnlen(str, LARGEST_INT);
 
     if (len == LARGEST_INT) {
-        printf("%s:%d string too long", file, line);
-        xexit(EXIT_FAILURE);
+        panic("%s:%d string too long", file, line);
+        /*NOTREACHED*/
     }
     return (unsigned) len;
 }
index 6f64341a81e261e07b48a69fa464e9e4ddd2ede0..d0d195f3483a01b4df7da61ce6d868b3e0ba93fc 100644 (file)
@@ -2351,14 +2351,4 @@ struct attribs attrmax, attrmin;
 #endif
 #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*/
index 97059dd5ebb0609135b1004855c0f0bae7d72425..53e7e57d21adea8dbeabe03ec12b6e8e574e3434 100644 (file)
@@ -241,14 +241,5 @@ main(int argc, char *argv[])
     return 0;
 }
 
-/* we need a local copy of this for alloc.o and because we don't have panic() */
-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;
-}
+/*tile2X11.c*/
 
index d45bbbd83011578cf5c5f5c1d30ee07727ac1735..fc1942be1be4cdcea14e92c66780d7a79fd3e7de 100644 (file)
@@ -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() */
-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;
-}
+/*tile2bmp.c*/