]> Chaos Git - corbenik/corbenik.git/commitdiff
Allocation debugging
authorchaoskagami <chaos.kagami@gmail.com>
Sun, 21 Aug 2016 16:55:11 +0000 (12:55 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Sun, 21 Aug 2016 16:55:11 +0000 (12:55 -0400)
common.mk
include/input.h
include/std/allocator.h
source/firm/firm.c
source/input.c
source/interpreter.c
source/patch/reboot.c
source/patcher.c
source/std/allocator.c
source/std/fs.c

index 326bcab14c0add03ed3bfa916a6220d693206286..51ab1d1950dfbcd6cdf806f713eed17f5365d08a 100644 (file)
--- a/common.mk
+++ b/common.mk
@@ -14,7 +14,7 @@ AM_CFLAGS= -std=gnu11 -Os -g -ffast-math \
        -Wundef -Wno-unused -Werror -Wno-error=cast-align -Wno-error=strict-overflow -Wno-error=pedantic \
        $(THUMBFLAGS) $(SIZE_OPTIMIZATION) $(INCPATHS) $(C9FLAGS) \
        -fno-builtin -std=gnu11 -DREVISION=\"$(REVISION)\" \
-       -DFW_NAME=\"corbenik\" $(PATHARGS)
+       -DFW_NAME=\"corbenik\" $(PATHARGS) -DMALLOC_DEBUG=1
 
 
 AM_LDFLAGS=-Wl,--use-blx,--pic-veneer,-q -nostdlib -nodefaultlibs -Wl,-z,defs -lgcc \
index 3f94a17a23cd8d456e2232face7262692ed69694..be263f39b5265aeb4711b619a4ed0eea80b9de6f 100644 (file)
@@ -10,4 +10,9 @@
  */
 uint32_t wait_key(_UNUSED int sleep);
 
+/* Displays a prompt on the bottom screen if the relevant option is enabled and waits on input
+ * to continue.
+ */
+void wait();
+
 #endif
index 860506756f7f70d395571d5fd1cc1005b6cec57f..1f49a4a6fd374f2fb8f7fe71437505af3ed46162 100644 (file)
  */
 void *sbrk(size_t bytes);
 
+#ifdef MALLOC_DEBUG
+
+/* Prints stats for allocation to stderr.
+ */
+void print_alloc_stats();
+
+/* Allocate memory for use (debugging only, don't call)
+ *
+ * \param size Size in bytes to allocate.
+ * \param info Info to store about malloc
+ */
+void* malloc_chkd(size_t size, char* info);
+
+/* Free in-use memory allocated by malloc (debugging only, don't call)
+ *
+ * \param ptr Pointer to free.
+ * \param info Info to store about free
+ */
+void  free_chkd(void* ptr, char* info);
+
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+#define malloc(x) malloc_chkd( x , __FILE__ ":" TOSTRING(__LINE__) )
+#define free(x)   free_chkd( x , __FILE__ ":" TOSTRING(__LINE__) )
+
+#else
+
 /* Allocate memory for use.
  *
  * \param size Size in bytes to allocate.
@@ -25,3 +52,5 @@ void *malloc   (size_t size);
 void  free     (void* ptr);
 
 #endif
+
+#endif
index 6a6e9b2d7ee06b9f047c191c843660f22dc2516b..c132cb8c43d11d90bd5b6c6390d0d3ae7a4afe75 100644 (file)
@@ -409,8 +409,6 @@ load_firm(firm_h *dest, char *path, char *path_firmkey, char *path_cetk, uint32_
     return 0;
 }
 
-extern void wait();
-
 __attribute__ ((noreturn))
 void
 boot_firm()
@@ -439,6 +437,14 @@ boot_firm()
         fprintf(stderr, "Updated keyX keyslots.\n");
     }
 
+#ifdef MALLOC_DEBUG
+    print_alloc_stats();
+    wait();
+#endif
+
+    // Beyond this point, using malloc() memory is unsafe, since we're trashing memory possibly.
+    // free() is also irrelevant from here on.
+
     for (firm_section_h *section = firm_loc->section; section < firm_loc->section + 4 && section->address != 0; section++) {
         memcpy((void *)section->address, (void *)((uint8_t*)firm_loc + section->offset), section->size);
     }
index 12978aa558770211df518d3b86ad5a52e7d1af53..9d940035528ca442bf3aec90e04a5ae7f796c6a8 100644 (file)
@@ -38,3 +38,15 @@ wait_key(_UNUSED int sleep)
     return ret;
 }
 
+extern int doing_autoboot;
+
+void
+wait()
+{
+    if (config->options[OPTION_TRACE] && !doing_autoboot) {
+        fprintf(stderr, "[Waiting...]");
+        wait_key(0); // No delay on traces.
+    }
+    fprintf(stderr, "\r            \r");
+}
+
index f732ebf72437edf76b4343ae8bc5ba7ab7c7fd58..58c55d8eb0e422db3ef70d8f5ee46437cf502ec6 100644 (file)
@@ -56,7 +56,6 @@
       }
 #else
   #define log(a) fprintf(stderr, a)
-  int wait();
 #endif
 
 struct mode
index 96ebd6875c59d40d5dac4f91423a3ff6c15e1319..d50237f78bc7d5060cff8e59d2d264e25332e60f 100644 (file)
@@ -4,8 +4,6 @@
 #include <common.h>
 #include <ctr9/io.h>
 
-int wait();
-
 uint8_t*
 getProcess9(uint8_t *pos, uint32_t size, uint32_t *process9Size, uint32_t *process9MemAddr)
 {
index 8cdcfc5905362ee1e7e7a7b9cdb6c29806e0c7a0..d24256f7ec2be11b037e6e8f6d451178386afef9 100644 (file)
@@ -13,16 +13,6 @@ extern uint8_t *enable_list;
 
 extern struct options_s* patches;
 
-void
-wait()
-{
-    if (config->options[OPTION_TRACE] && !doing_autoboot) {
-        fprintf(stderr, "[Waiting...]");
-        wait_key(0); // No delay on traces.
-    }
-    fprintf(stderr, "            \r");
-}
-
 void list_patches_build(char *name, int desc_is_fname);
 
 void
index 02d4dec25c0f3b8e16acfb34142fb96be4d89ea1..b9489be057eb21686fc8ab557bb907d0de8ea216 100644 (file)
@@ -26,38 +26,104 @@ void* sbrk(size_t incr) {
 
 typedef struct free_block {
     size_t size;
+#ifdef MALLOC_DEBUG
+    char* info;
+#endif
     struct free_block* next;
 } free_block;
 
-static free_block free_block_list_head = { 0, 0 };
+static free_block free_block_list_head = {
+    0,
+#ifdef MALLOC_DEBUG
+    NULL,
+#endif
+    0
+};
 
 // static const size_t overhead = sizeof(size_t);
 
 static const size_t align_to = 16;
 
+#ifdef MALLOC_DEBUG
+static size_t alloc_count      = 0;
+static size_t free_count       = 0;
+static size_t allocated_memory = 0;
+#endif
+
+#ifdef MALLOC_DEBUG
+void* malloc_chkd(size_t size, char* info) {
+#else
 void* malloc(size_t size) {
-    size = (size + sizeof(free_block) + (align_to - 1)) & ~ (align_to - 1);
+#endif
+    size_t bsize = (size + sizeof(free_block) + (align_to - 1)) & ~ (align_to - 1);
+
     free_block* block = free_block_list_head.next;
     free_block** head = &(free_block_list_head.next);
+
     while (block != 0) {
-        if (block->size >= size) {
+        if (block->size >= bsize) {
             *head = block->next;
+
+#ifdef MALLOC_DEBUG
+            block->info = info;
+
+            ++alloc_count;
+            allocated_memory += block->size;
+#endif
+
             return ((char*)block) + sizeof(free_block);
         }
         head = &(block->next);
         block = block->next;
     }
 
-    block = (free_block*)sbrk(size);
-    block->size = size;
+    block = (free_block*)sbrk(bsize);
+    block->size = bsize;
+
+#ifdef MALLOC_DEBUG
+    block->info = info;
+
+    ++alloc_count;
+    allocated_memory += bsize;
+#endif
 
     return ((char*)block) + sizeof(free_block);
 }
 
+void* malloc_zero(size_t size) {
+    void* ret = malloc(size);
+
+    if (ret)
+        memset(ret, 0, size);
+
+    return ret;
+}
+
+#ifdef MALLOC_DEBUG
+void free_chkd(void* ptr, char* info) {
+#else
 void free(void* ptr) {
+#endif
     if (ptr == NULL) return;
 
     free_block* block = (free_block*)(((char*)ptr) - sizeof(free_block ));
+
+#ifdef MALLOC_DEBUG
+    ++free_count;
+    if (allocated_memory < block->size) {
+        fprintf(stderr, "%s: Invalid free detected.\n"
+                        "  Allocated at: %s\n",
+                        info, block->info);
+    }
+    allocated_memory -= block->size;
+#endif
+
     block->next = free_block_list_head.next;
     free_block_list_head.next = block;
 }
+
+#ifdef MALLOC_DEBUG
+void print_alloc_stats() {
+       fprintf(stderr, "[A] %u [F] %u [M] %u [B] %lu\n", alloc_count, free_count, allocated_memory, (uint32_t)heap_end - (uint32_t)&__end__);
+}
+#endif
index 7bc4dd8f3db39055a9584de9074b7550bf9c9265..610263cd1d1be6711e947337729e0486d5b09a4b 100644 (file)
@@ -104,7 +104,7 @@ fopen(const char *filename, const char *mode)
     if (f_open(&(fp->handle), filename, fp->mode)) {
         free(fp);
         return NULL;
-      }
+    }
 
     fp->is_open = 1;
 
@@ -114,7 +114,7 @@ fopen(const char *filename, const char *mode)
 void
 fclose(FILE *fp)
 {
-    if (!fp->is_open)
+    if (fp == NULL || !fp->is_open)
         return;
 
     f_close(&(fp->handle));
@@ -127,7 +127,7 @@ fclose(FILE *fp)
 void
 fseek(FILE *fp, int64_t offset, int whence)
 {
-    if (!fp->is_open)
+    if (fp == NULL || !fp->is_open)
         return;
 
     uint32_t fixed_offset;
@@ -151,7 +151,7 @@ fseek(FILE *fp, int64_t offset, int whence)
 size_t
 ftell(FILE *fp)
 {
-    if (!fp->is_open)
+    if (fp == NULL || !fp->is_open)
         return 0;
 
     return f_tell(&(fp->handle));
@@ -160,7 +160,7 @@ ftell(FILE *fp)
 int
 feof(FILE *fp)
 {
-    if (!fp->is_open)
+    if (fp == NULL || !fp->is_open)
         return 0;
 
     return f_eof(&(fp->handle));
@@ -169,7 +169,7 @@ feof(FILE *fp)
 size_t
 fsize(FILE *fp)
 {
-    if (!fp->is_open)
+    if (fp == NULL || !fp->is_open)
         return 0;
 
     return f_size(&(fp->handle));
@@ -178,7 +178,7 @@ fsize(FILE *fp)
 size_t
 fwrite(const void *buffer, size_t elementSize, size_t elementCnt, FILE *fp)
 {
-    if (!fp->is_open)
+    if (fp == NULL || !fp->is_open)
         return 0;
 
     UINT br;
@@ -209,9 +209,14 @@ write_file(void *data, char *path, size_t size)
 {
     FILE *temp = fopen(path, "w");
 
-    if (!temp || !temp->is_open)
+    if (!temp)
         return 0;
 
+    if (!temp->is_open) {
+        fclose(temp);
+        return 0;
+    }
+
     size_t wrote = fwrite(data, 1, size, temp);
 
     fclose(temp);
@@ -224,9 +229,14 @@ read_file(void *data, char *path, size_t size)
 {
     FILE *temp = fopen(path, "r");
 
-    if (!temp || !temp->is_open)
+    if (!temp)
         return 0;
 
+    if (!temp->is_open) {
+        fclose(temp);
+        return 0;
+    }
+
     size_t read = fread(data, 1, size, temp);
 
     fclose(temp);