forked from Telodendria/Telodendria
Re-add memory bounds checking.
Also fixed a recursive lock error in some configurations, and replaced a usage of strcpy() with strncpy().
This commit is contained in:
parent
a358ca795d
commit
bd1918ee05
2 changed files with 58 additions and 23 deletions
77
src/Memory.c
77
src/Memory.c
|
@ -50,6 +50,13 @@ struct MemoryInfo
|
||||||
void *pointer;
|
void *pointer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MEM_BOUND_TYPE UInt32
|
||||||
|
#define MEM_BOUND 0xDEADBEEF
|
||||||
|
|
||||||
|
#define MEM_BOUND_LOWER(p) *((MEM_BOUND_TYPE *) p)
|
||||||
|
#define MEM_BOUND_UPPER(p, x) *(((MEM_BOUND_TYPE *) (((UInt8 *) p) + x)) + 1)
|
||||||
|
#define MEM_SIZE_ACTUAL(x) (((x) * sizeof(UInt8)) + (2 * sizeof(MEM_BOUND_TYPE)))
|
||||||
|
|
||||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static void (*hook) (MemoryAction, MemoryInfo *, void *) = NULL;
|
static void (*hook) (MemoryAction, MemoryInfo *, void *) = NULL;
|
||||||
static void *hookArgs = NULL;
|
static void *hookArgs = NULL;
|
||||||
|
@ -149,12 +156,29 @@ MemoryDelete(MemoryInfo * a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
MemoryCheck(MemoryInfo * a)
|
||||||
|
{
|
||||||
|
if (MEM_BOUND_LOWER(a->pointer) != MEM_BOUND ||
|
||||||
|
MEM_BOUND_UPPER(a->pointer, a->size - (2 * sizeof(MEM_BOUND_TYPE))) != MEM_BOUND)
|
||||||
|
{
|
||||||
|
if (hook)
|
||||||
|
{
|
||||||
|
hook(MEMORY_CORRUPTED, a, hookArgs);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
MemoryAllocate(size_t size, const char *file, int line)
|
MemoryAllocate(size_t size, const char *file, int line)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
MemoryInfo *a;
|
MemoryInfo *a;
|
||||||
|
|
||||||
|
MemoryIterate(NULL, NULL);
|
||||||
|
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
|
|
||||||
a = malloc(sizeof(MemoryInfo));
|
a = malloc(sizeof(MemoryInfo));
|
||||||
|
@ -164,7 +188,7 @@ MemoryAllocate(size_t size, const char *file, int line)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = malloc(size);
|
p = malloc(MEM_SIZE_ACTUAL(size));
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
free(a);
|
free(a);
|
||||||
|
@ -172,9 +196,11 @@ MemoryAllocate(size_t size, const char *file, int line)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(p, 0, size);
|
memset(p, 0, MEM_SIZE_ACTUAL(size));
|
||||||
|
MEM_BOUND_LOWER(p) = MEM_BOUND;
|
||||||
|
MEM_BOUND_UPPER(p, size) = MEM_BOUND;
|
||||||
|
|
||||||
a->size = size;
|
a->size = MEM_SIZE_ACTUAL(size);
|
||||||
a->file = file;
|
a->file = file;
|
||||||
a->line = line;
|
a->line = line;
|
||||||
a->pointer = p;
|
a->pointer = p;
|
||||||
|
@ -193,7 +219,7 @@ MemoryAllocate(size_t size, const char *file, int line)
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
return p;
|
return ((MEM_BOUND_TYPE *) p) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -202,6 +228,8 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
|
||||||
MemoryInfo *a;
|
MemoryInfo *a;
|
||||||
void *new = NULL;
|
void *new = NULL;
|
||||||
|
|
||||||
|
MemoryIterate(NULL, NULL);
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
return MemoryAllocate(size, file, line);
|
return MemoryAllocate(size, file, line);
|
||||||
|
@ -211,17 +239,20 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
|
||||||
if (a)
|
if (a)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
new = realloc(a->pointer, size);
|
new = realloc(a->pointer, MEM_SIZE_ACTUAL(size));
|
||||||
if (new)
|
if (new)
|
||||||
{
|
{
|
||||||
MemoryDelete(a);
|
MemoryDelete(a);
|
||||||
a->size = size;
|
a->size = MEM_SIZE_ACTUAL(size);
|
||||||
a->file = file;
|
a->file = file;
|
||||||
a->line = line;
|
a->line = line;
|
||||||
|
|
||||||
a->pointer = new;
|
a->pointer = new;
|
||||||
MemoryInsert(a);
|
MemoryInsert(a);
|
||||||
|
|
||||||
|
MEM_BOUND_LOWER(a->pointer) = MEM_BOUND;
|
||||||
|
MEM_BOUND_UPPER(a->pointer, size) = MEM_BOUND;
|
||||||
|
|
||||||
if (hook)
|
if (hook)
|
||||||
{
|
{
|
||||||
hook(MEMORY_REALLOCATE, a, hookArgs);
|
hook(MEMORY_REALLOCATE, a, hookArgs);
|
||||||
|
@ -244,7 +275,7 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new;
|
return ((MEM_BOUND_TYPE *) new) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -252,6 +283,8 @@ MemoryFree(void *p, const char *file, int line)
|
||||||
{
|
{
|
||||||
MemoryInfo *a;
|
MemoryInfo *a;
|
||||||
|
|
||||||
|
MemoryIterate(NULL, NULL);
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -340,6 +373,7 @@ MemoryInfoGet(void *p)
|
||||||
|
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
|
|
||||||
|
p = ((MEM_BOUND_TYPE *) p) - 1;
|
||||||
hash = MemoryHash(p);
|
hash = MemoryHash(p);
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
@ -352,6 +386,7 @@ MemoryInfoGet(void *p)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
MemoryCheck(allocations[hash]);
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
return allocations[hash];
|
return allocations[hash];
|
||||||
}
|
}
|
||||||
|
@ -369,7 +404,7 @@ MemoryInfoGetSize(MemoryInfo * a)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return a->size;
|
return a->size ? a->size - (2 * sizeof(MEM_BOUND_TYPE)) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -402,7 +437,7 @@ MemoryInfoGetPointer(MemoryInfo * a)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return a->pointer;
|
return ((MEM_BOUND_TYPE *) a->pointer) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -416,6 +451,7 @@ void
|
||||||
{
|
{
|
||||||
if (allocations[i])
|
if (allocations[i])
|
||||||
{
|
{
|
||||||
|
MemoryCheck(allocations[i]);
|
||||||
if (iterFunc)
|
if (iterFunc)
|
||||||
{
|
{
|
||||||
iterFunc(allocations[i], args);
|
iterFunc(allocations[i], args);
|
||||||
|
@ -471,28 +507,27 @@ MemoryDefaultHook(MemoryAction a, MemoryInfo * i, void *args)
|
||||||
switch (a)
|
switch (a)
|
||||||
{
|
{
|
||||||
case MEMORY_BAD_POINTER:
|
case MEMORY_BAD_POINTER:
|
||||||
write(STDOUT_FILENO, "Bad pointer: 0x", 15);
|
write(STDERR_FILENO, "Bad pointer: 0x", 15);
|
||||||
break;
|
break;
|
||||||
case MEMORY_CORRUPTED:
|
case MEMORY_CORRUPTED:
|
||||||
write(STDOUT_FILENO, "Corrupted block: 0x", 19);
|
write(STDERR_FILENO, "Corrupted block: 0x", 19);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
write(STDOUT_FILENO, buf, len);
|
write(STDERR_FILENO, buf, len);
|
||||||
write(STDOUT_FILENO, " to 0x", 6);
|
write(STDERR_FILENO, " to 0x", 6);
|
||||||
len = HexPtr(MemoryInfoGetSize(i), buf, sizeof(buf));
|
len = HexPtr(MemoryInfoGetSize(i), buf, sizeof(buf));
|
||||||
write(STDOUT_FILENO, buf, len);
|
write(STDERR_FILENO, buf, len);
|
||||||
write(STDOUT_FILENO, " bytes at ", 10);
|
write(STDERR_FILENO, " bytes at ", 10);
|
||||||
write(STDOUT_FILENO, MemoryInfoGetFile(i), strlen(MemoryInfoGetFile(i)));
|
write(STDERR_FILENO, MemoryInfoGetFile(i), strlen(MemoryInfoGetFile(i)));
|
||||||
write(STDOUT_FILENO, ":0x", 3);
|
write(STDERR_FILENO, ":0x", 3);
|
||||||
len = HexPtr(MemoryInfoGetLine(i), buf, sizeof(buf));
|
len = HexPtr(MemoryInfoGetLine(i), buf, sizeof(buf));
|
||||||
write(STDOUT_FILENO, buf, len);
|
write(STDERR_FILENO, buf, len);
|
||||||
write(STDOUT_FILENO, "\n", 1);
|
write(STDERR_FILENO, "\n", 1);
|
||||||
#if 0
|
|
||||||
raise(SIGSEGV);
|
raise(SIGSEGV);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -248,7 +248,7 @@ UtilGetLine(char **linePtr, size_t * n, Stream * stream)
|
||||||
static void
|
static void
|
||||||
ThreadNoDestructor(void *p)
|
ThreadNoDestructor(void *p)
|
||||||
{
|
{
|
||||||
Free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
|
@ -269,7 +269,7 @@ UtilThreadNo(void)
|
||||||
no = pthread_getspecific(key);
|
no = pthread_getspecific(key);
|
||||||
if (!no)
|
if (!no)
|
||||||
{
|
{
|
||||||
no = Malloc(sizeof(unsigned long));
|
no = malloc(sizeof(unsigned long));
|
||||||
*no = count++;
|
*no = count++;
|
||||||
pthread_setspecific(key, no);
|
pthread_setspecific(key, no);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue