Make Memory use a recursive mutex.

This allows some additional operations to be performed inside the memory
hooks, although it's still a bad idea to allocate or free memory while
inside the hook.
This commit is contained in:
Jordan Bancino 2023-06-04 18:44:37 +00:00
parent 3ef8a2b234
commit a177c55c26
2 changed files with 69 additions and 13 deletions

View file

@ -57,14 +57,42 @@ struct MemoryInfo
#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 void (*hook) (MemoryAction, MemoryInfo *, void *) = NULL;
static pthread_mutex_t lock;
static void (*hook) (MemoryAction, MemoryInfo *, void *) = MemoryDefaultHook;
static void *hookArgs = NULL;
static MemoryInfo **allocations = NULL;
static size_t allocationsSize = 0;
static size_t allocationsLen = 0;
int
MemoryRuntimeInit(void)
{
pthread_mutexattr_t attr;
int ret = 0;
if (pthread_mutexattr_init(&attr) != 0)
{
goto finish;
}
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
ret = pthread_mutex_init(&lock, &attr);
pthread_mutexattr_destroy(&attr);
ret = (ret == 0);
finish:
return ret;
}
int
MemoryRuntimeDestroy(void)
{
MemoryFreeAll();
return pthread_mutex_destroy(&lock) == 0;
}
static size_t
MemoryHash(void *p)
{

View file

@ -33,12 +33,18 @@
#include <string.h>
#include <pthread.h>
#define ERR_BUF_SIZE 128
/* Specified by POSIX to contain environment variables */
extern char **environ;
/* The linking program is expected to provide Main */
extern int Main(Array *, HashMap *);
/* Functions in the Memory API that are not exported via header */
extern int MemoryRuntimeInit(void);
extern int MemoryRuntimeDestroy(void);
typedef struct MainArgs
{
Array *args;
@ -69,32 +75,46 @@ main(int argc, char **argv)
MainArgs args;
MemoryHook(MemoryDefaultHook, NULL);
char errBuf[ERR_BUF_SIZE];
int errLen;
args.args = NULL;
args.env = NULL;
args.ret = EXIT_FAILURE;
if (!MemoryRuntimeInit())
{
errLen = snprintf(errBuf, ERR_BUF_SIZE, "Fatal: Unable to initialize Memory runtime.\n");
write(STDERR_FILENO, errBuf, errLen);
goto finish;
}
args.args = ArrayCreate();
if (!args.args)
{
Log(LOG_ERR, "Bootstrap error: Unable to allocate memory for arguments.");
args.ret = EXIT_FAILURE;
errLen = snprintf(errBuf, ERR_BUF_SIZE, "Fatal: Unable to allocate heap memory for program arguments.\n");
write(STDERR_FILENO, errBuf, errLen);
goto finish;
}
args.env = HashMapCreate();
if (!args.env)
{
Log(LOG_ERR, "Bootstrap error: Unable to allocate memory for environment.");
args.ret = EXIT_FAILURE;
errLen = snprintf(errBuf, ERR_BUF_SIZE, "Fatal: Unable to allocate heap memory for program environment.\n");
write(STDERR_FILENO, errBuf, errLen);
goto finish;
}
for (i = 0; i < (size_t) argc; i++)
{
ArrayAdd(args.args, StrDuplicate(argv[i]));
char *arg = StrDuplicate(argv[i]);
if (!arg || !ArrayAdd(args.args, arg))
{
errLen = snprintf(errBuf, ERR_BUF_SIZE, "Fatal: Unable to allocate heap memory for program argument.\n");
write(STDERR_FILENO, errBuf, errLen);
goto finish;
}
}
envp = environ;
@ -105,6 +125,14 @@ main(int argc, char **argv)
/* It is unclear whether or not envp strings are writable, so
* we make our own copy to manipulate it */
key = StrDuplicate(*envp);
if (!key)
{
errLen = snprintf(errBuf, ERR_BUF_SIZE, "Fatal: Unable to allocate heap memory for program environment variable.\n");
write(STDERR_FILENO, errBuf, errLen);
goto finish;
}
valInd = strcspn(key, "=");
key[valInd] = '\0';
@ -116,15 +144,15 @@ main(int argc, char **argv)
if (pthread_create(&mainThread, NULL, MainThread, &args) != 0)
{
Log(LOG_ERR, "Bootstrap error: Unable to create main thread.");
args.ret = EXIT_FAILURE;
errLen = snprintf(errBuf, ERR_BUF_SIZE, "Fatal: Unable to create main thread.\n");
write(STDERR_FILENO, errBuf, errLen);
goto finish;
}
if (pthread_join(mainThread, NULL) != 0)
{
/* Should never happen */
Log(LOG_ERR, "Unable to join main thread.");
errLen = snprintf(errBuf, ERR_BUF_SIZE, "Fatal: Unable to join main thread.\n");
write(STDERR_FILENO, errBuf, errLen);
args.ret = EXIT_FAILURE;
goto finish;
}
@ -156,7 +184,7 @@ finish:
GenerateMemoryReport(argc, argv);
MemoryFreeAll();
MemoryRuntimeDestroy();
return args.ret;
}