def print_slab(self, ramdump, slab_start, slab, page, out_file): p = slab_start if page is None: return n_objects = self.get_nobjects(self.ramdump, page) if n_objects is None: return slab_size_offset = self.ramdump.field_offset('struct kmem_cache', 'size') slab_size = self.ramdump.read_int(slab + slab_size_offset) if slab_size is None: return slab_max_offset = self.ramdump.field_offset('struct kmem_cache', 'max') slab_max = self.ramdump.read_word(slab + slab_max_offset) if slab_max is None: return bitarray = [0] * slab_max addr = page_address(self.ramdump, page) self.get_map(self.ramdump, slab, page, bitarray) while p < slab_start + n_objects * slab_size: idx = self.slab_index(self.ramdump, p, addr, slab) bitidx = self.slab_index(self.ramdump, p, addr, slab) if bitidx >= len(bitarray) or bitidx < 0: return if bitarray[bitidx] == 1: out_file.write(' Object {0:x}-{1:x} FREE\n'.format( p, p + slab_size)) else: out_file.write(' Object {0:x}-{1:x} ALLOCATED\n'.format( p, p + slab_size)) if self.ramdump.is_config_defined('CONFIG_SLUB_DEBUG_ON'): self.print_track(self.ramdump, slab, p, 0, out_file) self.print_track(self.ramdump, slab, p, 1, out_file) p = p + slab_size
def print_slab_page_info(self, ramdump, slab, slab_node, start, out_file, map_fn): page = self.ramdump.read_word(start) seen = [] if page == 0: return slab_lru_offset = self.ramdump.field_offset('struct page', 'lru') page_flags_offset = self.ramdump.field_offset('struct page', 'flags') max_pfn_addr = self.ramdump.address_of('max_pfn') max_pfn = self.ramdump.read_word(max_pfn_addr) max_page = pfn_to_page(ramdump, max_pfn) while page != start: if page is None: return if page in seen: return if page > max_page: return seen.append(page) page = page - slab_lru_offset page_flags = self.ramdump.read_word(page + page_flags_offset) page_addr = page_address(self.ramdump, page) self.print_slab(self.ramdump, page_addr, slab, page, out_file, map_fn) page = self.ramdump.read_word(page + slab_lru_offset)
def print_trailer(self, s, page, p, out_file): addr = page_address(self.ramdump, page) if self.ramdump.is_config_defined('CONFIG_SLUB_DEBUG_ON'): self.print_track(self.ramdump, s.addr, p, 0, out_file) self.print_track(self.ramdump, s.addr, p, 1, out_file) out_file.write( 'INFO: Object 0x{:x} @offset=0x{:x} fp=0x{:x}\n\n'.format( p, p - addr, self.get_free_pointer(self.ramdump, s, p))) if (p > addr + 16): self.print_section('Bytes b4 ', p - 16, 16, out_file) self.print_section('Object ', p, min(s.object_size, 4096), out_file) if (s.flags & SLAB_RED_ZONE): self.print_section('Redzone ', p + s.object_size, s.inuse - s.object_size, out_file) if (s.offset): off = s.offset + self.ramdump.sizeof('void *') else: off = s.inuse if (s.flags & SLAB_STORE_USER): off += 2 * self.ramdump.sizeof('struct track') if (off != s.size): # Beginning of the filler is the free pointer self.print_section('Padding ', p + off, s.size - off, out_file)
def print_trailer(self, s, page, p, out_file): addr = page_address(self.ramdump, page) if self.ramdump.is_config_defined('CONFIG_SLUB_DEBUG_ON'): self.print_track(self.ramdump, s.addr, p, 0, out_file) self.print_track(self.ramdump, s.addr, p, 1, out_file) out_file.write('INFO: Object 0x{:x} @offset=0x{:x} fp=0x{:x}\n\n'.format( p, p - addr, self.get_free_pointer(self.ramdump, s, p))) if (p > addr + 16): self.print_section('Bytes b4 ', p - 16, 16, out_file) self.print_section('Object ', p, min(s.object_size, 4096), out_file) if (s.flags & SLAB_RED_ZONE): self.print_section('Redzone ', p + s.object_size, s.inuse - s.object_size, out_file) if (s.offset): off = s.offset + self.ramdump.sizeof('void *') else: off = s.inuse if (s.flags & SLAB_STORE_USER): off += 2 * self.ramdump.sizeof('struct track') if (off != s.size): # Beginning of the filler is the free pointer self.print_section('Padding ', p + off, s.size - off, out_file)
def print_slab(self, ramdump, slab_start, slab, page, out_file): p = slab_start if page is None: return n_objects = self.get_nobjects(self.ramdump, page) if n_objects is None: return slab_size_offset = self.ramdump.field_offset("struct kmem_cache", "size") slab_size = self.ramdump.read_int(slab + slab_size_offset) if slab_size is None: return slab_max_offset = self.ramdump.field_offset("struct kmem_cache", "max") slab_max = self.ramdump.read_word(slab + slab_max_offset) if slab_max is None: return bitarray = [0] * slab_max addr = page_address(self.ramdump, page) self.get_map(self.ramdump, slab, page, bitarray) while p < slab_start + n_objects * slab_size: idx = self.slab_index(self.ramdump, p, addr, slab) bitidx = self.slab_index(self.ramdump, p, addr, slab) if bitidx >= len(bitarray) or bitidx < 0: return if bitarray[bitidx] == 1: out_file.write(" Object {0:x}-{1:x} FREE\n".format(p, p + slab_size)) else: out_file.write(" Object {0:x}-{1:x} ALLOCATED\n".format(p, p + slab_size)) if self.ramdump.is_config_defined("CONFIG_SLUB_DEBUG_ON"): self.print_track(self.ramdump, slab, p, 0, out_file) self.print_track(self.ramdump, slab, p, 1, out_file) p = p + slab_size
def print_per_cpu_slab_info(self, ramdump, slab, slab_node, start, out_file): page = self.ramdump.read_word(start) if page == 0: return page_flags_offset = self.ramdump.field_offset("struct page", "flags") if page is None: return page_flags = self.ramdump.read_word(page + page_flags_offset) page_addr = page_address(self.ramdump, page) self.print_slab(self.ramdump, page_addr, slab, page, out_file)
def print_per_cpu_slab_info(self, ramdump, slab, slab_node, start, out_file, map_fn): page = self.ramdump.read_word(start) if page == 0: return page_flags_offset = self.ramdump.field_offset('struct page', 'flags') if page is None: return page_flags = self.ramdump.read_word(page + page_flags_offset) page_addr = page_address(self.ramdump, page) self.print_slab(self.ramdump, page_addr, slab, page, out_file, map_fn)
def get_map(self, ramdump, slab, page, bitarray): freelist_offset = self.ramdump.field_offset('struct page', 'freelist') freelist = self.ramdump.read_word(page + freelist_offset) p = freelist addr = page_address(self.ramdump, page) seen = [] if addr is None: return while p != 0 and p is not None and p not in seen: idx = self.slab_index(self.ramdump, p, addr, slab) if idx >= len(bitarray) or idx < 0: return bitarray[idx] = 1 seen.append(p) p = self.get_free_pointer(self.ramdump, slab, p)
def get_map(self, ramdump, slab, page, bitarray): freelist_offset = self.ramdump.field_offset("struct page", "freelist") freelist = self.ramdump.read_word(page + freelist_offset) p = freelist addr = page_address(self.ramdump, page) seen = [] if addr is None: return while p != 0 and p is not None and p not in seen: idx = self.slab_index(self.ramdump, p, addr, slab) if idx >= len(bitarray) or idx < 0: return bitarray[idx] = 1 seen.append(p) p = self.get_free_pointer(self.ramdump, slab, p)
def print_slab(self, ramdump, slab_start, slab, page, out_file, map_fn): p = slab_start if page is None: return n_objects = self.get_nobjects(self.ramdump, page) if n_objects is None: return bitarray = [0] * slab.max addr = page_address(self.ramdump, page) self.get_map(self.ramdump, slab, page, bitarray) while p < slab_start + n_objects * slab.size: idx = self.slab_index(self.ramdump, p, addr, slab) bitidx = self.slab_index(self.ramdump, p, addr, slab) if bitidx >= len(bitarray) or bitidx < 0: return map_fn(p, bitarray[bitidx], slab, page, out_file) p = p + slab.size
def print_slab_page_info(self, ramdump, slab, slab_node, start, out_file): page = self.ramdump.read_word(start) seen = [] if page == 0: return slab_lru_offset = self.ramdump.field_offset("struct page", "lru") page_flags_offset = self.ramdump.field_offset("struct page", "flags") slab_node_offset = self.ramdump.field_offset("struct kmem_cache", "size") max_pfn_addr = self.ramdump.addr_lookup("max_pfn") max_pfn = self.ramdump.read_word(max_pfn_addr) max_page = pfn_to_page(ramdump, max_pfn) while page != start: if page is None: return if page in seen: return if page > max_page: return seen.append(page) page = page - slab_lru_offset page_flags = self.ramdump.read_word(page + page_flags_offset) page_addr = page_address(self.ramdump, page) self.print_slab(self.ramdump, page_addr, slab, page, out_file) page = self.ramdump.read_word(page + slab_lru_offset)