AmendHub

Download:

jcs

/

subtext

/

amendments

/

331

util: Make x* allocation functions no longer fatal on failure

Display a warning, but return NULL
 
Also remove MALLOC_DEBUG, it is not as helpful as I wanted and just
bloats things having to store all these note strings

jcs made amendment 331 about 1 year ago
--- util.c Sun Feb 5 11:13:11 2023 +++ util.c Wed Mar 1 15:45:47 2023 @@ -83,28 +83,6 @@ enum { APPICON_ALERT }; -/* - * Define to audit each malloc and free and verify that a pointer isn't - * double-freed. The list of outstanding allocations can be checked by - * looking through malloc_map. - */ -//#define MALLOC_DEBUG - -#ifdef MALLOC_DEBUG -/* - * List of allocations, updated at xmalloc() and xfree(). If an address - * passed to xfree() isn't in the list, it indicates a double-free. - */ -#define MALLOC_MAP_CHUNK_SIZE 1024 -struct malloc_map_e { - unsigned long addr; - unsigned long size; - char note[MALLOC_NOTE_SIZE]; -} *malloc_map = NULL; -unsigned long malloc_map_size = 0; -static bool malloc_map_compact = false; -#endif - void vwarn(short alert_func, const char *format, va_list ap); /* @@ -116,18 +94,11 @@ void util_init(void) { alert_ditl_h = xNewHandle(sizeof(alert_ditl)); + if (alert_ditl_h == NULL) + ExitToShell(); HLock(alert_ditl_h); memcpy(*alert_ditl_h, alert_ditl, sizeof(alert_ditl)); HUnlock(alert_ditl_h); - -#ifdef MALLOC_DEBUG - malloc_map_size = MALLOC_MAP_CHUNK_SIZE; - malloc_map = (struct malloc_map_e *)NewPtr(malloc_map_size * - sizeof(struct malloc_map_e)); - if (malloc_map == NULL) - panic("NewPtr(%lu) failed", MALLOC_MAP_CHUNK_SIZE); - memset(malloc_map, 0, malloc_map_size); -#endif } /* @@ -137,65 +108,17 @@ util_init(void) #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) void * -xmalloc(size_t size, char *note) +xmalloc(size_t size) { void *ptr; -#ifdef MALLOC_DEBUG - struct malloc_map_e *new_malloc_map; - unsigned short n, j; -#endif if (size == 0) panic("xmalloc: zero size"); ptr = NewPtr(size); if (ptr == NULL) - panic("xmalloc(%lu) failed", size); + warn("Insufficient memory available: xmalloc(%lu) failed", size); -#ifdef MALLOC_DEBUG - if (malloc_map_compact) { - for (n = 0; n < malloc_map_size; n++) { - if (malloc_map[n].addr != 0) - continue; - - for (j = n + 1; j < malloc_map_size; j++) { - if (malloc_map[j].addr == 0) - continue; - - malloc_map[n] = malloc_map[j]; - memset(&malloc_map[j], 0, sizeof(struct malloc_map_e)); - break; - } - } - - malloc_map_compact = false; - } - - for (n = 0; n <= malloc_map_size; n++) { - if (n == malloc_map_size) { - malloc_map_size += MALLOC_MAP_CHUNK_SIZE; - warn("xmalloc(%lu): out of malloc map entries, maybe a " - "memory leak, resizing to %ld", size, malloc_map_size); - new_malloc_map = (struct malloc_map_e *)NewPtr( - malloc_map_size * sizeof(struct malloc_map_e)); - if (new_malloc_map == NULL) - panic("out of memory resizing malloc map"); - memcpy(new_malloc_map, malloc_map, - (malloc_map_size - MALLOC_MAP_CHUNK_SIZE) * - sizeof(struct malloc_map_e)); - DisposePtr(malloc_map); - malloc_map = new_malloc_map; - } - if (malloc_map[n].addr == 0) { - malloc_map[n].addr = (unsigned long)ptr; - malloc_map[n].size = size; - strlcpy(malloc_map[n].note, note, sizeof(malloc_map[n].note)); - break; - } - n = n; - } -#endif - return ptr; } @@ -204,89 +127,51 @@ xfree(void *ptrptr) { unsigned long *addr = (unsigned long *)ptrptr; void *ptr; -#ifdef MALLOC_DEBUG - unsigned long n; -#endif if (ptrptr == NULL) panic("xfree(NULL)"); ptr = (void *)*addr; - if (ptr == NULL) - panic("xfree(&NULL) likely a double-free"); - -#ifdef MALLOC_DEBUG - for (n = 0; n <= malloc_map_size; n++) { - if (n == malloc_map_size) - panic("xfree(0x%lx): can't find in alloc map, likely " - "double free()", *addr); - if (malloc_map[n].addr == *addr) { - malloc_map[n].addr = 0; - malloc_map[n].size = 0; - malloc_map[n].note[0] = '\0'; - break; - } + if (ptr == NULL) { + warn("xfree(&NULL) likely a double-free"); + return; } -#endif - + DisposePtr(ptr); - *addr = 0L; } void * -xmalloczero(size_t size, char *note) +xmalloczero(size_t size) { void *ptr; - ptr = xmalloc(size, note); - memset(ptr, 0, size); + ptr = xmalloc(size); + if (ptr != NULL) + memset(ptr, 0, size); return ptr; } void * -xcalloc(size_t nmemb, size_t size, char *note) +xcalloc(size_t nmemb, size_t size) { void *ptr; if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && SIZE_MAX / nmemb < size) panic("xcalloc(%lu, %lu) overflow", nmemb, size); - ptr = xmalloczero(nmemb * size, note); - if (ptr == NULL) - panic("xcalloc(%lu, %lu) failed", nmemb, size); - - return ptr; + + return xmalloczero(nmemb * size); } void * xrealloc(void *src, size_t size) { void *ptr, *tsrc; -#ifdef MALLOC_DEBUG - unsigned long n; -#endif - char note[MALLOC_NOTE_SIZE] = "realloc from null"; -#ifdef MALLOC_DEBUG - if (src != NULL) { - for (n = 0; n <= malloc_map_size; n++) { - if (n == malloc_map_size) { - panic("xrealloc(%lu): can't find in alloc map, likely " - "double free()", (unsigned long)src); - return NULL; - } - if (malloc_map[n].addr == (unsigned long)src) { - strlcpy(note, malloc_map[n].note, sizeof(note)); - break; - } - } - } -#endif - - ptr = xmalloc(size, note); - if (src != NULL) { + ptr = xmalloc(size); + if (ptr != NULL && src != NULL) { memcpy(ptr, src, size); tsrc = src; xfree(&tsrc); @@ -301,25 +186,26 @@ xreallocarray(void *optr, size_t nmemb, size_t size) if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && SIZE_MAX / nmemb < size) panic("xreallocarray(%lu, %lu) failed", nmemb, size); + return xrealloc(optr, size * nmemb); } char * -xstrdup(const char *str, char *note) +xstrdup(const char *str) { char *cp; size_t len; len = strlen(str); + cp = xmalloc(len + 1); + if (cp != NULL) + strlcpy(cp, str, len + 1); - cp = xmalloc(len + 1, note); - strlcpy(cp, str, len + 1); - return cp; } char * -xstrndup(const char *str, size_t maxlen, char *note) +xstrndup(const char *str, size_t maxlen) { char *copy; const char *cp; @@ -330,14 +216,15 @@ xstrndup(const char *str, size_t maxlen, char *note) ; len = (size_t)(cp - str); - copy = xmalloc(len + 1, note); - (void)memcpy(copy, str, len); - copy[len] = '\0'; + copy = xmalloc(len + 1); + if (copy != NULL) { + (void)memcpy(copy, str, len); + copy[len] = '\0'; + } return copy; } - /* * String functions */ @@ -349,8 +236,11 @@ getline(char *str, size_t len, char **ret) for (i = 0; i < len; i++) { if (str[i] == '\r' || i == len - 1) { - if (*ret == NULL) - *ret = xmalloc(i + 1, "getline"); + if (*ret == NULL) { + *ret = xmalloc(i + 1); + if (*ret == NULL) + return -1; + } memcpy(*ret, str, i + 1); (*ret)[i] = '\0'; return i + 1; @@ -713,7 +603,7 @@ center_in_screen(short width, short height, bool title } Point -centered_sf_dialog(void) +centered_sfget_dialog(void) { Point p; Rect r; @@ -725,6 +615,18 @@ centered_sf_dialog(void) return p; } +Point +centered_sfput_dialog(void) +{ + Point p; + Rect r; + + center_in_screen(320, 200, false, &r); + p.h = r.left; + p.v = r.top; + + return p; +} /* * General Mac-specific non-GUI functions @@ -797,32 +699,38 @@ xGetStringAsChar(short id) h = xGetString(id); HLock(h); l = (*h)[0]; - out = xmalloc(l + 1, "xGetStringAsChar"); - memcpy((void *)out, (void *)(*h + 1), l); - out[l] = '\0'; + out = xmalloc(l + 1); + if (out != NULL) { + memcpy((void *)out, (void *)(*h + 1), l); + out[l] = '\0'; + } ReleaseResource(h); return out; } -long -xGetStringAsLong(short id) +bool +xGetStringAsLong(short id, long *ret) { char *c; - long r; c = xGetStringAsChar(id); - r = atol(c); + if (c == NULL) + return false; + *ret = atol(c); xfree(&c); - return r; + return true; } -void +bool xSetHandleSize(Handle h, Size s) { SetHandleSize(h, s); - if (MemError()) - panic("Failed to SetHandleSize to %ld", s); + if (MemError()) { + warn("Failed to SetHandleSize to %ld", s); + return false; + } + return true; } /* @@ -840,6 +748,8 @@ getpath(short vRefNum, Str255 fileName, Str255 *ret, b char *tmpret = NULL, *tmp = NULL; char *lastcolon; + *ret[0] = 0; + if (strchr((char *)fileName + 1, ':') != NULL) { /* already a full path */ memcpy(*ret, fileName, 256); @@ -852,8 +762,10 @@ getpath(short vRefNum, Str255 fileName, Str255 *ret, b return 0; } - name = xmalloc(FILENAME_MAX, "getpath"); - + name = xmalloc(FILENAME_MAX); + if (name == NULL) + return 1; + wdir.ioVRefNum = wdir.ioWDVRefNum = vRefNum; wdir.ioWDIndex = 0; wdir.ioWDProcID = 0; @@ -886,9 +798,18 @@ getpath(short vRefNum, Str255 fileName, Str255 *ret, b wcinfo.ioDrParID = wdir.ioWDDirID; wcinfo.ioDrDirID = wdir.ioWDDirID; - tmp = xmalloc(FILENAME_MAX, "getpath"); - tmpret = xmalloc(FILENAME_MAX, "getpath"); - + tmp = xmalloc(FILENAME_MAX); + if (tmp == NULL) { + xfree(&name); + return 1; + } + tmpret = xmalloc(FILENAME_MAX); + if (tmp == NULL) { + xfree(&tmp); + xfree(&name); + return 1; + } + /* go backwards, prepending each folder's parent */ while (wcinfo.ioDrParID != 1) { wcinfo.ioDrDirID = wcinfo.ioDrParID; /* .. */ @@ -940,7 +861,9 @@ stat(char *path, struct stat *sb) char *ppath; short ret; - ppath = xstrdup(path, "stat"); + ppath = xstrdup(path); + if (ppath == NULL) + return -1; CtoPstr(ppath); ret = FStat((unsigned char *)ppath, sb); xfree(&ppath); @@ -1082,7 +1005,9 @@ copy_file_contents(short source_ref, short dest_ref) if (error) return error; - buf = xmalloc(1024, "copy_file_contents"); + buf = xmalloc(1024); + if (buf == NULL) + return -1; while (source_size > 0) { count = 1024; @@ -1245,6 +1170,10 @@ DrawGrowIconOnly(WindowPtr win) RgnHandle tmp; GetClip(tmp = NewRgn()); + if (tmp == NULL) { + warn("NewRgn() failed"); + return; + } r = win->portRect; r.top = r.bottom - SCROLLBAR_WIDTH; r.left = r.right - SCROLLBAR_WIDTH + 1; --- util.h Sun Feb 5 11:13:11 2023 +++ util.h Wed Mar 1 15:37:54 2023 @@ -94,15 +94,15 @@ struct stat { void util_init(void); -void * xmalloc(size_t, char *note); +void * xmalloc(size_t); void xfree(void *ptrptr); void xfree_verify(void); -void * xmalloczero(size_t, char *note); -void * xcalloc(size_t, size_t, char *note); +void * xmalloczero(size_t); +void * xcalloc(size_t, size_t); void * xrealloc(void *src, size_t size); void * xreallocarray(void *, size_t, size_t); -char * xstrdup(const char *, char *note); -char * xstrndup(const char *str, size_t maxlen, char *note); +char * xstrdup(const char *); +char * xstrndup(const char *str, size_t maxlen); short getline(char *str, size_t len, char **ret); const char * ordinal(unsigned short n); @@ -125,14 +125,15 @@ void about(char *program_name); void progress(char *format, ...); void window_rect(WindowPtr win, Rect *ret); void center_in_screen(short width, short height, bool titlebar, Rect *b); -Point centered_sf_dialog(void); +Point centered_sfget_dialog(void); +Point centered_sfput_dialog(void); Handle xNewHandle(size_t size); Handle xGetResource(ResType type, short id); StringHandle xGetString(short id); char * xGetStringAsChar(short id); -long xGetStringAsLong(short id); -void xSetHandleSize(Handle h, Size s); +bool xGetStringAsLong(short id, long *ret); +bool xSetHandleSize(Handle h, Size s); short getpath(short vRefNum, Str255 fileName, Str255 *ret, bool include_file); bool FIsDir(Str255 path); @@ -169,7 +170,5 @@ char * strndup(const char *str, size_t maxlen); char * strsep(char **stringp, const char *delim); int snprintf(char *s, size_t size, const char *fmt, ...); int vsnprintf(char *s, size_t size, const char *fmt, void *p); - -void malloc_map_dump(void); #endif