From 277308563e7c38481681b566d79d1539ddade2b5 Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Sun, 23 May 2021 14:37:45 +0200 Subject: [PATCH] Dump information about given virtual address --- sys/debug/README.md | 2 ++ sys/debug/kdump.py | 8 +++--- sys/debug/virtmem.py | 62 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/sys/debug/README.md b/sys/debug/README.md index 41395fe45a..d34aaa0a98 100644 --- a/sys/debug/README.md +++ b/sys/debug/README.md @@ -18,6 +18,8 @@ you can use following custom commands: addresses, * `vm_map` - list memory map of process of given pid (when number is given as argument) or of current process (when no argument is given) +* `vm_address` - dump all information about given address in process virtual address space + (e.g. `kdump vm_address 3 0x412000` tells about address 0x412000 in vmspace of process 3) * `klog` - all log messages currently saved in the kernel, * `threads` - all existing threads, * `tlb` - Translation Lookaside Buffer with addresses and flags marking if page diff --git a/sys/debug/kdump.py b/sys/debug/kdump.py index 817b4f9a8f..5d45c7f945 100644 --- a/sys/debug/kdump.py +++ b/sys/debug/kdump.py @@ -1,4 +1,4 @@ -from .virtmem import VmPhysSeg, VmFreePages, VmMapSeg, PhysMap +from .virtmem import VmAddress, VmPhysSeg, VmFreePages, VmMapSeg, PhysMap from .memory import Vmem, Malloc, MallocStats, PoolStats from .cmd import CommandDispatcher @@ -7,6 +7,6 @@ class Kdump(CommandDispatcher): """Examine kernel data structures.""" def __init__(self): - super().__init__('kdump', [VmPhysSeg(), VmFreePages(), VmMapSeg(), - PhysMap(), Vmem(), Malloc(), MallocStats(), - PoolStats()]) + super().__init__('kdump', [VmAddress(), VmPhysSeg(), VmFreePages(), + VmMapSeg(), PhysMap(), Vmem(), Malloc(), + MallocStats(), PoolStats()]) diff --git a/sys/debug/virtmem.py b/sys/debug/virtmem.py index 987272d83d..9cced2a9bd 100644 --- a/sys/debug/virtmem.py +++ b/sys/debug/virtmem.py @@ -96,11 +96,65 @@ def __call__(self, args): vm_map = proc.vm_map() entries = vm_map['entries'] - table = TextTable(types='itttttt', align='rrrrrrr') - table.header(['segment', 'start', 'end', 'prot', 'flags', 'object', - 'offset']) + table = TextTable(types='ittttt', align='rrrrrr') + table.header(['segment', 'start', 'end', 'prot', 'flags', 'object']) segments = TailQueue(entries, 'link') for idx, seg in enumerate(segments): table.add_row([idx, seg['start'], seg['end'], seg['prot'], - seg['flags'], seg['object'], seg['offset']]) + seg['flags'], seg['object']]) print(table) + + +def print_entry(ent): + table = TextTable(types='tttttt', align='rrrrrr') + table.header(['start', 'end', 'prot', 'flags', 'object', 'offset']) + table.add_row([ent['start'], ent['end'], ent['prot'], ent['flags'], + ent['object'], ent['offset']]) + print(table) + + +def print_addr_in_object(ent, address): + offset = ent['offset'] + address - ent['start'] + obj_addr = ent['object'] + page = gdb.parse_and_eval(f'vm_object_find_page({obj_addr}, {offset})') + if page == 0x0: + print(f'There is no page for address {hex(address)} in vm_object') + return + obj = obj_addr.dereference() + print(f'Page found in object ({obj_addr}):\n{obj}') + + +class VmAddress(UserCommand): + """List all information about addres in given vm_map""" + + def __init__(self): + super().__init__('vm_address') + + def __call__(self, args): + args = args.split() + + if len(args) < 2: + print("Please give pid and address") + return + + pid = int(args[0]) + address = int(args[1], 16) + + proc = Process.from_pid(pid) + if proc is None: + print(f'No process of pid {pid}!') + return + + PAGESHIFT = 12 + entries = TailQueue(proc.vm_map()['entries'], 'link') + for ent in entries: + if address >= ent['start'] and address < ent['end']: + print(f'Address in entry {ent.address}') + print_entry(ent) + # align address + address = (address >> PAGESHIFT) << PAGESHIFT + obj = ent['object'] + if obj != 0: + print_addr_in_object(ent, address) + return + print(f'Adress not found in process {pid} address space.')