bpdb - 1.0 pass

This commit is contained in:
Ken Patel 2010-04-21 01:16:29 +00:00
parent 0dba1b0ab0
commit 3895096d94

View File

@ -4313,6 +4313,7 @@ if __debug__:
class BpDb: class BpDb:
enabled = True enabled = True
lastBp = None lastBp = None
grpInfos = {}
def set_trace(self, frameCount=1): def set_trace(self, frameCount=1):
#find usefule frame #find usefule frame
@ -4338,13 +4339,13 @@ class BpDb:
self.makeAlias('_h', 'bpdb.displayHelp()') self.makeAlias('_h', 'bpdb.displayHelp()')
self.makeAlias('_ua', 'bpdb.removeAliases()') self.makeAlias('_ua', 'bpdb.removeAliases()')
def makeAlias(self, name, cmd): def makeAlias(self, aliasName, aliasCmd):
self.aliases[name] = cmd self.aliases[aliasName] = aliasCmd
self.pdb.do_alias('%s %s'%(name,cmd)) self.pdb.do_alias('%s %s'%(aliasName,aliasCmd))
def removeAliases(self): def removeAliases(self):
for name in self.aliases.iterkeys(): for aliasName in self.aliases.iterkeys():
self.pdb.do_unalias(name) self.pdb.do_unalias(aliasName)
self.aliases = {} self.aliases = {}
print '(bpdb aliases removed)' print '(bpdb aliases removed)'
@ -4352,10 +4353,10 @@ class BpDb:
print 'You may use normal pdb commands plus the following:' print 'You may use normal pdb commands plus the following:'
#print ' cmd [param <def>] [cmd] does )this( with [param] (default is def)' #print ' cmd [param <def>] [cmd] does )this( with [param] (default is def)'
#print ' -----------------------------------------------------------------------' #print ' -----------------------------------------------------------------------'
print ' _i [n <0>, name=<curr>] set ignore count for breakpoint [name] to [n]' print ' _i [n <0> [, name=<curr>]] set ignore count for bp [name] to [n]'
print ' _t [name <curr>] toggle breakpoint name [name]' print ' _t [name <curr>] toggle bp [name]'
print ' _tg [grp <curr>] toggle breakpoint group [grp]' print ' _tg [grp <curr>] toggle bp group [grp]'
print ' _z [name <curr>] clear all settings for breakpoint [name]' print ' _z [name <curr>] clear all settings for bp [name]'
print ' _h displays this usage help' print ' _h displays this usage help'
print ' _ua unalias these commands from pdb' print ' _ua unalias these commands from pdb'
@ -4369,34 +4370,34 @@ class BpDb:
return bpdb.enabled return bpdb.enabled
@staticmethod @staticmethod
def bp(name=None, grp=None, cfg=None, iff=True, frameCount=1): def bp(id=None, grp=None, cfg=None, iff=True, frameCount=1):
if not bpdb.enabled or not bpdb.verifyEnabled(): if not bpdb.enabled or not bpdb.verifyEnabled():
return return
bpi = bp(name=name, grp=grp, cfg=cfg, iff=iff,frameCount=frameCount+1) bpi = bp(id=id, grp=grp, cfg=cfg, iff=iff,frameCount=frameCount+1)
bpi.maybeBreak(frameCount=frameCount+1) bpi.maybeBreak(frameCount=frameCount+1)
@staticmethod @staticmethod
def bpCall(name=None,grp=None,cfg=None,iff=True,frameCount=1,onEnter=1,onExit=0): def bpCall(id=None,grp=None,cfg=None,iff=True,frameCount=1,onEnter=1,onExit=0):
def decorator(f): def decorator(f):
return f return f
if not bpdb.enabled or not bpdb.verifyEnabled(): if not bpdb.enabled or not bpdb.verifyEnabled():
return decorator return decorator
bpi = bp(name=name, grp=grp, cfg=cfg, iff=iff, frameCount=frameCount+1) bpi = bp(id=id, grp=grp, cfg=cfg, iff=iff, frameCount=frameCount+1)
if bpi.disabled: if bpi.disabled:
return decorator return decorator
def decorator(f): def decorator(f):
def wrap(*args, **kwds): def wrap(*args, **kwds):
#create our bp object #create our bp object
bpi.name = name or f.__name__ dbp = bp(id=id or f.__name__, grp=bpi.grp, cfg=bpi.cfg, iff=iff, frameCount=frameCount+1)
if onEnter: if onEnter:
bpi.maybeBreak(iff=iff,frameCount=frameCount+1,displayPrefix='Calling ') dbp.maybeBreak(iff=iff,frameCount=frameCount+1,displayPrefix='Calling ')
f_result = f(*args, **kwds) f_result = f(*args, **kwds)
if onExit: if onExit:
bpi.maybeBreak(iff=iff,frameCount=frameCount+1,displayPrefix='Exited ') dbp.maybeBreak(iff=iff,frameCount=frameCount+1,displayPrefix='Exited ')
return f_result return f_result
wrap.func_name = f.func_name wrap.func_name = f.func_name
@ -4408,7 +4409,7 @@ class BpDb:
return decorator return decorator
@staticmethod @staticmethod
def group(*args, **kArgs): def bpGroup(*args, **kArgs):
if not bpdb.enabled or not bpdb.verifyEnabled(): if not bpdb.enabled or not bpdb.verifyEnabled():
def functor(*cArgs, **ckArgs): def functor(*cArgs, **ckArgs):
return return
@ -4423,33 +4424,32 @@ class BpDb:
class bp: class bp:
grpInfos = {} def __init__(self, id=None, grp=None, cfg=None, iff=True, frameCount=1):
nameInfos = {}
def __init__(self, name=None, grp=None, cfg=None, iff=True, frameCount=1):
#check early out conditions #check early out conditions
self.disabled = False self.disabled = False
if not bpdb.enabled: if not bpdb.enabled:
self.disabled = True self.disabled = True
return return
#default cfg to module name moduleName = None
callingModule = inspect.getmodule(inspect.stack()[frameCount][0]) callingModule = inspect.getmodule(inspect.stack()[frameCount][0])
moduleName = callingModule.__name__ if callingModule.__name__ != '__main__':
if cfg is None and moduleName != '__main__':
#get only leaf module name #get only leaf module name
moduleName = moduleName.split()[-1] moduleName = callingModule.__name__.split()[-1]
#prune 'Distributed' and 'AI/UD/OV'
if moduleName.find("Distributed") != -1: #default cfg to stripped module name
moduleName = moduleName[len("Distributed"):] if cfg is None and moduleName:
moduleLen = len(moduleName)
if moduleLen > 2:
for suffix in ['AI','UD','OV']:
suffixPos = moduleName.rfind(suffix)
if suffixPos == moduleLen - 2:
moduleName = moduleName[:moduleLen-2]
break
cfg = moduleName cfg = moduleName
#prune 'Distributed' and 'AI/UD/OV'
if cfg.find("Distributed") != -1:
cfg = cfg[len("Distributed"):]
cfgLen = len(cfg)
if cfg > 2:
for suffix in ['AI','UD','OV']:
suffixPos = cfg.rfind(suffix)
if suffixPos == cfg - 2:
cfg = cfg[:cfgLen-2]
break
# determine whether we should this bp is active # determine whether we should this bp is active
# based on the value of cfg. # based on the value of cfg.
@ -4457,7 +4457,7 @@ class bp:
dConfigParamList = [] dConfigParamList = []
dConfigParams = choice(isinstance(cfg, (list,tuple)), cfg, (cfg,)) dConfigParams = choice(isinstance(cfg, (list,tuple)), cfg, (cfg,))
dConfigParamList = [param for param in dConfigParams \ dConfigParamList = [param for param in dConfigParams \
if ConfigVariableBool('want-breakpoint-%s' % (param,), 0).getValue()] if ConfigVariableBool('want-bp-%s' % (param,), 0).getValue()]
if not dConfigParamList: if not dConfigParamList:
self.disabled = True self.disabled = True
return return
@ -4483,15 +4483,32 @@ class bp:
if slf: if slf:
className = slf.__class__.__name__ className = slf.__class__.__name__
grp = className grp = className
#default to module
if grp is None:
grp = moduleName
#default name to line number #default name to line number
if name is None: if id is None:
def byteOffsetToLineno(code, byte):
# Returns the source line number corresponding to the given byte
# offset into the indicated Python code module.
import array
lnotab = array.array('B', code.co_lnotab)
line = code.co_firstlineno
for i in range(0, len(lnotab), 2):
byte -= lnotab[i]
if byte <= 0:
return line
line += lnotab[i+1]
return line
if frameCount < len(inspect.stack()): if frameCount < len(inspect.stack()):
lineno = inspect.stack()[frameCount][2] frame = inspect.stack()[frameCount][0]
name = lineno lineno = byteOffsetToLineno(frame.f_code, frame.f_lasti)
id = lineno
#store this breakpoint's settings #store this breakpoint's settings
self.name = name self.id = id
self.grp = grp self.grp = grp
self.cfg = cfg self.cfg = cfg
self.iff = iff self.iff = iff
@ -4500,59 +4517,96 @@ class bp:
bpdb.lastBp = self bpdb.lastBp = self
@staticmethod @staticmethod
def prettyName(name=None, grp=None, cfg=None, q=0): def prettyName(id=None, grp=None, cfg=None, q=0):
prettyName = '' prettyName = ''
prettyName += choice(q, "'", '') prettyName += choice(q, "'", '')
if cfg: if cfg:
prettyName += '%s'%(cfg,) prettyName += '%s'%(cfg,)
if grp or name: if grp or id:
prettyName += '::' prettyName += '::'
if grp: if grp:
prettyName += '%s'%(grp,) prettyName += '%s'%(grp,)
if name: if id:
if isinstance(name, int): if isinstance(id, int):
prettyName += '(%s)'%(name,) prettyName += '(%s)'%(id,)
elif grp: elif grp:
prettyName += '.%s'%(name,) prettyName += '.%s'%(id,)
else: else:
prettyName += '%s'%(name,) prettyName += '%s'%(id,)
prettyName += choice(q, "'", '') prettyName += choice(q, "'", '')
return prettyName return prettyName
def displayContextHint(self, displayPrefix=''): def displayContextHint(self, displayPrefix=''):
contextString = displayPrefix + self.prettyName(name=self.name,grp=self.grp,cfg=self.cfg) contextString = displayPrefix + self.prettyName(id=self.id,grp=self.grp,cfg=self.cfg)
dashes = '-'*max(0, (80 - len(contextString) - 4) / 2) dashes = '-'*max(0, (80 - len(contextString) - 4) / 2)
print '<%s %s %s>'%(dashes,contextString,dashes) print '<%s %s %s>'%(dashes,contextString,dashes)
def enable(self, enabled=True, name=None): def makeIdGrp(self, id, grp):
name = name or self.name bpdb.grpInfos.setdefault(grp, {'__settings__':{},})
self.nameInfos.setdefault(name, {}) bpdb.grpInfos[grp].setdefault(id, {})
self.nameInfos[name]['enabled'] = enabled
def toggle(self, name=None): def parseBPPath(self, arg=None):
name = name or self.name id = None
self.nameInfos.setdefault(name, {}) grp = None
newEnabled = not self.nameInfos[name].get('enabled', True) if arg:
self.nameInfos[name]['enabled'] = newEnabled if not isinstance(arg, type('')):
print '%s is now %s.'%(self.prettyName(name,q=1),choice(newEnabled,'enabled','disabled'),) print "error: argument must be string '[grp.]id'"
return None, None
tokens = arg.split('.')
id = tokens[-1]
if len(tokens) > 1:
grp = tokens[-2]
id = id or bpdb.lastBp.id
grp = grp or bpdb.lastBp.grp
return id, grp
def enable(self, enabled=True, id=None, grp=None):
id = id or bpdb.lastBp.id
grp = grp or bpdb.lastBp.grp
self.makeIdGrp(id,grp)
bpdb.grpInfos[grp][id]['enabled'] = enabled
def toggle(self, arg=None):
id, grp = self.parseBPPath(arg)
self.makeIdGrp(id,grp)
newEnabled = not bpdb.grpInfos[grp][id].get('enabled', True)
bpdb.grpInfos[grp][id]['enabled'] = newEnabled
print '%s is now %s.'%(self.prettyName(id,grp,q=1),choice(newEnabled,'enabled','disabled'),)
def toggleGroup(self, grp=None): def toggleGroup(self, grp=None):
grp = grp or self.grp if grp and not isinstance(grp, type('')):
self.grpInfos.setdefault(grp, {}) print "error: argument must be string 'grp'"
newEnabled = not self.grpInfos[grp].get('enabled', True) return
self.grpInfos[grp]['enabled'] = newEnabled
print 'group %s is now %s.'%(self.prettyName(grp,q=1),choice(newEnabled,'enabled','disabled'),)
def ignore(self, ignoreCount=0, name=None): grp = grp or bpdb.lastBp.grp
name = name or self.name bpdb.grpInfos.setdefault(grp, {'__settings__':{},})
self.nameInfos.setdefault(name, {})
self.nameInfos[name]['ignoreCount'] = ignoreCount
print '%s will ignored %s times.'%(self.prettyName(name,q=1),ignoreCount,)
def reset(self, name=None): newEnabled = not bpdb.grpInfos[grp]['__settings__'].get('enabled', True)
name = name or self.name bpdb.grpInfos[grp]['__settings__']['enabled'] = newEnabled
self.nameInfos[name] = {} print 'group %s is now %s.'%(self.prettyName(grp=grp,q=1),choice(newEnabled,'enabled','disabled'),)
print '%s has been reset.'%(self.prettyName(name,q=1),)
def ignore(self, ignoreCount=0, arg=None):
if not isinstance(ignoreCount, int):
print 'error: first argument should be integer ignoreCount'
return
id, grp = self.parseBPPath(arg)
self.makeIdGrp(id,grp)
bpdb.grpInfos[grp][id]['ignoreCount'] = ignoreCount
print '%s will ignored %s times.'%(self.prettyName(id,grp,q=1),ignoreCount,)
def reset(self, arg=None):
id, grp = self.parseBPPath(arg)
self.makeIdGrp(id,grp)
bpdb.grpInfos[grp][id] = {}
print '%s has been reset.'%(self.prettyName(id,grp,q=1),)
def maybeBreak(self, iff=True, frameCount=1,displayPrefix=''): def maybeBreak(self, iff=True, frameCount=1,displayPrefix=''):
if self.shouldBreak(iff): if self.shouldBreak(iff):
@ -4566,27 +4620,26 @@ class bp:
return False return False
#make sure we exist #make sure we exist
bp.grpInfos.setdefault(self.grp, {}) self.makeIdGrp(self.id,self.grp)
bp.nameInfos.setdefault(self.name, {})
#check disabled conditions #check disabled conditions
if not bp.grpInfos[self.grp].get('enabled', True): if not bpdb.grpInfos[self.grp]['__settings__'].get('enabled', True):
return False return False
if not bp.nameInfos[self.name].get('enabled', True): if not bpdb.grpInfos[self.grp][self.id].get('enabled', True):
return False return False
if self.cfg: if self.cfg:
dConfigParamList = [] dConfigParamList = []
dConfigParams = choice(isinstance(self.cfg, (list,tuple)), self.cfg, (self.cfg,)) dConfigParams = choice(isinstance(self.cfg, (list,tuple)), self.cfg, (self.cfg,))
dConfigParamList = [param for param in dConfigParams \ dConfigParamList = [param for param in dConfigParams \
if ConfigVariableBool('want-breakpoint-%s' % (param,), 0).getValue()] if ConfigVariableBool('want-bp-%s' % (param,), 0).getValue()]
if not dConfigParamList: if not dConfigParamList:
return False return False
#check skip conditions #check skip conditions
if bp.nameInfos[self.name].get('ignore', 0) > 0: if bpdb.grpInfos[self.grp][self.id].get('ignoreCount', 0) > 0:
bp.nameInfos[self.name]['ignoreCount'] -= 1 bpdb.grpInfos[self.grp][self.id]['ignoreCount'] -= 1
return False return False
if bp.nameInfos[self.name].get('lifetime', -1) == 0: if bpdb.grpInfos[self.grp][self.id].get('lifetime', -1) == 0:
return False return False
#all conditions go #all conditions go
@ -4594,13 +4647,12 @@ class bp:
def doBreak(self, frameCount=1,displayPrefix=''): def doBreak(self, frameCount=1,displayPrefix=''):
#make sure we exist #make sure we exist
bp.grpInfos.setdefault(self.grp, {}) self.makeIdGrp(self.id,self.grp)
bp.nameInfos.setdefault(self.name, {})
#accumulate hit count #accumulate hit count
if 'lifetime' in bp.nameInfos[self.name]: if 'lifetime' in bpdb.grpInfos[self.grp][self.id]:
bp.nameInfos[self.name]['lifetime'] -= 1 bpdb.grpInfos[self.grp][self.id]['lifetime'] -= 1
bp.nameInfos[self.name]['count'] = bp.nameInfos[self.name].get('count', 0) + 1 bpdb.grpInfos[self.grp][self.id]['count'] = bpdb.grpInfos[self.grp][self.id].get('count', 0) + 1
#setup debugger #setup debugger
self.displayContextHint(displayPrefix=displayPrefix) self.displayContextHint(displayPrefix=displayPrefix)