summaryrefslogtreecommitdiff
path: root/accel-pppd/memdebug.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/memdebug.c')
-rw-r--r--accel-pppd/memdebug.c121
1 files changed, 92 insertions, 29 deletions
diff --git a/accel-pppd/memdebug.c b/accel-pppd/memdebug.c
index 8e9dd4b..1f4af36 100644
--- a/accel-pppd/memdebug.c
+++ b/accel-pppd/memdebug.c
@@ -1,5 +1,6 @@
#undef MEMDEBUG
+#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@@ -25,7 +26,7 @@
(type *)( (char *)__mptr - offsetof(type,member) );})
-#define MAGIC1 0x1122334455667788llu
+#define MAGIC1 UINT64_C(0x1122334455667788)
struct mem_t
{
@@ -41,10 +42,13 @@ struct mem_t
static LIST_HEAD(mem_list);
static spinlock_t mem_list_lock = SPINLOCK_INITIALIZER;
-struct mem_t *_md_malloc(size_t size, const char *fname, int line)
+static struct mem_t *_md_malloc(size_t size, const char *fname, int line)
{
struct mem_t *mem = malloc(sizeof(*mem) + size + 8);
+ if (mem == NULL)
+ return NULL;
+
if (size > 4096)
line = 0;
@@ -66,25 +70,26 @@ void __export *md_malloc(size_t size, const char *fname, int line)
{
struct mem_t *mem = _md_malloc(size, fname, line);
- return mem->data;
+ return mem ? mem->data : NULL;
}
void __export md_free(void *ptr, const char *fname, int line)
{
- struct mem_t *mem = container_of(ptr, typeof(*mem), data);
+ struct mem_t *mem;
+
+ if (!ptr)
+ return;
+
+ mem = container_of(ptr, typeof(*mem), data);
- if (!ptr) {
- printf("free null pointer at %s:%i\n", fname, line);
- abort();
- }
-
if (mem->magic1 != MAGIC1) {
printf("memory corruption:\nfree at %s:%i\n", fname, line);
abort();
}
if (mem->magic2 != *(uint64_t*)(mem->data + mem->size)) {
- printf("memory corruption:\nmalloc(%lu) at %s:%i\nfree at %s:%i\n", (long unsigned)mem->size, mem->fname, mem->line, fname, line);
+ printf("memory corruption:\nmalloc(%zu) at %s:%i\nfree at %s:%i\n",
+ mem->size, mem->fname, mem->line, fname, line);
abort();
}
@@ -101,40 +106,98 @@ void __export md_free(void *ptr, const char *fname, int line)
void __export *md_realloc(void *ptr, size_t size, const char *fname, int line)
{
- struct mem_t *mem = container_of(ptr, typeof(*mem), data);
+ struct mem_t *mem = ptr ? container_of(ptr, typeof(*mem), data) : NULL;
struct mem_t *mem2;
-
- if (mem->magic1 != MAGIC1) {
- printf("memory corruption:\nfree at %s:%i\n", fname, line);
- abort();
- }
- if (mem->magic2 != *(uint64_t*)(mem->data + mem->size)) {
- printf("memory corruption:\nmalloc(%lu) at %s:%i\nfree at %s:%i\n", (long unsigned)mem->size, mem->fname, mem->line, fname, line);
- abort();
+ if (mem) {
+ if (mem->magic1 != MAGIC1) {
+ printf("memory corruption:\nfree at %s:%i\n",
+ fname, line);
+ abort();
+ }
+
+ if (mem->magic2 != *(uint64_t*)(mem->data + mem->size)) {
+ printf("memory corruption:\nmalloc(%zu) at %s:%i\nfree at %s:%i\n",
+ mem->size, mem->fname, mem->line, fname, line);
+ abort();
+ }
+
+ if (size == 0) {
+ md_free(mem->data, fname, line);
+ return NULL;
+ }
}
mem2 = _md_malloc(size, fname, line);
- memcpy(mem2->data, mem->data, mem->size);
-
- md_free(mem->data, fname, line);
+ if (mem2 == NULL)
+ return NULL;
+
+ if (mem) {
+ memcpy(mem2->data, mem->data,
+ (size < mem->size) ? size : mem->size);
+ md_free(mem->data, fname, line);
+ }
return mem2->data;
}
char __export *md_strdup(const char *ptr, const char *fname, int line)
{
- struct mem_t *mem = _md_malloc(strlen(ptr) + 1, fname, line);
- memcpy(mem->data, ptr, strlen(ptr) + 1);
- return mem->data;
+ size_t len = strlen(ptr);
+ char *str = md_malloc(len + 1, fname, line);
+
+ if (str)
+ memcpy(str, ptr, len + 1);
+
+ return str;
}
char __export *md_strndup(const char *ptr, size_t n, const char *fname, int line)
{
- struct mem_t *mem = _md_malloc(n + 1, fname, line);
- memcpy(mem->data, ptr, n);
- mem->data[n] = 0;
- return mem->data;
+ size_t len = strnlen(ptr, n);
+ char *str = md_malloc(len + 1, fname, line);
+
+ if (str) {
+ memcpy(str, ptr, len);
+ str[len] = '\0';
+ }
+
+ return str;
+}
+
+int __export md_asprintf(const char *fname, int line,
+ char **strp, const char *fmt, ...)
+{
+ va_list ap;
+ va_list aq;
+ int len;
+
+ va_start(ap, fmt);
+ va_copy(aq, ap);
+
+ len = vsnprintf(NULL, 0, fmt, ap);
+ if (len < 0)
+ goto err;
+
+ *strp = md_malloc(len + 1, fname, line);
+ if (*strp == NULL)
+ goto err;
+
+ len = vsnprintf(*strp, len + 1, fmt, aq);
+ if (len < 0)
+ goto err_strp;
+
+ va_end(aq);
+ va_end(ap);
+
+ return len;
+
+err_strp:
+ md_free(*strp, fname, line);
+err:
+ va_end(aq);
+ va_end(ap);
+ return -1;
}
static void siginfo(int num)