Skip to content

Instantly share code, notes, and snippets.

@crimsonwoods
Created April 13, 2013 08:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crimsonwoods/5377628 to your computer and use it in GitHub Desktop.
Save crimsonwoods/5377628 to your computer and use it in GitHub Desktop.
A path to add debug information to mruby memory allocation.
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