| Trees | Indices | Help |
|---|
|
|
1 '''
2 GDB support
3 '''
4 import os
5 import re
6 import code
7 import time
8 import socket
9 import struct
10 import platform
11 import tempfile
12
13 import PE
14 import vdb
15 import envi
16 import envi.bits as e_bits
17 import envi.resolver as e_resolv
18 import vtrace
19
20 import envi.registers as e_registers
21 import vtrace.platforms.base as v_base
22
23 '''
24 VMWare config options...
25 debugStub.listen.guest64 = "TRUE" # ends up on port 8864 (or next avail)
26 debugStub.listen.guest32 = "TRUE" # .... 8832
27
28 debugStub.listen.guest32.remote = "TRUE"
29
30 debugStub.hideBreakpoints = "TRUE" # Enable breakpoints
31
32 From GDB stuff...
33 ===== i386
34 src/gdb/i386-tdep.c
35 src/gdb/regformats/reg-i386.dat
36 ===== amd64
37 src/gdb/amd64-tdep.c
38 src/gdb/regformats/reg-x86-64.dat
39 ===== arm
40 name:arm
41 expedite:r11,sp,pc
42 32:r0
43 32:r1
44 32:r2
45 32:r3
46 32:r4
47 32:r5
48 32:r6
49 32:r7
50 32:r8
51 32:r9
52 32:r10
53 32:r11
54 32:r12
55 32:sp
56 32:lr
57 32:pc
58 96:f0
59 96:f1
60 96:f2
61 96:f3
62 96:f4
63 96:f5
64 96:f6
65 96:f7
66 32:fps
67 32:cpsr
68 '''
69
70 gdb_reg_defs = {
71 'i386': (
72 ['eax','ecx','edx','ebx','esp','ebp','esi','edi','eip','eflags','cs','ss','ds','es','fs','gs'
73 ],
74 '<16I'
75 ),
76
77 'amd64': (
78 ['rax','rbx','rcx','rdx','rsi','rdi','rbp','rsp',
79 'r8','r9','r10','r11','r12','r13','r14','r15','rip',
80 'eflags','cs','ss','ds','es','fs','gs',
81 #'st0','st1','st2','st3','st4','st5','st6','st7',
82 #'fctrl','fstat','ftag','fiseg','fioff','foseg','fooff','fop'
83 ],
84
85 #'<17Q7L' + ('10s' * 8) + '8L'
86 '<17Q7L'
87 ),
88
89 # FIXME we will need arm flavors...
90 'arm': (
91 ["r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","sl","fp","ip","sp",
92 "lr","pc", None, "cpsr"],
93 '<16I96sI'
94 ),
95 }
96
97 exit_types = ('X', 'W')
98
100 return '$%s#%.2x' % (cmd, csum(cmd))
101
107
108 SIGINT = 2
109 SIGTRAP = 5
110
111 trap_sigs = (SIGINT, SIGTRAP)
112
115
117
121
123 sp = trace.getStackCounter()
124 savedpc, exccode = trace.readMemoryFormat(sp, '<PP')
125 trace._fireSignal(exccode)
126
128
130 self._gdb_host = host
131 self._gdb_port = port
132 self._gdb_sock = None
133
134 self._gdb_filemagic = None # Tracers may use this to trigger _findLibraryMaps
135
136 # These get set by _gdbSetRegisterInfo
137 self._gdb_regfmt = ''
138 self._gdb_regsize = 0
139 self._gdb_reg_xlat = []
140 self._gdb_regnames = []
141
142 self.breaking = False
143
145 ret = ''
146 while not ret.endswith(c):
147 x = self._gdb_sock.recv(1)
148 if len(x) == 0:
149 raise Exception('socket closed prematurely!')
150 ret += x
151 return ret
152
154 b = self._gdb_sock.recv(1)
155 if len(b) == 0:
156 raise GdbServerDisconnected()
157
158 if b != '$':
159 raise Exception('Invalid Pkt Beginning! ->%s<-' % b)
160
161 bytes = self._recvUntil('#')
162 bytes = bytes[:-1]
163
164 isum = int(self._gdb_sock.recv(2), 16)
165 ssum = csum(bytes)
166 if isum != ssum:
167 raise Exception('Invalid Checksum! his: 0x%.2x ours: 0x%.2x' % (isum, ssum))
168
169 self._gdb_sock.sendall('+')
170
171 #print 'RECV: ->%s<-' % bytes
172 return bytes
173
177
179 #print 'SEND: ->%s<-' % cmd
180 self._gdb_sock.sendall(pkt(cmd))
181 b = self._gdb_sock.recv(1)
182 if b != '+':
183 raise Exception('Retrans! ->%s<-' % b)
184
186 if self._gdb_sock != None:
187 self._gdb_sock.shutdown(2)
188
189 tries = 0
190 while tries < 10:
191 self._gdb_sock = socket.socket()
192 try:
193 self._gdb_sock.connect( (self._gdb_host, self._gdb_port) )
194
195 # Some gdb stubs seem to send/expect an initial '+'
196 try:
197 self._gdb_sock.settimeout(1)
198 self._gdb_sock.recv(1)
199 self._gdb_sock.sendall('+')
200
201 except socket.timeout, t:
202 pass
203
204 self._gdb_sock.settimeout(None)
205 break
206
207 except Exception, e:
208 time.sleep(0.2)
209 tries += 1
210
212 resp = ''
213 cmd = 'qRcmd,%s' % cmd.encode('hex')
214 pkt = self._cmdTransact(cmd)
215 while not pkt.startswith('OK'):
216 self._raiseIfError(pkt)
217 if not pkt.startswith('O'):
218 return pkt.decode('hex')
219 resp += pkt[1:].decode('hex')
220 pkt = self._recvPkt()
221 return resp
222
224 self._connectSocket()
225 self.attaching = True
226 # Wait for the debug stub to stop the target
227 while True:
228 pkt = self._cmdTransact('?')
229 if len(pkt) == 0:
230 raise Exception('Attach Response Error!')
231
232 if int(pkt[1:3], 16) == 0:
233 import time
234 time.sleep(0.1)
235 self.platformSendBreak()
236 pkt = self._cmdTransact('?')
237 break
238 self._sendPkt('?')
239
241 sig = self.getCurrentSignal()
242 cmd = 'c'
243 if sig != None:
244 cmd = 'C%.2x' % sig
245 self._sendPkt(cmd)
246 #self._cmdTransact(cmd)
247
249 # FIXME by selected thread? and address?
250 #self._cmdTransact('s')
251 self._sendPkt('s')
252 self.stepping = True
253
255 if not self.running:
256 self.platformContinue()
257 self._gdb_sock.shutdown(2)
258 self._gdb_sock = None
259
261 '''
262 For now, the only way I know how to re-break the target
263 is to disconnect and re-connect... TOTALLY GHETTO HACK!
264 '''
265 # If this isn't a break during attach, tell everybody we are
266 # breaking...
267 if not self.attaching:
268 self.breaking = True
269 self._gdb_sock.sendall('\x03')
270
272 while True:
273 pkt = self._recvPkt()
274 if pkt.startswith('O'):
275 print 'GDBSTUB SAID: %s' % pkt[1:].decode('hex')
276 continue
277 break
278 return pkt
279
281 #print 'EVENT ->%s<-' % event
282
283 if len(event) == 0:
284 self.setMeta('ExitCode', 0xffffffff)
285 self.fireNotifiers(vtrace.NOTIFY_EXIT)
286 self._gdb_sock.shutdown(2)
287 self._gdb_sock = None
288 return
289
290 atype = event[0]
291 signo = int(event[1:3], 16)
292
293 # Is this a thread specific signal?
294 if atype == 'T':
295
296 #print 'SIGNAL',sig
297
298 dictbytes = event[3:]
299
300 evdict = {}
301 for kvstr in dictbytes.split(';'):
302 if not kvstr: break
303 #print 'KVSTR ->%s<-' % kvstr
304 key, value = kvstr.split(':', 1)
305 evdict[key.lower()] = value
306
307 # Did we get a specific thread?
308 tidstr = evdict.get('thread')
309 if tidstr != None:
310 tid = int(tidstr, 16)
311 self.setMeta('ThreadId', tid)
312 #else:
313 #print "WE SHOULD ASK FOR THE CURRENT THREAD HERE!"
314
315 elif atype == 'S':
316 pass
317
318 elif atype in exit_types:
319
320 # Fire an exit event and GTFO!
321 self._fireExit(signo)
322 return
323
324 else:
325 print 'Unhandled Gdb Server Event: %s' % event
326
327 #if self.attaching and signo in trap_sigs:
328 if self.attaching:
329 self.attaching = False
330 #self._enumGdbTarget()
331 if self._gdb_filemagic:
332 self._findLibraryMaps(self._gdb_filemagic, always=True)
333 self._simpleCreateThreads()
334 self.runAgain(False) # Clear this, if they want BREAK to run, it will
335 self.fireNotifiers(vtrace.NOTIFY_BREAK)
336
337 elif self.breaking and signo in trap_sigs:
338 self.breaking = False
339 self.fireNotifiers(vtrace.NOTIFY_BREAK)
340
341 # Process the signal and decide what to do...
342 elif signo == SIGTRAP:
343
344 # Traps on posix systems are a little complicated
345 if self.stepping:
346 #FIXME try out was single step thing for intel
347 self.stepping = False
348 self.fireNotifiers(vtrace.NOTIFY_STEP)
349
350 elif self.checkBreakpoints():
351 return
352
353 #elif self.checkWatchpoints():
354 #return
355
356 #elif self.checkBreakpoints():
357 # It was either a known BP or a sendBreak()
358 #return
359
360 #elif self.execing:
361 ##self.execing = False
362 #self.handleAttach()
363
364 else:
365 self._fireSignal(signo)
366
367 #elif signo == signal.SIGSTOP:
368 #self.handleAttach()
369
370 else:
371 self._fireSignal(signo)
372
374 initid = self.getMeta('ThreadId')
375 for tid in self.platformGetThreads().keys():
376 self.setMeta('ThreadId', tid)
377 self.fireNotifiers(vtrace.NOTIFY_CREATE_THREAD)
378 self.setMeta('ThreadId', initid)
379
381 # Used by the Trace implementations to tell the gdb
382 # stub code how to unpack the register buf
383
384 self._gdb_regfmt = fmt
385 self._gdb_regnames = names
386
387 self._gdb_reg_xlat = []
388 self._gdb_regsize = struct.calcsize(fmt)
389
390
391 for i,name in enumerate(names):
392 if name == None: # So we can skip parts of the gdb definition...
393 continue
394 j = self.getRegisterIndex(name)
395 if j != None:
396 self._gdb_reg_xlat.append( (i, j) )
397
399 '''
400 Get an envi register context from the target stub.
401 '''
402 # FIXME tid!
403 regbuf = self._cmdTransact('g')
404 regbytes = self._runLengthDecode(regbuf)
405 rvals = struct.unpack(self._gdb_regfmt, regbytes[:self._gdb_regsize])
406 ctx = self.arch.archGetRegCtx()
407 for myidx, enviidx in self._gdb_reg_xlat:
408 ctx.setRegister(enviidx, rvals[myidx])
409 return ctx
410
412 '''
413 Set the target stub's register context from the envi register context
414 '''
415 # FIXME tid!
416 regbytes = self._cmdTransact('g').decode('hex')
417 regremain = regbytes[self._gdb_regsize:]
418 rvals = struct.unpack(self._gdb_regfmt, regbytes[:self._gdb_regsize])
419 rvals = list(rvals) # So we can assign to them...
420 for myidx, enviidx in self._gdb_reg_xlat:
421 rvals[myidx] = ctx.getRegister(enviidx)
422 newbytes = struct.pack(self._gdb_regfmt, rvals) + regremain
423 return self._cmdTransact('G'+newbytes.encode('hex'))
424
426
427 ret = {}
428
429 self._sendPkt('qfThreadInfo')
430 tbytes = self._recvPkt()
431
432 while tbytes.startswith('m'):
433
434 if tbytes.find(','):
435 for bval in tbytes[1:].split(','):
436 ret[int(bval, 16)] = 0
437 else:
438 ret[int(tbytes[1:], 16)] = 0
439
440 self._sendPkt('qsThreadInfo')
441 tbytes = self._recvPkt()
442
443 return ret
444
448
450 # GDB RSP implements some run-length encoding to save space
451 i = buf.find('*')
452 while i != -1:
453 cnt = ord(buf[i+1]) - 29 # Run-length encoding is minus 29...
454 pad = buf[i-1] * cnt
455 buf = buf[:i] + pad + buf[i+2:]
456
457 i = buf.find('*')
458
459 return buf.decode('hex')
460
462 mbytes = ''
463 offset = 0
464 while len(mbytes) < size:
465 # FIXME is this 256 problem just in the VMWare gdb stub?
466 cmd = 'm%x,%x' % (addr + offset, min(256, size-offset))
467 pkt = self._cmdTransact(cmd)
468 self._raiseIfError(pkt)
469 pbytes = self._runLengthDecode(pkt)
470 offset += len(pbytes)
471 mbytes += pbytes
472 return mbytes
473
475 cmd = 'M%x,%x:%s' % (addr, len(mbytes), mbytes.encode('hex'))
476 pkt = self._cmdTransact(cmd)
477 self._raiseIfError(pkt)
478
481
482 # FROM HERE DOWN IS ALL CRAP THAT IS STILL GETTING SORTED OUT
483
485
487
488 self.stepping = False
489 self.attaching = False
490 self.breaking = False
491
492 self.bigmask = e_bits.u_maxes[ self.getPointerSize() ]
493
494 aname = self.getMeta('Architecture')
495 self._addArchNamespace(aname)
496
497 self.setMeta('Platform', 'gdbstub')
498
499 self.setMeta('GdbServerHost', 'localhost')
500 self.setMeta('GdbServerPort', 0)
501 self.setMeta('GdbPlatform', 'Unknown')
502 self.setMeta('GdbTargetPlatform', 'Unknown')
503
504 self.setMeta('BinaryFormat', None)
505
506 arch_reg_info = gdb_reg_defs.get(aname)
507 if arch_reg_info == None:
508 raise Exception('We dont know the GDB register definition for arch: %s' % name)
509
510 self._arch_regnames, self._arch_regfmt = arch_reg_info
511 self._arch_regsize = struct.calcsize(self._arch_regfmt)
512
513 self._arch_rctx = self.arch.archGetRegCtx()
514 self._arch_reg_xlat = []
515 for i,name in enumerate(self._arch_regnames):
516 if name == None: # So we can skip parts of the gdb definition...
517 continue
518 j = self._arch_rctx.getRegisterIndex(name)
519 if j != None:
520 self._arch_reg_xlat.append((i,j))
521
522 # Load up our register definition!
523 e_registers.RegisterContext.__init__(self)
524 rinfo = self._arch_rctx.getRegisterInfo(meta=True)
525 self.setRegisterInfo(rinfo)
526
528 if aname == 'arm':
529 import vstruct.defs.arm7 as vs_arm7
530 self.vsbuilder.addVStructNamespace('arm7', vs_arm7)
531
533 # We don't know if it's / or \ ... do both!
534 basename = fname.split('/')[-1].split('\\')[-1]
535 return basename.split(".")[0].split("-")[0].lower()
536
539
541
542 # If we're on windows, fake out the PE header and use dbghelp
543 #if platform.system() in ['Microsoft', 'Windows']:
544 if False:
545 # FIXME this code is stolen and should be a function!
546 import vtrace.platforms.win32 as vt_win32
547 fakepe = self.readMemory(baseaddr, 1024)
548 tfile = tempfile.NamedTemporaryFile(delete=False)
549 tfilename = tfile.name
550 import ctypes
551 pebuf = ctypes.create_string_buffer(fakepe)
552 try:
553 try:
554 tfile.write(fakepe)
555 tfile.close()
556 #parser = vt_win32.Win32SymbolParser(-1, tfilename, baseaddr)
557 parser = vt_win32.Win32SymbolParser(-1, None, ctypes.addressof(pebuf))
558 parser.parse()
559 parser.loadSymsIntoTrace(self, normname)
560 finally:
561 os.unlink(tfilename)
562 except Exception, e:
563 print e
564
565 else:
566 pe = PE.peFromMemoryObject(self, baseaddr)
567 for rva, ord, name in pe.getExports():
568 self.addSymbol(e_resolv.Symbol(name, baseaddr+rva, 0, normname))
569
572
574 '''
575 Use VMWare's monitor extension to get a register we wouldn't
576 normally have...
577 '''
578 #fs 0x30 base 0xffdff000 limit 0x00001fff type 0x3 s 1 dpl 0 p 1 db 1
579 fsstr = self._monitorCommand('r %s' % rname)
580 fsparts = fsstr.split()
581 return int(fsparts[3], 16)
582
584 istr = self._monitorCommand('r idtr')
585 m = re.match('.* base=(0x\w+) .*', istr)
586 idtr = long(m.groups()[0], 0)
587 return idtr
588
590 x1, kptr, x2 = self.readMemoryFormat(idtr, '<IQI')
591 try:
592 kptr -= kptr & 0xfff
593 while not self.readMemory(kptr, 16).startswith('MZ\x90\x00'):
594 kptr -= 4096
595 return kptr
596 except Exception, e:
597 return None
598
600
601 self.setVariable('fsbase', fsbase)
602
603 fs_fields = self.readMemoryFormat(fsbase, '<8I')
604
605 # Windows has a self reference in the KPCR...
606 if fs_fields[7] == fsbase:
607
608 # Use KPCR from XP for now...
609 import vstruct.defs.windows.win_5_1_i386.ntoskrnl as vs_w_ntoskrnl
610 self.vsbuilder.addVStructNamespace('nt', vs_w_ntoskrnl)
611
612 self.setMeta('GdbTargetPlatform', 'Windows')
613 self.casesens = False
614
615 kpcr = self.getStruct('nt.KPCR', fsbase)
616 kver = self.getStruct('nt.DBGKD_GET_VERSION64', kpcr.KdVersionBlock)
617
618 #print kpcr.tree()
619 #print kver.tree()
620
621 kernbase = kver.KernBase & self.bigmask
622 modlist = kver.PsLoadedModuleList & self.bigmask
623
624 self.setVariable('PsLoadedModuleList', modlist)
625 self.setVariable('KernelBase', kernbase)
626
627 self.platformParseBinary = self.platformParseBinaryPe
628
629 self.fireNotifiers(vtrace.NOTIFY_ATTACH)
630
631 self.addLibraryBase('nt', kernbase, always=True)
632 ldr_entry = self.readMemoryFormat(modlist, '<I')[0]
633 while ldr_entry != modlist:
634 ldte = self.getStruct('nt.LDR_DATA_TABLE_ENTRY', ldr_entry)
635 dllname = self.readMemory(ldte.FullDllName.Buffer, ldte.FullDllName.Length).decode('utf-16le')
636 dllbase = ldte.DllBase & self.bigmask
637 self.addLibraryBase(dllname, dllbase, always=True)
638 ldr_entry = ldte.InLoadOrderLinks.Flink & self.bigmask
639
640 try:
641 self.addBreakpoint(KeBugCheckBreak('nt.KeBugCheck'))
642 except Exception, e:
643 print 'Error Seting KeBugCheck Bp: %s' % e
644
645 try:
646 self.addBreakpoint(KeBugCheckBreak('nt.KeBugCheckEx'))
647 except Exception, e:
648 print 'Error Seting KeBugCheck Bp: %s' % e
649
650 else:
651 # FIXME enumerate non-windows OSs!
652 self.fireNotifiers(vtrace.NOTIFY_ATTACH)
653
655 psize = self.getPointerSize()
656 vercmd = self._monitorCommand('version')
657
658 monhelp = self._monitorCommand('help')
659
660 if monhelp.find('netdev_add') != -1:
661
662 self.setMeta('GdbPlatform', 'Qemu32')
663
664 fsbase = None
665 monreg = self._monitorCommand('info registers')
666 for line in monreg.split('\n'):
667 if not line.startswith('FS'):
668 continue
669 parts = line.split()
670 fsbase = int(parts[2], 16)
671 break
672
673 self._enumTargetOs(fsbase)
674 #print monreg
675 #m = re.match('FS =\w+ (\w+)', monreg, re.G)
676 #fsbase = long(m.groups()[0], 0)
677 #print 'FSBASE',hex(fsbase)
678
679 elif monhelp.find('linuxoffsets') != -1:
680
681 self.setMeta('GdbPlatform', 'VMware%d' % (psize * 8))
682
683 if psize == 4: # Use the fs register to get KPCR
684 fsbase = self._getVmwareReg('fs')
685 self._enumTargetOs(fsbase)
686
687 else: # FIXME 64bit vmware!
688
689 idtr = self._getVmwareIdtr()
690 self.setVariable('idtr', idtr)
691
692 win_kpcr = 0x07fffffde000
693
694 fields = [-1,]
695 try:
696 fields = self.readMemoryFormat(win_kpcr, '<7Q')
697 except Exception, e:
698 print 'Exception:',e
699
700 # FIXME other heuristics for linux/bsd/etc...
701 if fields[-1] == win_kpcr:
702 self._initWin64(win_kpcr)
703 else:
704 self.fireNotifiers(vtrace.NOTIFY_ATTACH)
705
706 #fsbase = self._getVmwareReg('fs')
707 #self.setVariable('fsbase', fsbase)
708
709 #fs_fields = self.readMemoryFormat(fsbase, '<8I')
710
711 #nt = self._getNtOsKrnl(idtr)
712 #if nt != None:
713 # We are 64bit windows!
714 #import vstruct.defs.windows.win_6_1_amd64.ntoskrnl as vs_w_ntoskrnl
715 #self.vsbuilder.addVStructNamespace('nt', vs_w_ntoskrnl)
716 #self.setMeta('GdbTargetPlatform', 'Windows')
717 #self.setVariable('KernelBase', nt)
718 #self.platformParseBinary = self.platformParseBinaryPe
719 #self.fireNotifiers(vtrace.NOTIFY_ATTACH)
720 #self.addLibraryBase('nt', nt, always=True)
721
722 #else:
723
724 elif vercmd.lower().find('open on-chip debugger') != -1:
725
726 self.setMeta('GdbPlatform', 'OpenOCD')
727 self.fireNotifiers(vtrace.NOTIFY_ATTACH)
728
729 else:
730 print 'Unidentified gdbstub: %s' % vercmd
731 self.fireNotifiers(vtrace.NOTIFY_ATTACH)
732
733
734 # FIXME implement getRegister(idx) and steal get/set for regs which are not part of the whole...
736
737 import vstrct.defs.windows.win_6_1_amd64.ntoskrnl as vs_w_ntoskrnl
738 self.vsbuilder.addVStructNamespace('nt', vs_w_ntoskrnl)
739 self._initWinBase()
740 #nt = self._getNtOsKrnl(idtr)
741 #if nt != None:
742 # We are 64bit windows!
743 #import vstruct.defs.windows.win_6_1_amd64.ntoskrnl as vs_w_ntoskrnl
744 #self.vsbuilder.addVStructNamespace('nt', vs_w_ntoskrnl)
745 #self.setMeta('GdbTargetPlatform', 'Windows')
746 #self.setVariable('KernelBase', nt)
747 #self.platformParseBinary = self.platformParseBinaryPe
748 #self.fireNotifiers(vtrace.NOTIFY_ATTACH)
749 #self.addLibraryBase('nt', nt, always=True)
750
752
753 self.setMeta('GdbTargetPlatform', 'Windows')
754 self.casesens = False
755
756 kpcr = self.getStruct('nt.KPCR', kpcr)
757 kver = self.getStruct('nt.DBGKD_GET_VERSION64', kpcr.KdVersionBlock)
758
759 kernbase = kver.KernBase & self.bigmask
760 modlist = kver.PsLoadedModuleList & self.bigmask
761
762 self.setVariable('PsLoadedModuleList', modlist)
763 self.setVariable('KernelBase', kernbase)
764
765 self.platformParseBinary = self.platformParseBinaryPe
766
767 self.fireNotifiers(vtrace.NOTIFY_ATTACH)
768
769 self.addLibraryBase('nt', kernbase, always=True)
770 ldr_entry = self.readMemoryFormat(modlist, '<P')[0]
771 while ldr_entry != modlist:
772 ldte = self.getStruct('nt.LDR_DATA_TABLE_ENTRY', ldr_entry)
773 dllname = self.readMemory(ldte.FullDllName.Buffer, ldte.FullDllName.Length).decode('utf-16le')
774 dllbase = ldte.DllBase & self.bigmask
775 self.addLibraryBase(dllname, dllbase, always=True)
776 ldr_entry = ldte.InLoadOrderLinks.Flink & self.bigmask
777
778 try:
779 self.addBreakpoint(KeBugCheckBreak('nt.KeBugCheck'))
780 except Exception, e:
781 print 'Error Seting KeBugCheck Bp: %s' % e
782
783 try:
784 self.addBreakpoint(KeBugCheckBreak('nt.KeBugCheckEx'))
785 except Exception, e:
786 print 'Error Seting KeBugCheck Bp: %s' % e
787
788
789 GDB_BP_SOFTWARE = 0
790 GDB_BP_HARDWARE = 1
791 GDB_BP_WATCH_WRITE = 2
792 GDB_BP_WATCH_READ = 3
793 GDB_BP_WATCH_ACCESS = 4
794
799
801
802 # First things first, lets steal ourself an arch!
803 envi.stealArchMethods(self, archname)
804 vtrace.Trace.__init__(self, archname=archname)
805 v_base.TracerBase.__init__(self)
806 GdbStubMixin.__init__(self)
807
808 self._break_after_bp = False # We break *at* the bp
809
810 # FIXME this should have a cleaner abstraction to allow for stuff...
811 # platformActivateBreak / Watch!
812 # platformDeactivateBreak / Watch!
813
814 # FIXME we also need cleaner abstraction for checkBreakpoints
815 # (some platforms stop *on* break and some stop *after...)
816
818 # For now, we don't support watchpoints...
819 if not bp.active:
820 addr = bp.resolveAddress(self)
821 self._cmdTransact('Z%d,%x,%x' % (GDB_BP_SOFTWARE,addr,1))
822
824 '''
825 Cleanup any non-fastbreak breakpoints. This routine doesn't even get
826 called in the event of mode FastBreak=True.
827 '''
828 self.fb_bp_done = False
829 for bp in self.breakpoints.itervalues():
830 # No harm in calling deactivate on
831 # an inactive bp
832 if force or not bp.fastbreak:
833 self._cmdTransact('z%d,%x,%x' % (GDB_BP_SOFTWARE,bp.getAddress(),1))
834 bp.active = False
835 #bp.deactivate(self)
836
838 """
839 Check to see if we've landed on a breakpoint, and if so
840 deactivate and step us past it.
841
842 WARNING: Unfortunatly, cause this is used immidiatly before
843 a call to run/wait, we must block briefly even for the GUI
844 """
845 # Steal a reference because the step should
846 # clear curbp...
847 bp = self.curbp
848 if bp != None and bp.isEnabled():
849 # We had to remove a check for active and a deactivate here...
850 orig = self.getMode("FastStep")
851 self.setMode("FastStep", True)
852 self.stepi()
853 self.setMode("FastStep", orig)
854 self._activateBreak(bp)
855
862
| Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Fri Nov 16 18:22:21 2012 | http://epydoc.sourceforge.net |