|
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | +import gdb |
| 4 | + |
| 5 | +def container_of(member_ptr, parent_type, member_name): |
| 6 | + # 获取成员在父结构体中的偏移量 |
| 7 | + parent_type = gdb.lookup_type(parent_type) |
| 8 | + member_offset = int(parent_type[member_name].bitpos / 8) |
| 9 | + |
| 10 | + # 计算结构体的起始地址 |
| 11 | + parent_address = member_ptr.cast(gdb.lookup_type('uintptr_t')) - member_offset |
| 12 | + |
| 13 | + # 返回父结构体的对象 |
| 14 | + return gdb.Value(parent_address).cast(parent_type.pointer()).dereference() |
| 15 | + |
| 16 | +def per_cpu_ptr(ptr, cpu): |
| 17 | + # __per_cpu_offset can be found by `init_kmem_cache_cpus` (inlined in `__kmem_cache_create`) |
| 18 | + # 0xffffffff814538ae <__kmem_cache_create+974>: add rbx,QWORD PTR [r14*8-0x7d5af4c0] |
| 19 | + __per_cpu_offset = gdb.lookup_symbol('__per_cpu_offset')[0] |
| 20 | + if __per_cpu_offset is None: |
| 21 | + print("全局变量 '__per_cpu_offset' 未找到。") |
| 22 | + return None |
| 23 | + |
| 24 | + per_cpu_offset = __per_cpu_offset.value() |
| 25 | + |
| 26 | + per_cpu_base = per_cpu_offset[cpu].cast(gdb.lookup_type('uintptr_t')) |
| 27 | + return per_cpu_base + ptr |
| 28 | + # print(per_cpu_base) |
| 29 | + |
| 30 | +def traverse_slab_caches(cb): |
| 31 | + # 查找全局变量 slab_caches |
| 32 | + slab_caches = gdb.lookup_symbol('slab_caches')[0] |
| 33 | + if slab_caches is None: |
| 34 | + print("全局变量 'slab_caches' 未找到。") |
| 35 | + return |
| 36 | + |
| 37 | + # 获取 slab_caches 的值 |
| 38 | + slab_cache = slab_caches.value() |
| 39 | + if slab_cache is None: |
| 40 | + print("slab_caches 是空的。") |
| 41 | + return |
| 42 | + |
| 43 | + # 遍历链表 |
| 44 | + node = slab_cache |
| 45 | + count = 0 |
| 46 | + while node and node['next'].dereference() != slab_cache: |
| 47 | + cache = container_of(node, 'struct kmem_cache', 'list') |
| 48 | + |
| 49 | + cb(cache) |
| 50 | + |
| 51 | + if node['next']: |
| 52 | + node = node['next'].dereference() |
| 53 | + else: |
| 54 | + break |
| 55 | + |
| 56 | + count += 1 |
| 57 | + |
| 58 | +def find_slab_caches(name): |
| 59 | + # 查找全局变量 slab_caches |
| 60 | + slab_caches = gdb.lookup_symbol('slab_caches')[0] |
| 61 | + if slab_caches is None: |
| 62 | + print("全局变量 'slab_caches' 未找到。") |
| 63 | + return None |
| 64 | + |
| 65 | + # 获取 slab_caches 的值 |
| 66 | + slab_cache = slab_caches.value() |
| 67 | + if slab_cache is None: |
| 68 | + print("slab_caches 是空的。") |
| 69 | + return None |
| 70 | + |
| 71 | + # 遍历链表 |
| 72 | + node = slab_cache |
| 73 | + count = 0 |
| 74 | + while node and node['next'].dereference() != slab_cache: |
| 75 | + cache = container_of(node, 'struct kmem_cache', 'list') |
| 76 | + |
| 77 | + if cache['name'].string() == name: |
| 78 | + return cache |
| 79 | + |
| 80 | + if node['next']: |
| 81 | + node = node['next'].dereference() |
| 82 | + else: |
| 83 | + break |
| 84 | + |
| 85 | + count += 1 |
| 86 | + |
| 87 | + return None |
| 88 | + |
| 89 | + |
| 90 | +slab_unix = [] |
| 91 | +# name = 0xffff88800a662090 ":A-0001088", |
| 92 | +def is_same_slab_unix(cache): |
| 93 | + if cache['kobj']['name'].string() == ':A-0001088': |
| 94 | + slab_unix.append(cache['name'].string()) |
| 95 | + return True |
| 96 | + return False |
| 97 | + |
| 98 | + |
| 99 | +# 在 GDB 中运行此函数 |
| 100 | +cache = find_slab_caches('UNIX') |
| 101 | +cpu_slab = per_cpu_ptr(cache['cpu_slab'].cast(gdb.lookup_type('int')), 0).cast(gdb.lookup_type('struct kmem_cache_cpu').pointer()).dereference() |
| 102 | + |
| 103 | +print(cache) |
| 104 | + |
| 105 | +node = cpu_slab['partial'].cast(gdb.lookup_type('struct slab').pointer()).dereference() |
| 106 | +list = node['slab_list'] |
| 107 | +print(node) |
0 commit comments