1
2 """
3 Breakpoint Objects
4 """
5
6
7
8 import time
9
10 import vtrace
11
13 """
14 Breakpoints in Vtrace are platform independant objects that
15 use the underlying trace objects to get things like the
16 program counter and the break instruction. As long as
17 platfforms are completely implemented, all breakpoint
18 objects should be portable.
19 """
20
21 bpcodeobj = {}
22
23 - def __init__(self, address, expression=None):
24 self.saved = None
25 self.resonce = False
26 self.address = address
27 self.breakinst = None
28 self.enabled = True
29 self.active = False
30 self.fastbreak = False
31 self.id = -1
32 self.vte = None
33 self.bpcode = None
34 if expression:
35 self.vte = expression
36
38 """
39 This will return the address for this breakpoint. If the return'd
40 address is None, this is a deferred breakpoint which needs to have
41 resolveAddress() called to attempt to set the address.
42 """
43 return self.address
44
47
49 if self.vte:
50 return str(self.vte)
51 return "0x%.8x" % self.address
52
54 if self.address == None:
55 addr = "unresolved"
56 else:
57 addr = "0x%.8x" % self.address
58 return "[%d] %s %s: %s" % (self.id, addr, self.__class__.__name__, self.getName())
59
61 '''
62 A callback to do housekeeping at the time the breakpoint is
63 added to the tracer object. This should be used instead of activate
64 for initialization time infoz to save on time per activate call...
65 '''
66 self.breakinst = trace.archGetBreakInstr()
67
69 '''
70 An initialization callback which will be executed when the
71 actual address for this breakpoint has been resolved.
72 '''
73 self.saved = trace.readMemory(addr, len(self.breakinst))
74
76 """
77 Actually store off and replace memory for this process. This
78 is caried out by the trace object itself when it begins
79 running or stops. You probably never need to call this
80 (see isEnabled() setEnabled() for boolean enable/disablle)
81 """
82 trace.requireAttached()
83 if not self.active:
84 if self.address != None:
85 trace.writeMemory(self.address, self.breakinst)
86 self.active = True
87 return self.active
88
90 """
91 Repair the process for continued execution. this does NOT
92 make a breakpoint *inactive*, but removes it's "0xcc" from mem
93 (see isEnabled() setEnabled() for boolean enable/dissable)
94 """
95 trace.requireAttached()
96 if self.active:
97 self.active = False
98 trace.writeMemory(self.address, self.saved)
99 return self.active
100
102 """
103 Try to resolve the address for this break. If this is a statically
104 addressed break, just return the address. If it has an "expression"
105 use that to resolve the address...
106 """
107 if self.address == None and self.vte:
108 try:
109 self.address = trace.parseExpression(self.vte)
110 except Exception, e:
111 self.address == None
112
113
114 if self.address != None and not self.resonce:
115 self.resonce = True
116 self.resolvedaddr(trace, self.address)
117
118 return self.address
119
121 """
122 Is this breakpoint "enabled"?
123 """
124 return self.enabled
125
127 """
128 Set this breakpoints "enabled" status
129 """
130 self.enabled = enabled
131
133 """
134 Use this method to set custom python code to run when this
135 breakpoint gets hit. The code will have the following objects
136 mapped into it's namespace when run:
137 trace - the tracer
138 vtrace - the vtrace module
139 bp - the breakpoint
140 """
141 self.bpcode = pystr
142 Breakpoint.bpcodeobj.pop(self.id, None)
143
145 """
146 Return the current python string that will be run when this break is hit.
147 """
148 return self.bpcode
149
150 - def notify(self, event, trace):
151 """
152 Breakpoints may also extend and implement "notify" which will be
153 called whenever they are hit. If you want to continue the ability
154 for this breakpoint to have bpcode, you must call this method from
155 your override.
156 """
157 if self.bpcode != None:
158 cobj = Breakpoint.bpcodeobj.get(self.id, None)
159 if cobj == None:
160 fname = "BP:%d (0x%.8x)" % (self.id, self.address)
161 cobj = compile(self.bpcode, fname, "exec")
162 Breakpoint.bpcodeobj[self.id] = cobj
163
164 d = vtrace.VtraceExpressionLocals(trace)
165 d['bp'] = self
166 exec(cobj, None, d)
167
169 """
170 A breakpoint which will record how many times it was hit
171 (by the address it was at) as metadata for the tracer.
172 """
173 - def notify(self, event, trace):
174 tb = trace.getMeta("TrackerBreak", None)
175 if tb == None:
176 tb = {}
177 trace.setMeta("TrackerBreak", tb)
178 tb[self.address] = (tb.get(self.address,0) + 1)
179 Breakpoint.notify(self, event, trace)
180
182 """
183 This type of breakpoint is exclusivly for marking
184 and code-coverage stuff. It removes itself.
185 (most frequently used with a continued trace)
186 """
187 - def notify(self, event, trace):
190
192 """
193 This breakpoint will turn off RunForever mode
194 on the tracer object when hit. it's a good way
195 to let things run on and on processing exceptions
196 but stop when you get to this one thing.
197 """
198 - def notify(self, event, trace):
201
203 """
204 When hit, take the tracer out of run-forever mode and
205 remove this breakpoint.
206 """
207 - def notify(self, event, trace):
211
213 """
214 A special breakpoint which will restore process
215 state (registers in particular) when it gets hit.
216 This is primarily used by the call method inside
217 the trace object to restore original state
218 after a successful "call" method call.
219
220 Additionally, the endregs dict will be filled in
221 with the regs at the time it was hit and kept until
222 we get garbage collected...
223 """
224 - def __init__(self, address, saved_regs):
225 Breakpoint.__init__(self, address)
226 self.endregs = None
227 self.saved_regs = saved_regs
228
229 - def notify(self, event, trace):
234
236 """
237 A special breakpoint type which will produce vtrace snapshots
238 for the target process when hit. The snapshots will be saved
239 to a default name of <exename>-<timestamp>.vsnap. This is not
240 recommended for use in heavily hit breakpoints as taking a
241 snapshot is processor intensive.
242 """
243 - def notify(self, event, trace):
248