-
Notifications
You must be signed in to change notification settings - Fork 0
/
bp.py
58 lines (50 loc) · 1.88 KB
/
bp.py
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
try:
import gdb
except ImportError as e:
raise ImportError("This script must be run in GDB: ", str(e))
class BreakPoint(gdb.Breakpoint):
'''create a breakpoint at `bp_expr`, call the cb when the breakpoint hit, stop if stop=true'''
def __init__(self, bp_expr, callback, stop=False, temporary=False):
gdb.Breakpoint.__init__(self, bp_expr, gdb.BP_BREAKPOINT, False, temporary)
self.silent = True
self._callback = callback
self._stop = stop
def stop(self):
stop_after_callback = self._callback()
return self._stop and stop_after_callback
class FinishBreakpoint(gdb.FinishBreakpoint):
def __init__(self, cb):
super().__init__()
self._callback = cb
def stop(self):
print("normal finish")
try:
if self._callback:
self._callback()
except RuntimeError as e:
print(e)
return False
def out_of_scope():
print("abnormal finish, do not run the call back")
class WatchPoint(gdb.Breakpoint):
'''
gdb watchpoint expression '..'
doesn't work. It will complains 'You may have requested too many hardware breakpoints/watchpoints.'
The workaround is set wp by address, like 'watch *(long *) 0xa0f74d8'
'''
def __init__(self, expr, cb):
self.expr = expr
self.val = gdb.parse_and_eval(self.expr)
self.address = self.val.address
self.ty = gdb.lookup_type('int')
addr_expr = '*(int*)' + str(self.address)
gdb.Breakpoint.__init__(self, addr_expr, gdb.BP_WATCHPOINT)
self.silent = True
self.callback = cb
def stop(self):
addr = int(str(self.address), 16)
val_buf = gdb.selected_inferior().read_memory(addr, 4)
val = gdb.Value(val_buf, self.ty)
print('symbal value = ' + str(val))
self.callback()
return False