quick & dirty leak checker
This commit is contained in:
parent
ec2158386c
commit
0d840ab330
117
stb_leakcheck.h
Normal file
117
stb_leakcheck.h
Normal file
@ -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
|
@ -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
|
||||||
|
@ -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
tests/test_vorbis.c
Normal file
18
tests/test_vorbis.c
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user