Skip to content

Commit

Permalink
Dump information about given virtual address
Browse files Browse the repository at this point in the history
  • Loading branch information
franciscozdo committed May 23, 2021
1 parent f0787c5 commit 2773085
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
2 changes: 2 additions & 0 deletions sys/debug/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions sys/debug/kdump.py
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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()])
62 changes: 58 additions & 4 deletions sys/debug/virtmem.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.')

0 comments on commit 2773085

Please sign in to comment.