Kouhei Sutou
kou****@cozmi*****
2008年 9月 25日 (木) 22:36:39 JST
須藤です。
現在はビルド時に--enable-fmallocオプションを指定することで
fail mallocの機能を有効がなり、sen_malloc()の代わりに
sen_fail_malloc()が使用されるようになります。もし、実行
時に動的にsen_malloc()の代わりの関数を変更できるとテストが書
きやすくなる気がしています。(特定の処理の間だけfailするよう
にするとかが簡単にできそう)
実装のイメージはパッチの通りなのですが、これに加えて
sen_ctx_set_malloc_func()のようなアクセサがあるとよいのかと
思っています。
速度の事もあるので、ビルド時のオプションで有効・無効を切り替
えるようにした方がよいのもしれません。
(ほんとはベンチマークをとってから言った方がよいのですが。。。)
どうでしょうか?
-------------- next part --------------
Index: lib/ctx.c
===================================================================
--- lib/ctx.c (リビジョン 1138)
+++ lib/ctx.c (作業コピー)
@@ -207,6 +207,17 @@
ctx->impl->encoding = ctx->encoding;
ctx->impl->lifoseg = -1;
ctx->impl->currseg = -1;
+#ifdef USE_FAIL_MALLOC
+ ctx->impl->malloc_func = sen_malloc_fail;
+ ctx->impl->calloc_func = sen_calloc_fail;
+ ctx->impl->realloc_func = sen_realloc_fail;
+ ctx->impl->strdup_func = sen_strdup_fail;
+#else
+ ctx->impl->malloc_func = sen_malloc_default;
+ ctx->impl->calloc_func = sen_calloc_default;
+ ctx->impl->realloc_func = sen_realloc_default;
+ ctx->impl->strdup_func = sen_strdup_default;
+#endif
ctx->impl->db = NULL;
ctx->impl->phs = NIL;
ctx->impl->code = NIL;
@@ -880,8 +891,48 @@
}
void *
-sen_malloc(sen_ctx *ctx, size_t size, const char* file, int line)
+sen_malloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
{
+ if (ctx && ctx->impl && ctx->impl->malloc_func) {
+ return ctx->impl->malloc_func(ctx, size, file, line, func);
+ } else {
+ return sen_malloc_default(ctx, size, file, line, func);
+ }
+}
+
+void *
+sen_calloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
+{
+ if (ctx && ctx->impl && ctx->impl->calloc_func) {
+ return ctx->impl->calloc_func(ctx, size, file, line, func);
+ } else {
+ return sen_calloc_default(ctx, size, file, line, func);
+ }
+}
+
+void *
+sen_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func)
+{
+ if (ctx && ctx->impl && ctx->impl->realloc_func) {
+ return ctx->impl->realloc_func(ctx, ptr, size, file, line, func);
+ } else {
+ return sen_realloc_default(ctx, ptr, size, file, line, func);
+ }
+}
+
+char *
+sen_strdup(sen_ctx *ctx, const char *string, const char* file, int line, const char *func)
+{
+ if (ctx && ctx->impl && ctx->impl->strdup_func) {
+ return ctx->impl->strdup_func(ctx, string, file, line, func);
+ } else {
+ return sen_strdup_default(ctx, string, file, line, func);
+ }
+}
+
+void *
+sen_malloc_default(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
+{
void *res = malloc(size);
if (res) {
alloc_count++;
@@ -895,7 +946,7 @@
}
void *
-sen_calloc(sen_ctx *ctx, size_t size, const char* file, int line)
+sen_calloc_default(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
{
void *res = calloc(size, 1);
if (res) {
@@ -921,7 +972,7 @@
}
void *
-sen_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line)
+sen_realloc_default(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func)
{
void *res;
if (!size) {
@@ -953,7 +1004,7 @@
}
char *
-sen_strdup(sen_ctx *ctx, const char *s, const char* file, int line)
+sen_strdup_default(sen_ctx *ctx, const char *s, const char* file, int line, const char *func)
{
char *res = strdup(s);
if (res) {
@@ -968,7 +1019,7 @@
}
#ifdef USE_FAIL_MALLOC
-int
+static int
fail_malloc_check(size_t size, const char *file, int line, const char *func)
{
if ((sen_fmalloc_file && strcmp(file, sen_fmalloc_file)) ||
@@ -983,10 +1034,10 @@
}
void *
-sen_fail_malloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
+sen_malloc_fail(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
{
if (fail_malloc_check(size, file, line, func)) {
- return sen_malloc(ctx, size, file, line);
+ return sen_malloc_default(ctx, size, file, line);
} else {
sen_index_expire();
MERR("fail_malloc (%d) (%s:%d@%s) <%d>", size, file, line, func, alloc_count);
@@ -995,10 +1046,10 @@
}
void *
-sen_fail_calloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
+sen_calloc_fail(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
{
if (fail_malloc_check(size, file, line, func)) {
- return sen_calloc(ctx, size, file, line);
+ return sen_calloc_default(ctx, size, file, line);
} else {
sen_index_expire();
MERR("fail_calloc (%d) (%s:%d@%s) <%d>", size, file, line, func, alloc_count);
@@ -1007,24 +1058,23 @@
}
void *
-sen_fail_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line,
+sen_realloc_fail(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line,
const char *func)
{
if (fail_malloc_check(size, file, line, func)) {
- return sen_realloc(ctx, ptr, size, file, line);
+ return sen_realloc_default(ctx, ptr, size, file, line);
} else {
sen_index_expire();
- MERR("fail_realloc (%p,%zu) (%s:%d@%s) <%d>", ptr, size
- , file, line, func, alloc_count);
+ MERR("fail_realloc (%p,%zu) (%s:%d@%s) <%d>", ptr, size, file, line, func, alloc_count);
return NULL;
}
}
char *
-sen_fail_strdup(sen_ctx *ctx, const char *s, const char* file, int line, const char *func)
+sen_strdup_fail(sen_ctx *ctx, const char *s, const char* file, int line, const char *func)
{
if (fail_malloc_check(strlen(s), file, line, func)) {
- return sen_strdup(ctx, s, file, line);
+ return sen_strdup_default(ctx, s, file, line);
} else {
sen_index_expire();
MERR("fail_strdup(%p) (%s:%d@%s) <%d>", s, file, line, func, alloc_count);
Index: lib/ctx.h
===================================================================
--- lib/ctx.h (リビジョン 1138)
+++ lib/ctx.h (作業コピー)
@@ -99,25 +99,14 @@
#define GMERR(...) ERRSET(&sen_gctx, SEN_ALERT, sen_memory_exhausted, __VA_ARGS__)
#define GSERR(str) GERR(sen_other_error, "syscall error '%s' (%s)", str, strerror(errno))
-#ifdef USE_FAIL_MALLOC
-#define SEN_MALLOC(s) sen_fail_malloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define SEN_CALLOC(s) sen_fail_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define SEN_REALLOC(p,s) sen_fail_realloc(ctx,p,s,__FILE__,__LINE__,__FUNCTION__)
-#define SEN_STRDUP(s) sen_fail_strdup(ctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define SEN_GMALLOC(s) sen_fail_malloc(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define SEN_GCALLOC(s) sen_fail_calloc(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define SEN_GREALLOC(p,s) sen_fail_realloc(&sen_gctx,p,s,__FILE__,__LINE__,__FUNCTION__)
-#define SEN_GSTRDUP(s) sen_fail_strdup(&sen_gctx,s,__FILE__,__LINE__,__FUNTION__)
-#else /* USE_FAIL_MALLOC */
-#define SEN_MALLOC(s) sen_malloc(ctx,s,__FILE__,__LINE__)
-#define SEN_CALLOC(s) sen_calloc(ctx,s,__FILE__,__LINE__)
-#define SEN_REALLOC(p,s) sen_realloc(ctx,p,s,__FILE__,__LINE__)
-#define SEN_STRDUP(s) sen_strdup(ctx,s,__FILE__,__LINE__)
-#define SEN_GMALLOC(s) sen_malloc(&sen_gctx,s,__FILE__,__LINE__)
-#define SEN_GCALLOC(s) sen_calloc(&sen_gctx,s,__FILE__,__LINE__)
-#define SEN_GREALLOC(p,s) sen_realloc(&sen_gctx,p,s,__FILE__,__LINE__)
-#define SEN_GSTRDUP(s) sen_strdup(&sen_gctx,s,__FILE__,__LINE__)
-#endif /* USE_FAIL_MALLOC */
+#define SEN_MALLOC(s) sen_malloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define SEN_CALLOC(s) sen_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define SEN_REALLOC(p,s) sen_realloc(ctx,p,s,__FILE__,__LINE__,__FUNCTION__)
+#define SEN_STRDUP(s) sen_strdup(ctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define SEN_GMALLOC(s) sen_malloc(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define SEN_GCALLOC(s) sen_calloc(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define SEN_GREALLOC(p,s) sen_realloc(&sen_gctx,p,s,__FILE__,__LINE__,__FUNCTION__)
+#define SEN_GSTRDUP(s) sen_strdup(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
#define SEN_FREE(p) sen_free(ctx,p,__FILE__,__LINE__)
#define SEN_MALLOCN(t,n) ((t *)(SEN_MALLOC(sizeof(t) * (n))))
#define SEN_GFREE(p) sen_free(&sen_gctx,p,__FILE__,__LINE__)
@@ -143,17 +132,32 @@
void sen_ctx_free_lifo(sen_ctx *ctx, void *ptr,
const char* file, int line, const char *func);
+typedef void *(*sen_malloc_func) (sen_ctx *ctx, size_t size,
+ const char *file, int line, const char *func);
+typedef void *(*sen_calloc_func) (sen_ctx *ctx, size_t size,
+ const char *file, int line, const char *func);
+typedef void *(*sen_realloc_func) (sen_ctx *ctx, void *ptr, size_t size,
+ const char *file, int line, const char *func);
+typedef void *(*sen_strdup_func) (sen_ctx *ctx, const char *string,
+ const char *file, int line, const char *func);
+
+void *sen_malloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
+void *sen_calloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
+void *sen_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
+char *sen_strdup(sen_ctx *ctx, const char *s, const char* file, int line, const char *func);
+
+void *sen_malloc_default(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
+void *sen_calloc_default(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
+void *sen_realloc_default(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
+char *sen_strdup_default(sen_ctx *ctx, const char *s, const char* file, int line, const char *func);
+
#ifdef USE_FAIL_MALLOC
-int fail_malloc_check(size_t size, const char *file, int line, const char *func);
-void *sen_fail_malloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
-void *sen_fail_calloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
-void *sen_fail_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
-char *sen_fail_strdup(sen_ctx *ctx, const char *s, const char* file, int line, const char *func);
-#endif /* USE_FAIL_MALLOC */
-void *sen_malloc(sen_ctx *ctx, size_t size, const char* file, int line);
-void *sen_calloc(sen_ctx *ctx, size_t size, const char* file, int line);
-void *sen_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line);
-char *sen_strdup(sen_ctx *ctx, const char *s, const char* file, int line);
+void *sen_malloc_fail(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
+void *sen_calloc_fail(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
+void *sen_realloc_fail(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
+char *sen_strdup_fail(sen_ctx *ctx, const char *s, const char* file, int line, const char *func);
+#endif
+
void sen_free(sen_ctx *ctx, void *ptr, const char* file, int line);
void sen_assert(int cond, const char* file, int line, const char* func);
@@ -327,6 +331,12 @@
sen_io_mapinfo mi;
sen_io_mapinfo *segs;
+ /* memory allocation portion */
+ sen_malloc_func malloc_func;
+ sen_calloc_func calloc_func;
+ sen_realloc_func realloc_func;
+ sen_strdup_func strdup_func;
+
/* ql portion */
uint32_t ncells;
uint32_t seqno;