-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathregdiff-gdb.py
More file actions
78 lines (64 loc) · 2.68 KB
/
Copy pathregdiff-gdb.py
File metadata and controls
78 lines (64 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import gdb
import re
class RegDiff(gdb.Command):
"""Display only registers that have changed since last call."""
def __init__(self):
super(RegDiff, self).__init__("reg-diff", gdb.COMMAND_DATA)
self.last_registers = {}
self.match_groups = set()
self.match_registers = None
# Thanks to gdb-dashboard:
# https://github.com/cyrus-and/gdb-dashboard/blob/616ed5100d3588bb70e3b86737ac0609ce0635cc/.gdbinit#L2095
def fetch_register_list(self, *match_groups):
"""Fetch register names using maintenance print register-groups."""
names = []
output = gdb.execute("maintenance print register-groups",
to_string=True)
for line in output.split('\n'):
fields = line.split()
if len(fields) != 7:
continue
name, _, _, _, _, _, groups = fields
if not re.match(r'^\w+$', name):
continue
if name in match_groups:
names.append(name)
for group in groups.split(','):
if group in match_groups:
names.append(name)
break
return names
def get_register_value(self, name):
"""Get the value of a single register."""
try:
return gdb.parse_and_eval(f"${name}")
except gdb.error:
return None
def invoke(self, arg, from_tty):
"""Compare current register values with previous ones."""
# args = gdb.string_to_argv(arg)
# TODO: get match_groups from args
match_groups = set(['general'])
if match_groups != self.match_groups:
self.match_registers = self.fetch_register_list(*match_groups)
self.match_groups = match_groups
current_registers = {}
# Get current values for all registers
for reg in self.match_registers:
value = self.get_register_value(reg)
if value is not None:
current_registers[reg] = str(value)
# Find changed registers
changed = {}
for reg, value in current_registers.items():
if reg not in self.last_registers or self.last_registers[reg] != value:
changed[reg] = (self.last_registers.get(reg, '<unknown>'), value)
self.last_registers = current_registers
if changed:
print("Changed registers:")
max_name_len = max(len(reg) for reg in changed.keys())
for reg, (old_val, new_val) in sorted(changed.items()):
print(f"{reg.ljust(max_name_len)} {old_val} -> {new_val}")
else:
print("No registers changed since last call.")
RegDiff()