Package vtrace :: Module breakpoints
[hide private]
[frames] | no frames]

Source Code for Module vtrace.breakpoints

  1   
  2  """ 
  3  Breakpoint Objects 
  4  """ 
  5   
  6  # Copyright (C) 2007 Invisigoth - See LICENSE file for details 
  7   
  8  import time 
  9   
 10  import vtrace 
 11   
12 -class Breakpoint:
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 = {} # Cache compiled code objects on the class def 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
37 - def getAddress(self):
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
45 - def getId(self):
46 return self.id
47
48 - def getName(self):
49 if self.vte: 50 return str(self.vte) 51 return "0x%.8x" % self.address
52
53 - def __repr__(self):
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
60 - def inittrace(self, trace):
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
68 - def resolvedaddr(self, trace, addr):
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
75 - def activate(self, trace):
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
89 - def deactivate(self, trace):
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
101 - def resolveAddress(self, trace):
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 # If we resolved, lets get our saved code... 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
120 - def isEnabled(self):
121 """ 122 Is this breakpoint "enabled"? 123 """ 124 return self.enabled
125
126 - def setEnabled(self, enabled=True):
127 """ 128 Set this breakpoints "enabled" status 129 """ 130 self.enabled = enabled
131
132 - def setBreakpointCode(self, pystr):
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
144 - def getBreakpointCode(self):
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
168 -class TrackerBreak(Breakpoint):
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
181 -class OneTimeBreak(Breakpoint):
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):
188 trace.removeBreakpoint(self.id) 189 Breakpoint.notify(self, event, trace)
190
191 -class StopRunForeverBreak(Breakpoint):
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):
199 trace.setMode("RunForever", False) 200 Breakpoint.notify(self, event, trace)
201
202 -class StopAndRemoveBreak(Breakpoint):
203 """ 204 When hit, take the tracer out of run-forever mode and 205 remove this breakpoint. 206 """
207 - def notify(self, event, trace):
208 trace.setMode("RunForever", False) 209 trace.removeBreakpoint(self.id) 210 Breakpoint.notify(self, event, trace)
211
212 -class CallBreak(Breakpoint):
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 # Filled in when we get hit 227 self.saved_regs = saved_regs
228
229 - def notify(self, event, trace):
230 self.endregs = trace.getRegisters() 231 trace.removeBreakpoint(self.id) 232 trace.setRegisters(self.saved_regs) 233 trace.setMeta("PendingSignal", None)
234
235 -class SnapshotBreak(Breakpoint):
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):
244 exe = trace.getExe() 245 snap = trace.takeSnapshot() 246 snap.saveToFile("%s-%d.vsnap" % (exe,time.time())) 247 Breakpoint.notify(self, event, trace)
248