forked from Telodendria/Telodendria
Add sane default memory hook to Cytoplasm, fix more leaks in json.
This commit is contained in:
parent
e22cf38eac
commit
2693b89598
6 changed files with 76 additions and 4 deletions
|
@ -124,7 +124,6 @@ LogConfigFree(LogConfig * config)
|
|||
}
|
||||
|
||||
pthread_mutex_destroy(&config->lock);
|
||||
Free(config->tsFmt);
|
||||
Free(config);
|
||||
|
||||
if (config == globalConfig)
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <Int.h>
|
||||
|
@ -154,7 +157,7 @@ MemoryDelete(MemoryInfo * a)
|
|||
}
|
||||
|
||||
static int
|
||||
MemoryCheck(MemoryInfo *a)
|
||||
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)
|
||||
|
@ -458,6 +461,64 @@ void
|
|||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
static size_t
|
||||
HexPtr(unsigned long ptr, char *out, size_t len)
|
||||
{
|
||||
size_t i = len - 1;
|
||||
size_t j = 0;
|
||||
|
||||
do
|
||||
{
|
||||
out[i] = "0123456789abcdef"[ptr % 16];
|
||||
i--;
|
||||
ptr /= 16;
|
||||
} while (ptr > 0);
|
||||
|
||||
while (++i < len)
|
||||
{
|
||||
out[j++] = out[i];
|
||||
}
|
||||
|
||||
out[j] = '\0';
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
void
|
||||
MemoryDefaultHook(MemoryAction a, MemoryInfo * i, void *args)
|
||||
{
|
||||
char buf[64];
|
||||
unsigned long ptr = (unsigned long) MemoryInfoGetPointer(i);
|
||||
|
||||
size_t len = HexPtr(ptr, buf, sizeof(buf));
|
||||
|
||||
(void) args;
|
||||
|
||||
switch (a)
|
||||
{
|
||||
case MEMORY_BAD_POINTER:
|
||||
write(STDERR_FILENO, "Bad pointer: 0x", 15);
|
||||
break;
|
||||
case MEMORY_CORRUPTED:
|
||||
write(STDERR_FILENO, "Corrupted block: 0x", 19);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
write(STDERR_FILENO, buf, len);
|
||||
write(STDERR_FILENO, " to 0x", 6);
|
||||
len = HexPtr(MemoryInfoGetSize(i), buf, sizeof(buf));
|
||||
write(STDERR_FILENO, buf, len);
|
||||
write(STDERR_FILENO, " bytes at ", 10);
|
||||
write(STDERR_FILENO, MemoryInfoGetFile(i), strlen(MemoryInfoGetFile(i)));
|
||||
write(STDERR_FILENO, ":0x", 3);
|
||||
len = HexPtr(MemoryInfoGetLine(i), buf, sizeof(buf));
|
||||
write(STDERR_FILENO, buf, len);
|
||||
write(STDERR_FILENO, "\n", 1);
|
||||
raise(SIGSEGV);
|
||||
}
|
||||
|
||||
void
|
||||
MemoryHexDump(MemoryInfo * info, void (*printFunc) (size_t, char *, char *, void *), void *args)
|
||||
{
|
||||
|
|
|
@ -70,6 +70,8 @@ main(int argc, char **argv)
|
|||
|
||||
MainArgs args;
|
||||
|
||||
MemoryHook(MemoryDefaultHook, NULL);
|
||||
|
||||
args.args = NULL;
|
||||
args.env = NULL;
|
||||
|
||||
|
|
|
@ -199,6 +199,15 @@ extern void MemoryIterate(void (*) (MemoryInfo *, void *), void *);
|
|||
*/
|
||||
extern void MemoryHook(void (*) (MemoryAction, MemoryInfo *, void *), void *);
|
||||
|
||||
/**
|
||||
* The default memory hook, which has sane behavior and is installed
|
||||
* at runtime. This function does not use any memory on the heap,
|
||||
* except for the MemoryInfo passed to it, which it assumes to be
|
||||
* valid. Everything else happens on the stack only, to ensure that
|
||||
* the hook doesn't make any memory problems worse.
|
||||
*/
|
||||
extern void MemoryDefaultHook(MemoryAction, MemoryInfo *, void *);
|
||||
|
||||
/**
|
||||
* Read over the block of memory represented by the given memory info
|
||||
* structure and generate a hexadecimal and ASCII string for each
|
||||
|
|
2
TODO.txt
2
TODO.txt
|
@ -28,7 +28,7 @@ Milestone: v0.3.0
|
|||
[x] hdoc(1) and hdoc(5)
|
||||
[x] Fix memory leaks in hdoc
|
||||
[x] Detect memory write out of bounds
|
||||
[ ] Add a sane default memory hook
|
||||
[x] Add a sane default memory hook
|
||||
|
||||
Milestone: v0.4.0
|
||||
-----------------
|
||||
|
|
|
@ -223,7 +223,7 @@ Main(Array * args)
|
|||
switch (flag)
|
||||
{
|
||||
case FLAG_SELECT:
|
||||
query(input, json);
|
||||
query(input, json); /* This will implicitly free json */
|
||||
break;
|
||||
case FLAG_ENCODE:
|
||||
encode(input);
|
||||
|
@ -231,6 +231,7 @@ Main(Array * args)
|
|||
default:
|
||||
JsonEncode(json, StreamStdout(), JSON_PRETTY);
|
||||
StreamPutc(StreamStdout(), '\n');
|
||||
JsonFree(json);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue