Bladeren bron

quick & dirty leak checker

Sean Barrett 10 jaren geleden
bovenliggende
commit
0d840ab330
4 gewijzigde bestanden met toevoegingen van 150 en 0 verwijderingen
  1. 117 0
      stb_leakcheck.h
  2. 7 0
      stb_vorbis.c
  3. 8 0
      tests/stb.dsp
  4. 18 0
      tests/test_vorbis.c

+ 117 - 0
stb_leakcheck.h

@@ -0,0 +1,117 @@
+// stb_leakcheck.h - v0.1 - quick & dirty malloc leak-checking - public domain
+
+#ifdef STB_LEAKCHECK_IMPLEMENTATION
+#undef STB_LEAKCHECK_IMPLEMENTATION // don't implenment more than once
+
+// if we've already included leakcheck before, undefine the macros
+#ifdef malloc
+#undef malloc
+#undef free
+#undef realloc
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+typedef struct malloc_info stb_leakcheck_malloc_info;
+
+struct malloc_info
+{
+   char *file;
+   int line;
+   size_t size;
+   stb_leakcheck_malloc_info *next,*prev;
+};
+
+static stb_leakcheck_malloc_info *mi_head;
+
+void *stb_leakcheck_malloc(size_t sz, char *file, int line)
+{
+   stb_leakcheck_malloc_info *mi = malloc(sz + sizeof(*mi));
+   if (mi == NULL) return mi;
+   mi->file = file;
+   mi->line = line;
+   mi->next = mi_head;
+   if (mi_head)
+      mi->next->prev = mi;
+   mi->prev = NULL;
+   mi->size = (int) sz;
+   mi_head = mi;
+   return mi+1;
+}
+
+void stb_leakcheck_free(void *ptr)
+{
+   if (ptr != NULL) {
+      stb_leakcheck_malloc_info *mi = (stb_leakcheck_malloc_info *) ptr - 1;
+      mi->size = ~mi->size;
+      #ifndef STB_LEAKCHECK_SHOWALL
+      if (mi->prev == NULL) {
+         assert(mi_head == mi);
+         mi_head = mi->next;
+      } else
+         mi->prev->next = mi->next;
+      if (mi->next)
+         mi->next->prev = mi->prev;
+      #endif
+   }
+}
+
+void *stb_leakcheck_realloc(void *ptr, size_t sz, char *file, int line)
+{
+   if (ptr == NULL) {
+      return stb_leakcheck_malloc(sz, file, line);
+   } else if (sz == 0) {
+      stb_leakcheck_free(ptr);
+      return NULL;
+   } else {
+      stb_leakcheck_malloc_info *mi = (stb_leakcheck_malloc_info *) ptr - 1;
+      if (sz <= mi->size)
+         return ptr;
+      else {
+         #ifdef STB_LEAKCHECK_REALLOC_PRESERVE_MALLOC_FILELINE
+         void *q = stb_leakcheck_malloc(sz, mi->file, mi->line);
+         #else
+         void *q = stb_leakcheck_malloc(sz, file, line);
+         #endif
+         if (q) {
+            memcpy(q, ptr, mi->size);
+            stb_leakcheck_free(ptr);
+         }
+         return q;
+      }
+   }
+}
+
+void stb_leakcheck_dumpmem(void)
+{
+   stb_leakcheck_malloc_info *mi = mi_head;
+   while (mi) {
+      if ((ptrdiff_t) mi->size >= 0)
+         printf("LEAKED: %s (%4d): %8z bytes at %p\n", mi->file, mi->line, mi->size, mi+1);
+      mi = mi->next;
+   }
+   #ifdef STB_LEAKCHECK_SHOWALL
+   mi = mi_head;
+   while (mi) {
+      if ((ptrdiff_t) mi->size < 0)
+         printf("FREED : %s (%4d): %8z bytes at %p\n", mi->file, mi->line, ~mi->size, mi+1);
+      mi = mi->next;
+   }
+   #endif
+}
+#endif // STB_LEAKCHECK_IMPLEMENTATION
+
+#ifndef INCLUDE_STB_LEAKCHECK_H
+#define INCLUDE_STB_LEAKCHECK_H
+
+#define malloc(sz)    stb_leakcheck_malloc(sz, __FILE__, __LINE__)
+#define free(p)       stb_leakcheck_free(p)
+#define realloc(p,sz) stb_leakcheck_realloc(p,sz, __FILE__, __LINE__)
+
+extern void * stb_leakcheck_malloc(size_t sz, char *file, int line);
+extern void * stb_leakcheck_realloc(void *ptr, size_t sz, char *file, int line);
+extern void   stb_leakcheck_free(void *ptr);
+extern void   stb_leakcheck_dumpmem(void);
+
+#endif // INCLUDE_STB_LEAKCHECK_H

+ 7 - 0
stb_vorbis.c

@@ -327,6 +327,8 @@ extern int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buf
 
 
 #endif
 #endif
 
 
+extern void stb_vorbis_free(void *p);
+
 ////////   ERROR CODES
 ////////   ERROR CODES
 
 
 enum STBVorbisError
 enum STBVorbisError
@@ -592,6 +594,11 @@ typedef float codetype;
 typedef uint16 codetype;
 typedef uint16 codetype;
 #endif
 #endif
 
 
+//#define STB_LEAKCHECK_IMPLEMENTATION
+//#define STB_LEAKCHECK_SHOWALL
+//#include "stb_leakcheck.h"
+//void stb_vorbis_dumpmem(void) { stb_leakcheck_dumpmem(); }
+
 // @NOTE
 // @NOTE
 //
 //
 // Some arrays below are tagged "//varies", which means it's actually
 // Some arrays below are tagged "//varies", which means it's actually

+ 8 - 0
tests/stb.dsp

@@ -122,6 +122,10 @@ SOURCE=..\stb_image_write.h
 # End Source File
 # End Source File
 # Begin Source File
 # Begin Source File
 
 
+SOURCE=..\stb_leakcheck.h
+# End Source File
+# Begin Source File
+
 SOURCE=..\stb_perlin.h
 SOURCE=..\stb_perlin.h
 # End Source File
 # End Source File
 # Begin Source File
 # Begin Source File
@@ -162,6 +166,10 @@ SOURCE=.\test_truetype.c
 # End Source File
 # End Source File
 # Begin Source File
 # Begin Source File
 
 
+SOURCE=.\test_vorbis.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\textedit_sample.c
 SOURCE=.\textedit_sample.c
 # End Source File
 # End Source File
 # End Target
 # End Target

+ 18 - 0
tests/test_vorbis.c

@@ -0,0 +1,18 @@
+#define STB_VORBIS_HEADER_ONLY
+#include "stb_vorbis.c"
+#include "stb.h"
+
+extern void stb_vorbis_dumpmem(void);
+
+#ifdef VORBIS_TEST
+int main(int argc, char **argv)
+{
+   size_t memlen;
+   unsigned char *mem = stb_fileu("c:/x/01.ogg", &memlen);
+   int chan, samplerate;
+   short *output;
+   int samples = stb_vorbis_decode_memory(mem, memlen, &chan, &samplerate, &output);
+   stb_vorbis_dumpmem();
+   return 0;
+}
+#endif