Tcache Theory Analysis

Tcache

tcache_entry

Ubuntu 17.04 에서 glibc 2.6 버전이 릴리즈 되었는데 tcache_entrytcache_perthread_struct라는 구조체가 새로 추가되었다.

특징

  • Single linked list(단일 연결 구조)를 이루고 있다.
  • Consolidate를 하지 않는다.
  • LIFO 구조를 가지고 있다.
  • Pointer가 오직 next chunk만 포함하고 있다.
  • 기본적으로 Chunk Size는 24 ~ 1032 bytes 이다. (32bit : 12 ~ 516 bytes)
1
2
3
/* This is another arbitrary limit, which tunables can change.  Each
tcache bin will hold at most this number of chunks. */
# define TCACHE_FILL_COUNT 7

tcache bin 한 개당 기본적으로 7개의 Chunk를 가질 수 있다.

1
2
3
#if USE_TCACHE
/* We want 64 entries. This is an arbitrary limit, which tunables can reduce. */
# define TCACHE_MAX_BINS 64
1
2
3
4
5
6
7
8
9
10
11
12
13
tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
assert (tc_idx < TCACHE_MAX_BINS);

/* Mark this chunk as "in the tcache" so the test in _int_free will
detect a double free. */
e->key = tcache;

e->next = tcache->entries[tc_idx];
tcache->entries[tc_idx] = e;
++(tcache->counts[tc_idx]);
}
[tcache_put]
1
2
3
4
5
6
7
8
9
10
11
12
13
/* Caller must ensure that we know tc_idx is valid and there's
available chunks to remove. */
static __always_inline void *
tcache_get (size_t tc_idx)
{
tcache_entry *e = tcache->entries[tc_idx];
assert (tc_idx < TCACHE_MAX_BINS);
assert (tcache->counts[tc_idx] > 0);
tcache->entries[tc_idx] = e->next;
--(tcache->counts[tc_idx]);
e->key = NULL;
return (void *) e;
}
[tcache_get]

tcache_puttcache_get 함수는 _int_free 와 __libc_malloc 함수가 시작할때 호출된다.
tacace_get은 할당된 크기의 영역이 요청될때 0x408보다 작으면 호출된다.


[free]
[한번 더 free]
entry와 count가 보이는 것을 알 수 있다.

공유하기