システム全体の標準的な malloc を (LD_PRELOAD を介して、またはインストールされている libc を単に置き換えるだけで) 、解放されたブロックで可能なすべてのものをゼロにするものに置き換えたいと思います。誰かが既存のソリューションを知っていますか?
ヒープの未使用部分にゼロを含めると、zram-config を介して圧縮する方がはるかに効果的です。CPU よりも RAM が必要なので、CPU 使用率の増加は問題になりません。
システム全体の標準的な malloc を (LD_PRELOAD を介して、またはインストールされている libc を単に置き換えるだけで) 、解放されたブロックで可能なすべてのものをゼロにするものに置き換えたいと思います。誰かが既存のソリューションを知っていますか?
ヒープの未使用部分にゼロを含めると、zram-config を介して圧縮する方がはるかに効果的です。CPU よりも RAM が必要なので、CPU 使用率の増加は問題になりません。
システムの C ライブラリを変更できます。非標準であるため、変更されたCライブラリがそのように正確にメモリ割り当てを行うとは思わない. しかし、変更は比較的簡単に聞こえます。C ライブラリの実装を見てください。free の実装を、単に free ではなく、free+memset を実行するラッパーに置き換えることができます。
同様の問題が発生した場合に備えて、以下は eglibc 2.17 のパッチです。
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1424,10 +1424,16 @@
#define first(b) ((b)->fd)
#define last(b) ((b)->bk)
+#define zero_sizes(P) { \
+ P->size = 0; \
+ P->prev_size = 0; \
+}
+
/* Take a chunk off a bin list */
#define unlink(P, BK, FD) { \
FD = P->fd; \
BK = P->bk; \
+ P->bk = 0; P->fd = 0; \
if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \
malloc_printerr (check_action, "corrupted double-linked list", P); \
else { \
@@ -1449,9 +1455,11 @@
} else { \
P->fd_nextsize->bk_nextsize = P->bk_nextsize; \
P->bk_nextsize->fd_nextsize = P->fd_nextsize; \
} \
+ P->fd_nextsize = 0; \
+ P->bk_nextsize = 0; \
} \
} \
}
/*
@@ -1878,8 +1886,10 @@
static int perturb_byte;
-#define alloc_perturb(p, n) memset (p, (perturb_byte ^ 0xff) & 0xff, n)
-#define free_perturb(p, n) memset (p, perturb_byte & 0xff, n)
+#define alloc_perturb(p, n) do {} while(0)
+#define free_perturb(p, n) memset (p, 0, n)
/* ------------------- Support for multiple arenas -------------------- */
@@ -3809,8 +3819,7 @@
}
}
- if (__builtin_expect (perturb_byte, 0))
- free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
+ free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
set_fastchunks(av);
unsigned int idx = fastbin_index(size);
@@ -3892,13 +3901,13 @@
goto errout;
}
- if (__builtin_expect (perturb_byte, 0))
- free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
+ free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
/* consolidate backward */
if (!prev_inuse(p)) {
prevsize = p->prev_size;
size += prevsize;
+ unlink_free(p);
p = chunk_at_offset(p, -((long) prevsize));
unlink(p, bck, fwd);
}
@@ -3910,6 +3921,7 @@
/* consolidate forward */
if (!nextinuse) {
unlink(nextchunk, bck, fwd);
+ zero_sizes(nextchunk);
size += nextsize;
} else
clear_inuse_bit_at_offset(nextchunk, 0);
@@ -4069,6 +4081,7 @@
if (!prev_inuse(p)) {
prevsize = p->prev_size;
size += prevsize;
+ zero_sizes(p);
p = chunk_at_offset(p, -((long) prevsize));
unlink(p, bck, fwd);
}
@@ -4079,6 +4092,7 @@
if (!nextinuse) {
size += nextsize;
unlink(nextchunk, bck, fwd);
+ zero_sizes(nextchunk);
} else
clear_inuse_bit_at_offset(nextchunk, 0);
独自のfree_zero
関数を作成してみませんか?
void free_zero(void *p, size_t n)
{
volatile unsigned char *zp = p;
if (!p) return;
while (n--)
{
*zp++ = 0;
}
free(p);
}