Created
April 13, 2013 08:43
-
-
Save crimsonwoods/5377628 to your computer and use it in GitHub Desktop.
A path to add debug information to mruby memory allocation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git build_config.rb build_config.rb | |
index 424f9d0..890173a 100644 | |
--- build_config.rb | |
+++ build_config.rb | |
@@ -59,7 +59,8 @@ MRuby::Build.new do |conf| | |
# C compiler settings | |
- # conf.cc do |cc| | |
+ conf.cc do |cc| | |
+ cc.defines << %w(MRB_DEBUG_MALLOC); | |
# cc.command = ENV['CC'] || 'gcc' | |
# cc.flags = [ENV['CFLAGS'] || %w()] | |
# cc.include_paths = ["#{root}/include"] | |
@@ -67,7 +68,7 @@ MRuby::Build.new do |conf| | |
# cc.option_include_path = '-I%s' | |
# cc.option_define = '-D%s' | |
# cc.compile_options = "%{flags} -MMD -o %{outfile} -c %{infile}" | |
- # end | |
+ end | |
# Linker settings | |
# conf.linker do |linker| | |
diff --git include/mruby.h include/mruby.h | |
index 1336d34..450dab0 100644 | |
--- include/mruby.h | |
+++ include/mruby.h | |
@@ -41,7 +41,11 @@ typedef int32_t mrb_aspec; | |
struct mrb_state; | |
+#if defined(MRB_DEBUG_MALLOC) | |
+typedef void* (*mrb_allocf) (struct mrb_state *, void*, size_t, void *, char const *, int, char const *); | |
+#else | |
typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud); | |
+#endif | |
#ifndef MRB_ARENA_SIZE | |
#define MRB_ARENA_SIZE 100 | |
@@ -207,11 +211,22 @@ mrb_sym mrb_intern(mrb_state *mrb,const char *cstr) | |
return mrb_intern_cstr(mrb, cstr); | |
} | |
+#if defined(MRB_DEBUG_MALLOC) | |
+void *mrb_malloc_debug(mrb_state*, size_t, char const *, int, char const *); | |
+void *mrb_calloc_debug(mrb_state*, size_t, size_t, char const *, int, char const *); | |
+void *mrb_realloc_debug(mrb_state*, void*, size_t, char const *, int, char const *); | |
+void *mrb_free_debug(mrb_state*, void*, char const *, int, char const *); | |
+#define mrb_malloc(mrb, len) mrb_malloc_debug((mrb), (len), __FILE__, __LINE__, __func__) | |
+#define mrb_calloc(mrb, nelem, len) mrb_calloc_debug((mrb), (nelem), (len), __FILE__, __LINE__, __func__) | |
+#define mrb_realloc(mrb, p, len) mrb_realloc_debug((mrb), (p), (len), __FILE__, __LINE__, __func__) | |
+#define mrb_free(mrb, p) mrb_free_debug((mrb), (p), __FILE__, __LINE__, __func__) | |
+#else | |
void *mrb_malloc(mrb_state*, size_t); | |
void *mrb_calloc(mrb_state*, size_t, size_t); | |
void *mrb_realloc(mrb_state*, void*, size_t); | |
-struct RBasic *mrb_obj_alloc(mrb_state*, enum mrb_vtype, struct RClass*); | |
void *mrb_free(mrb_state*, void*); | |
+#endif | |
+struct RBasic *mrb_obj_alloc(mrb_state*, enum mrb_vtype, struct RClass*); | |
mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len); | |
mrb_value mrb_str_new_cstr(mrb_state*, const char*); | |
diff --git src/gc.c src/gc.c | |
index 07bc23b..1a3aacb 100644 | |
--- src/gc.c | |
+++ src/gc.c | |
@@ -146,16 +146,29 @@ gettimeofday_time(void) | |
#define GC_STEP_SIZE 1024 | |
+#if defined(MRB_DEBUG_MALLOC) | |
+void* | |
+mrb_realloc_debug(mrb_state *mrb, void *p, size_t len, char const *file, int line, char const *func) | |
+#else | |
void* | |
mrb_realloc(mrb_state *mrb, void *p, size_t len) | |
+#endif | |
{ | |
void *p2; | |
+#if defined(MRB_DEBUG_MALLOC) | |
+ p2 = (mrb->allocf)(mrb, p, len, mrb->ud, file ,line, func); | |
+#else | |
p2 = (mrb->allocf)(mrb, p, len, mrb->ud); | |
+#endif | |
if (!p2 && len > 0 && mrb->heaps) { | |
mrb_garbage_collect(mrb); | |
+#if defined(MRB_DEBUG_MALLOC) | |
+ p2 = (mrb->allocf)(mrb, p, len, mrb->ud, file, line, func); | |
+#else | |
p2 = (mrb->allocf)(mrb, p, len, mrb->ud); | |
+#endif | |
} | |
if (!p2 && len) { | |
@@ -174,21 +187,38 @@ mrb_realloc(mrb_state *mrb, void *p, size_t len) | |
return p2; | |
} | |
+#if defined(MRB_DEBUG_MALLOC) | |
+void* | |
+mrb_malloc_debug(mrb_state *mrb, size_t len, char const *file, int line, char const *func) | |
+{ | |
+ return mrb_realloc_debug(mrb, 0, len, file, line, func); | |
+} | |
+#else | |
void* | |
mrb_malloc(mrb_state *mrb, size_t len) | |
{ | |
return mrb_realloc(mrb, 0, len); | |
} | |
+#endif | |
+#if defined(MRB_DEBUG_MALLOC) | |
+void* | |
+mrb_calloc_debug(mrb_state *mrb, size_t nelem, size_t len, char const *file, int line, char const *func) | |
+#else | |
void* | |
mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) | |
+#endif | |
{ | |
void *p = NULL; | |
size_t size; | |
if (nelem <= SIZE_MAX / len) { | |
size = nelem * len; | |
+#if defined(MRB_DEBUG_MALLOC) | |
+ p = mrb_realloc_debug(mrb, 0, size, file, line, func); | |
+#else | |
p = mrb_realloc(mrb, 0, size); | |
+#endif | |
if (p && size > 0) | |
memset(p, 0, size); | |
@@ -197,11 +227,19 @@ mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) | |
return p; | |
} | |
+#if defined(MRB_DEBUG_MALLOC) | |
+void* | |
+mrb_free_debug(mrb_state *mrb, void *p, char const *file, int line, char const *func) | |
+{ | |
+ return (mrb->allocf)(mrb, p, 0, mrb->ud, file, line, func); | |
+} | |
+#else | |
void* | |
mrb_free(mrb_state *mrb, void *p) | |
{ | |
return (mrb->allocf)(mrb, p, 0, mrb->ud); | |
} | |
+#endif | |
#ifndef MRB_HEAP_PAGE_SIZE | |
#define MRB_HEAP_PAGE_SIZE 1024 | |
diff --git src/state.c src/state.c | |
index adc7da0..0b6c755 100644 | |
--- src/state.c | |
+++ src/state.c | |
@@ -25,7 +25,11 @@ mrb_state* | |
mrb_open_allocf(mrb_allocf f, void *ud) | |
{ | |
static const mrb_state mrb_state_zero = { 0 }; | |
+#if defined(MRB_DEBUG_MALLOC) | |
+ mrb_state *mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud, __FILE__, __LINE__, __func__); | |
+#else | |
mrb_state *mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud); | |
+#endif | |
if (mrb == NULL) return NULL; | |
*mrb = mrb_state_zero; | |
@@ -38,6 +42,40 @@ mrb_open_allocf(mrb_allocf f, void *ud) | |
return mrb; | |
} | |
+#if defined(MRB_DEBUG_MALLOC) | |
+static char const * | |
+filename(char const *path) | |
+{ | |
+ size_t const len = strlen(path); | |
+ size_t i; | |
+ for (i = len - 1; i > 0; --i) { | |
+ if (path[i] == '/' || path[i] == '\\') { | |
+ return &path[i+1]; | |
+ } | |
+ } | |
+ return path; | |
+} | |
+static void* | |
+allocf(mrb_state *mrb, void *p, size_t size, void *ud, char const *file, int line, char const *func) | |
+{ | |
+ if (size == 0) { | |
+ fprintf(stderr, "FREE : %10p %15s %4d (%s)\n", p, filename(file), line, func); | |
+ free(p); | |
+ return NULL; | |
+ } | |
+ else { | |
+ void *new_ptr = realloc(p, size); | |
+ if (new_ptr) { | |
+ if (NULL == p) { | |
+ fprintf(stderr, "ALLOCATE: %10p %8lu %15s %4d (%s)\n", new_ptr, size, filename(file), line, func); | |
+ } else { | |
+ fprintf(stderr, "REALLOC : %10p %8lu %15s %4d (%s)\n", new_ptr, size, filename(file), line, func); | |
+ } | |
+ } | |
+ return new_ptr; | |
+ } | |
+} | |
+#else | |
static void* | |
allocf(mrb_state *mrb, void *p, size_t size, void *ud) | |
{ | |
@@ -49,6 +87,7 @@ allocf(mrb_state *mrb, void *p, size_t size, void *ud) | |
return realloc(p, size); | |
} | |
} | |
+#endif | |
struct alloca_header { | |
struct alloca_header *next; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment