크래시 유틸리티 프로그램을 실행할 때 페이지 디스크립터가 위치한 vmemmap의 범위는
'ffffffbc00000000 - ffffffbdffffffff'와 같습니다.
crash64: kernel image: ffffff96ff280000 - ffffff9702265000
crash64: vmemmap: ffffffbc00000000 - ffffffbdffffffff
kmalloc 슬랩 캐시를 확인해보겠습니다.
crash64> p kmalloc_caches
kmalloc_caches = $1 =
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffc6008fdc80, 0xffffffc6008fdb00, 0xffffffc6008fd980, 0xffffffc6008fd800, 0xffffffc6008fd680, 0xffffffc6008fd500, 0xffffffc6008fd380}
0xffffffc6008fdb00 주소에 해당하는 슬랩 캐시의 정체는 다음과 같습니다.
crash64> struct kmem_cache.name 0xffffffc6008fdb00
name = 0xffffff9700f6e049 "kmalloc-256"
페이지 디스크립터 구조체를 보면 포인터 형인 slab_cache 필드가 있습니다.
crash64> struct page
struct page {
unsigned long flags;
...
struct {
union {
struct list_head slab_list;
struct {
struct page *next;
int pages;
int pobjects;
};
};
struct kmem_cache *slab_cache;
void *freelist;
...
crash64_kaslr> struct page.slab_cache
struct page {
[0x18] struct kmem_cache *slab_cache;
}
그래서 슬랩 캐시의 주소 검색을 통해 해당 슬랩 캐시의 페이지 갯수를 확인할 수 있습니다.
crash64_kaslr> search 0xffffffc6008fdb00
ffffff80156ab8a0: ffffffc6008fdb00
ffffff97012c4a00: ffffffc6008fdb00
ffffffbf18023e98: ffffffc6008fdb00
...
vmemmap의 시작 주소가 ffffffbc00000000 이므로 ffffff80156ab8a0와 ffffff97012c4a00 주소에 위치한 슬랩 캐시의 주소는 별 의미가 없습니다.
vmemmap 메모리 공간에서 "kmalloc-256" 슬랩 캐시를 포함하는 페이지 디스크립터의 갯수는 880개입니다.
crash64> search 0xffffffc6008fdb00 | wc -l
882
// 880 = 882 - 2
이번에는 "kmalloc-128" 슬랩 캐시의 페이지 디스크립터의 갯수를 확인하겠습니다.
crash64_kaslr> struct kmem_cache.name 0xffffffc6008fdb00
name = 0xffffff9700f6e03d "kmalloc-128"
엄청난 갯수의 페이지 디스크립터를 사용하고 있습니다.
crash64> search 0xffffffc6008fdc80 | wc -l
891606
vmemmap의 범위('ffffffbc00000000 - ffffffbdffffffff') 밖의 주소가 포함하는 "kmalloc-128" 슬랩 캐시의 갯수는
16이므로, 891590(891606 - 16) 개의 페이지를 소진하고 있습니다.
crash64> search 0xffffffc6008fdc80
ffffff80083ab670: ffffffc6008fdc80
ffffff80083ab6f8: ffffffc6008fdc80
ffffff800951bc20: ffffffc6008fdc80
ffffff800951bc30: ffffffc6008fdc80
ffffff800951bc50: ffffffc6008fdc80
ffffff800958b8b0: ffffffc6008fdc80
ffffff800958b8c0: ffffffc6008fdc80
ffffff80145bbba0: ffffffc6008fdc80
ffffff8015a0bab0: ffffffc6008fdc80
ffffff8015e9bb30: ffffffc6008fdc80
ffffff801647b6d0: ffffffc6008fdc80
ffffff801772b830: ffffffc6008fdc80
ffffff8017a5b830: ffffffc6008fdc80
ffffff8017a5b840: ffffffc6008fdc80
ffffff8021223ab0: ffffffc6008fdc80
ffffff97012c49f8: ffffffc6008fdc80
"kmalloc-128" 슬랩 오브젝트의 Leak을 확인할 필요가 있습니다.
# Reference: For more information on 'Linux Kernel';
디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 1
디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 2
'[Debugging] Tips' 카테고리의 다른 글
[리눅스커널][디버깅] ftrace: ftrace를 비활성화하기 (0) | 2023.05.04 |
---|---|
[TRACE32] 폰트(FONT) 사이트 변경 (0) | 2023.05.04 |
[리눅스커널] TRACE32: 'v.type' 명령어로 구조체와 enum 필드를 바로 확인하기 (0) | 2023.05.04 |
[리눅스][디버깅] GDB로 깨진 콜 스택 복원하기(공유 라이브러리 로딩하는 방법) (0) | 2023.05.04 |
[리눅스] GDB 프로그램 사용 위치 파악: 'which -a' (0) | 2023.05.04 |