Expand coverage of heap memory checking of debug builds and simplify FREE() calls

This commit is contained in:
Aaron Culliney 2016-02-25 21:43:54 -08:00
parent 0663141589
commit b87273e742
15 changed files with 181 additions and 113 deletions

View File

@ -112,11 +112,11 @@ void Java_org_deadc0de_apple2ix_Apple2CrashHandler_nativeProcessCrash(JNIEnv *en
}
if (android_armArchV7A) {
asprintf(&symbolsPath, "%s/symbols/armeabi-v7a", data_dir);
ASPRINTF(&symbolsPath, "%s/symbols/armeabi-v7a", data_dir);
} else if (android_x86) {
asprintf(&symbolsPath, "%s/symbols/x86", data_dir);
ASPRINTF(&symbolsPath, "%s/symbols/x86", data_dir);
} else /*if (android_armArch)*/ {
asprintf(&symbolsPath, "%s/symbols/armeabi", data_dir);
ASPRINTF(&symbolsPath, "%s/symbols/armeabi", data_dir);
} /*else { moar archs ... } */
bool success = crashHandler->processCrash(crashPath, symbolsPath, outputFILE);
@ -131,7 +131,7 @@ void Java_org_deadc0de_apple2ix_Apple2CrashHandler_nativeProcessCrash(JNIEnv *en
}
if (symbolsPath) {
ASPRINTF_FREE(symbolsPath);
FREE(symbolsPath);
}
(*env)->ReleaseStringUTFChars(env, jCrashPath, crashPath);

View File

@ -159,7 +159,7 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnCreate(JNIEnv *env, jclas
int pagesize = getpagesize();
LOG("PAGESIZE IS : %d", pagesize);
data_dir = strdup(dataDir);
data_dir = STRDUP(dataDir);
if (crashHandler && crashHandler->init) {
crashHandler->init(data_dir);
}
@ -177,9 +177,9 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnCreate(JNIEnv *env, jclas
#if DO_CPU65_TRACING
# warning !!!!!!!!!! this will quickly eat up disk space !!!!!!!!!!
char *trfile = NULL;
asprintf(&trfile, "%s/%s", data_dir, "cpu_trace.txt");
ASPRINTF(&trfile, "%s/%s", data_dir, "cpu_trace.txt");
cpu65_trace_begin(trfile);
ASPRINTF_FREE(trfile);
FREE(trfile);
#endif
#if !TESTING
@ -351,7 +351,7 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, jcl
LOG(": (%s, %s, %s)", path, driveA ? "drive A" : "drive B", readOnly ? "read only" : "read/write");
if (disk6_insert(drive, path, ro)) {
char *gzPath = NULL;
asprintf(&gzPath, "%s.gz", path);
ASPRINTF(&gzPath, "%s.gz", path);
if (disk6_insert(drive, gzPath, ro)) {
char *diskImageUnreadable = "Disk Image Unreadable";
unsigned int cols = strlen(diskImageUnreadable);
@ -359,7 +359,7 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, jcl
} else {
video_animations->animation_showDiskChosen(drive);
}
ASPRINTF_FREE(gzPath);
FREE(gzPath);
} else {
video_animations->animation_showDiskChosen(drive);
}
@ -404,10 +404,10 @@ jstring Java_org_deadc0de_apple2ix_Apple2Activity_nativeLoadState(JNIEnv *env, j
bool readOnly2 = disk6.disk[1].is_protected;
char *str = NULL;
jstring jstr = NULL;
asprintf(&str, "{ disk1 = \"%s\"; readOnly1 = %s; disk2 = \"%s\"; readOnly2 = %s }", (disk1 ?: ""), readOnly1 ? "true" : "false", (disk2 ?: ""), readOnly2 ? "true" : "false");
ASPRINTF(&str, "{ disk1 = \"%s\"; readOnly1 = %s; disk2 = \"%s\"; readOnly2 = %s }", (disk1 ?: ""), readOnly1 ? "true" : "false", (disk2 ?: ""), readOnly2 ? "true" : "false");
if (str) {
jstr = (*env)->NewStringUTF(env, str);
ASPRINTF_FREE(str);
FREE(str);
}
return jstr;

View File

@ -49,7 +49,7 @@ AUDIO_SRC = \
META_SRC = \
src/meta/debug.l src/meta/debugger.c src/meta/opcodes.c src/test/sha1.c \
src/meta/lintrace.c src/json_parse.c externals/jsmn/jsmn.c
src/meta/lintrace.c
# NOTE : selectively enabled through configuration process ...
EXTRA_apple2ix_SOURCES = \
@ -63,7 +63,8 @@ EXTRA_apple2ix_SOURCES = \
apple2ix_SOURCES = src/font.c src/rom.c src/misc.c src/display.c src/vm.c \
src/timing.c src/zlib-helpers.c src/joystick.c src/keys.c src/prefs.c \
src/interface.c src/disk.c src/cpu-supp.c
src/interface.c src/disk.c src/cpu-supp.c src/json_parse.c src/memmngt.c \
externals/jsmn/jsmn.c
apple2ix_CFLAGS = @AM_CFLAGS@ @X_CFLAGS@
apple2ix_CCASFLAGS = $(apple2ix_CFLAGS)

View File

@ -770,7 +770,7 @@ const char *disk6_eject(int drive) {
#endif
}
STRDUP_FREE(disk6.disk[drive].file_name);
FREE(disk6.disk[drive].file_name);
disk6.disk[drive].fd = -1;
disk6.disk[drive].mmap_image = MAP_FAILED;
@ -799,7 +799,7 @@ const char *disk6_insert(int drive, const char * const raw_file_name, int readon
disk6_eject(drive);
disk6.disk[drive].file_name = strdup(raw_file_name);
disk6.disk[drive].file_name = STRDUP(raw_file_name);
int expected = NIB_SIZE;
disk6.disk[drive].nibblized = true;

View File

@ -23,7 +23,7 @@ static int _json_createFromString(const char *jsonString, INOUT JSON_s *parsedDa
if (!parsedData) {
break;
}
parsedData->jsonString = strdup(jsonString);
parsedData->jsonString = STRDUP(jsonString);
parsedData->jsonTokens = NULL;
unsigned int numTokens = DEFAULT_NUMTOK;
@ -240,7 +240,7 @@ bool json_mapCopyStringValue(const JSON_s *map, const char *key, INOUT char **va
int len = 0;
bool foundMatch = _json_mapGetStringValue(map, key, val, &len);
if (foundMatch) {
*val = len>0 ? strndup(*val, len) : strdup("");
*val = len>0 ? STRNDUP(*val, len) : STRDUP("");
}
return foundMatch;
}
@ -290,7 +290,7 @@ bool json_mapParseFloatValue(const JSON_s *map, const char *key, INOUT float *va
}
void json_destroy(JSON_s *parsedData) {
STRDUP_FREE(parsedData->jsonString);
FREE(parsedData->jsonString);
FREE(parsedData->jsonTokens);
}

121
src/memmngt.c Normal file
View File

@ -0,0 +1,121 @@
/*
* Apple // emulator for *ix
*
* This software package is subject to the GNU General Public License
* version 3 or later (your choice) as published by the Free Software
* Foundation.
*
* Copyright 2015-2016 Aaron Culliney
*
*/
#include "common.h"
#ifndef NDEBUG
void *_a2_malloc(size_t size) {
const size_t totalSize = sizeof(size_t)+_BUF_FENCE_SZ+size+_BUF_FENCE_SZ;
char *p = (char *)malloc(totalSize);
if (p) {
*((size_t *)p) = totalSize;
*((uint32_t *)(p+sizeof(size_t))) = _BUF_SENTINEL;
*((uint32_t *)(p+totalSize-_BUF_FENCE_SZ)) = _BUF_SENTINEL;
p += sizeof(size_t)+_BUF_FENCE_SZ;
}
return p;
}
void *_a2_calloc(size_t nmemb, size_t size) {
size *= nmemb;
const size_t totalSize = sizeof(size_t)+_BUF_FENCE_SZ+size+_BUF_FENCE_SZ;
char *p = (char *)calloc(totalSize, 1);
if (p) {
*((size_t *)p) = totalSize;
*((uint32_t *)(p+sizeof(size_t))) = _BUF_SENTINEL;
*((uint32_t *)(p+totalSize-_BUF_FENCE_SZ)) = _BUF_SENTINEL;
p += sizeof(size_t)+_BUF_FENCE_SZ;
}
return p;
}
void *_a2_realloc(void *ptr, size_t size) {
char *p = (char *)ptr;
if (!p) {
return _a2_malloc(size);
}
if (size == 0) {
FREE(ptr);
return NULL;
}
// verify prior allocation is sane
p = p-_BUF_FENCE_SZ-sizeof(size_t);
const size_t totalSizeBefore = *((size_t *)p);
assert( *((uint32_t *)(p+sizeof(size_t))) == _BUF_SENTINEL && "1st memory sentinel invalid!" );
assert( *((uint32_t *)(p+totalSizeBefore-_BUF_FENCE_SZ)) == _BUF_SENTINEL && "2nd memory sentinel invalid!" );
const size_t totalSizeAfter = sizeof(size_t)+_BUF_FENCE_SZ+size+_BUF_FENCE_SZ;
assert(totalSizeAfter > totalSizeBefore && "FIXME fenced realloc() to smaller sizes not implemented!");
p = (char *)realloc(p, totalSizeAfter);
if (p) {
*((size_t *)p) = totalSizeAfter;
assert( *((uint32_t *)(p+sizeof(size_t))) == _BUF_SENTINEL && "1st memory sentinel invalid!" );
*((uint32_t *)(p+totalSizeAfter-_BUF_FENCE_SZ)) = _BUF_SENTINEL;
p += sizeof(size_t)+_BUF_FENCE_SZ;
}
return p;
}
void _a2_free(void *ptr) {
char *p = (char *)ptr;
if (!p) {
return;
}
p = p-_BUF_FENCE_SZ-sizeof(size_t);
const size_t totalSize = *((size_t *)p);
assert( *((uint32_t *)(p+sizeof(size_t))) == _BUF_SENTINEL && "1st memory sentinel invalid!" );
assert( *((uint32_t *)(p+totalSize-_BUF_FENCE_SZ)) == _BUF_SENTINEL && "2nd memory sentinel invalid!" );
memset(p, 0xAA, totalSize);
free(p);
}
char *_a2_strndup(const char *str, size_t len) {
if (len == 0) {
len = strlen(str);
}
char *dst = NULL;
do {
dst = (char *)_a2_malloc(len+1);
memcpy(dst, str, len);
*(dst+len) = '\0';
} while (0);
return dst;
}
int _a2_asprintf(char **strp, const char *fmt, ...) {
char *strp0 = NULL;
int ret = -1;
va_list args;
va_start(args, fmt);
ret = vasprintf(&strp0, fmt, args);
va_end(args);
if (ret > 0) {
assert(*strp0);
*strp = _a2_malloc(ret+1);
memcpy(*strp, strp0, ret);
*((*strp)+ret) = '\0';
free(strp0);
}
return ret;
}
#endif // NDEBUG

View File

@ -5,7 +5,7 @@
* version 3 or later (your choice) as published by the Free Software
* Foundation.
*
* Copyright 2013-2015 Aaron Culliney
* Copyright 2015-2016 Aaron Culliney
*
*/
@ -21,14 +21,13 @@
(ptr) = NULL; \
} while (0)
#define ASPRINTF_FREE(ptr) _FREE((ptr), free)
#define STRDUP_FREE(ptr) _FREE((ptr), free)
#define GETLINE_FREE(ptr) _FREE((ptr), free)
#ifdef NDEBUG
# define MALLOC(size) malloc((size))
# define CALLOC(nmemb, size) calloc((nmemb), (size))
# define REALLOC(ptr, size) realloc((ptr), (size))
# define STRDUP(str) strdup((str))
# define STRNDUP(str, n) strndup((str), (n))
# define ASPRINTF(s, f, ...) asprintf((s), (f), __VA_ARGS__)
# define FREE(ptr) _FREE((ptr), free)
#else
@ -38,78 +37,25 @@
# define MALLOC(size) _a2_malloc((size))
# define CALLOC(nmemb, size) _a2_calloc((nmemb), (size))
# define REALLOC(ptr, size) _a2_realloc((ptr), (size))
# define STRDUP(str) _a2_strndup((str), 0)
# define STRNDUP(str, n) _a2_strndup((str), (n))
# define ASPRINTF(s, f, ...) _a2_asprintf((s), (f), __VA_ARGS__)
# define FREE(ptr) _FREE((ptr), _a2_free)
# define _BUF_SENTINEL 0xDEADC0DEUL
# define _BUF_FENCE_SZ (sizeof(_BUF_SENTINEL))
static inline void *_a2_malloc(size_t size) {
const size_t totalSize = sizeof(size_t)+_BUF_FENCE_SZ+size+_BUF_FENCE_SZ;
char *p = (char *)malloc(totalSize);
if (p) {
*((size_t *)p) = totalSize;
*((uint32_t *)(p+sizeof(size_t))) = _BUF_SENTINEL;
*((uint32_t *)(p+totalSize-_BUF_FENCE_SZ)) = _BUF_SENTINEL;
p += sizeof(size_t)+_BUF_FENCE_SZ;
}
return p;
}
void *_a2_malloc(size_t size);
static inline void *_a2_calloc(size_t nmemb, size_t size) {
size *= nmemb;
const size_t totalSize = sizeof(size_t)+_BUF_FENCE_SZ+size+_BUF_FENCE_SZ;
char *p = (char *)calloc(totalSize, 1);
if (p) {
*((size_t *)p) = totalSize;
*((uint32_t *)(p+sizeof(size_t))) = _BUF_SENTINEL;
*((uint32_t *)(p+totalSize-_BUF_FENCE_SZ)) = _BUF_SENTINEL;
p += sizeof(size_t)+_BUF_FENCE_SZ;
}
return p;
}
void *_a2_calloc(size_t nmemb, size_t size);
static inline void _a2_free(void *ptr) {
char *p = (char *)ptr;
if (!p) {
return;
}
p = p-_BUF_FENCE_SZ-sizeof(size_t);
const size_t totalSize = *((size_t *)p);
assert( *((uint32_t *)(p+sizeof(size_t))) == _BUF_SENTINEL && "1st memory sentinel invalid!" );
assert( *((uint32_t *)(p+totalSize-_BUF_FENCE_SZ)) == _BUF_SENTINEL && "2nd memory sentinel invalid!" );
memset(p, 0xAA, totalSize);
free(p);
}
void _a2_free(void *ptr);
static inline void *_a2_realloc(void *ptr, size_t size) {
char *p = (char *)ptr;
if (!p) {
return _a2_malloc(size);
}
if (size == 0) {
FREE(ptr);
return NULL;
}
void *_a2_realloc(void *ptr, size_t size);
// verify prior allocation is sane
p = p-_BUF_FENCE_SZ-sizeof(size_t);
const size_t totalSizeBefore = *((size_t *)p);
assert( *((uint32_t *)(p+sizeof(size_t))) == _BUF_SENTINEL && "1st memory sentinel invalid!" );
assert( *((uint32_t *)(p+totalSizeBefore-_BUF_FENCE_SZ)) == _BUF_SENTINEL && "2nd memory sentinel invalid!" );
char *_a2_strndup(const char *s, size_t size);
const size_t totalSizeAfter = sizeof(size_t)+_BUF_FENCE_SZ+size+_BUF_FENCE_SZ;
assert(totalSizeAfter > totalSizeBefore && "FIXME fenced realloc() to smaller sizes not implemented!");
p = (char *)realloc(p, totalSizeAfter);
if (p) {
*((size_t *)p) = totalSizeAfter;
assert( *((uint32_t *)(p+sizeof(size_t))) == _BUF_SENTINEL && "1st memory sentinel invalid!" );
*((uint32_t *)(p+totalSizeAfter-_BUF_FENCE_SZ)) = _BUF_SENTINEL;
p += sizeof(size_t)+_BUF_FENCE_SZ;
}
return p;
}
int _a2_asprintf(char **strp, const char *fmt, ...);
#endif

View File

@ -2368,7 +2368,7 @@ YY_RULE_SETUP
char *buf = NULL;
asprintf(&buf, "%s/%s", getenv("HOME"), "cputrace.txt");
cpu65_trace_toggle(buf);
ASPRINTF_FREE(buf);
FREE(buf);
#else
LOG("CPU tracing not enabled...");
#endif
@ -2383,7 +2383,7 @@ YY_RULE_SETUP
char *buf = NULL;
asprintf(&buf, "%s/%s", getenv("HOME"), "disktrace.txt");
c_toggle_disk_trace_6(buf, NULL);
ASPRINTF_FREE(buf);
FREE(buf);
#else
LOG("Disk tracing not enabled...");
#endif

View File

@ -854,7 +854,7 @@ ADDRS [0-9a-fA-F]+
char *buf = NULL;
asprintf(&buf, "%s/%s", getenv("HOME"), "cputrace.txt");
cpu65_trace_toggle(buf);
ASPRINTF_FREE(buf);
FREE(buf);
#else
LOG("CPU tracing not enabled...");
#endif
@ -865,7 +865,7 @@ ADDRS [0-9a-fA-F]+
char *buf = NULL;
asprintf(&buf, "%s/%s", getenv("HOME"), "disktrace.txt");
c_toggle_disk_trace_6(buf, NULL);
ASPRINTF_FREE(buf);
FREE(buf);
#else
LOG("Disk tracing not enabled...");
#endif

View File

@ -38,7 +38,7 @@ CrashHandler_s *crashHandler = NULL;
#if defined(CONFIG_DATADIR)
static void _init_common(void) {
LOG("Initializing common...");
data_dir = strdup(CONFIG_DATADIR PATH_SEPARATOR PACKAGE_NAME);
data_dir = STRDUP(CONFIG_DATADIR PATH_SEPARATOR PACKAGE_NAME);
}
static __attribute__((constructor)) void __init_common(void) {

View File

@ -303,7 +303,7 @@ void load_settings(void)
}
}
GETLINE_FREE(buffer);
free(buffer);
fclose(config_file);
}

View File

@ -182,7 +182,7 @@ int test_setup_boot_disk(const char *fileName, int readonly) {
while (*path) {
char *disk = *path;
++path;
ASPRINTF_FREE(disk);
FREE(disk);
}
return err;

View File

@ -86,7 +86,7 @@ TEST test_boot_disk_bytes() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
PASS();
}
@ -134,7 +134,7 @@ TEST test_boot_disk_bytes_nib() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
PASS();
}
@ -187,7 +187,7 @@ TEST test_boot_disk_bytes_po() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
PASS();
}
@ -382,7 +382,7 @@ TEST test_disk_bytes_savehello_dsk() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
REBOOT_TO_DOS();
c_debugger_go();
@ -476,7 +476,7 @@ TEST test_disk_bytes_savehello_nib() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
REBOOT_TO_DOS();
c_debugger_go();
@ -570,7 +570,7 @@ TEST test_disk_bytes_savehello_po() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
REBOOT_TO_DOS();
c_debugger_go();
@ -683,7 +683,7 @@ TEST test_outofspace_dsk() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
REBOOT_TO_DOS();
c_debugger_go();
@ -951,7 +951,7 @@ TEST test_bload_trace_dsk() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
disk6_eject(0);
@ -1069,7 +1069,7 @@ TEST test_bload_trace_nib() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
disk6_eject(0);
@ -1187,7 +1187,7 @@ TEST test_bload_trace_po() {
} while(0);
unlink(disk);
ASPRINTF_FREE(disk);
FREE(disk);
disk6_eject(0);

View File

@ -98,15 +98,15 @@ TEST test_json_map_1() {
json_mapCopyStringValue(&parsedData, "key0", &val);
ASSERT(strcmp(val, "a value zero") == 0);
STRDUP_FREE(val);
FREE(val);
json_mapCopyStringValue(&parsedData, "key1", &val);
ASSERT(strcmp(val, " \t ") == 0);
STRDUP_FREE(val);
FREE(val);
json_mapCopyStringValue(&parsedData, "key2", &val);
ASSERT(strcmp(val, "{ \t \n}") == 0);
STRDUP_FREE(val);
FREE(val);
json_mapCopyStringValue(&parsedData, "key3", &val);
ASSERT(strcmp(val, "{ \t \n \"subkey0\" : \"subval0\", \"subkey1\" : { \"moar\" : \"recursion\" } , \"subkey2\" : \"line0 \n \tline1 \tline2\" \n}") == 0);
@ -120,26 +120,26 @@ TEST test_json_map_1() {
char *subval;
json_mapCopyStringValue(&parsedSubData, "subkey0", &subval);
ASSERT(strcmp(subval, "subval0") == 0);
STRDUP_FREE(subval);
FREE(subval);
json_mapCopyStringValue(&parsedSubData, "subkey1", &subval);
ASSERT(strcmp(subval, "{ \"moar\" : \"recursion\" }") == 0);
STRDUP_FREE(subval);
FREE(subval);
json_mapCopyStringValue(&parsedSubData, "subkey2", &subval);
ASSERT(strcmp(subval, "line0 \n \tline1 \tline2") == 0);
STRDUP_FREE(subval);
FREE(subval);
}
STRDUP_FREE(val);
FREE(val);
json_mapCopyStringValue(&parsedData, "key4", &val);
ASSERT(strcmp(val, "[ \"Q\", \"W\", \"E\", \"R\", \"T\", \"Y\", \"U\", \"I\", \"O\", \"P\", { \"x\" : [ 22, 4, \"ab\" ] } ]") == 0);
// TODO : subarray checks
STRDUP_FREE(val);
FREE(val);
json_mapCopyStringValue(&parsedData, "key5", &val);
ASSERT(strcmp(val, "") == 0);
STRDUP_FREE(val);
FREE(val);
json_mapParseLongValue(&parsedData, "intKey0", &lVal, 10);
ASSERT(lVal == 42);

View File

@ -66,10 +66,10 @@ demoSource *glshader_createSource(const char *fileName) {
CFRELEASE(filePath);
#else
char *filePath = NULL;
asprintf(&filePath, "%s/shaders/%s", data_dir, fileName);
ASPRINTF(&filePath, "%s/shaders/%s", data_dir, fileName);
if (filePath) {
src = srcLoadSource(filePath);
ASPRINTF_FREE(filePath);
FREE(filePath);
} else {
ERRLOG("OOPS Could not load shader from %s (%s)", filePath, fileName);
}