@@ -24,45 +24,56 @@ def __getitem__(self, id):
2424
2525 def __call__ (self , * args ):
2626 rawbp = DebugBreakpoint (args [0 ])
27+ bpid = rawbp .GetId ()
28+
2729 try :
28- bpfn = self .__getitem__ (rawbp . GetId () )
30+ ( count , bpfn ) = self .__getitem__ (bpid )
2931 except KeyError :
32+ count = 0
3033 bpfn = None
3134 if bpfn :
3235 ret = bpfn (rawbp )
3336 else :
3437 ret = DbgEng .DEBUG_STATUS_NO_CHANGE
3538
36- if rawbp . GetFlags () & DbgEng . DEBUG_BREAKPOINT_ONE_SHOT :
37- self . _bp . pop ( rawbp . GetId (), None )
38- self . _control . RemoveBreakpoint ( rawbp )
39-
39+ count -= 1
40+ if count == 0 :
41+ # We can disable here and but not delete
42+ rawbp . RemoveFlags ( DbgEng . DEBUG_BREAKPOINT_ENABLED )
4043 return ret
4144
4245 def set (self , expr , handler = None , type = None , windbgcmd = None , oneshot = False ,
43- passcount = None , threadid = None , size = None , access = None ):
44- # XXX - would be nice to check if bp with expr already exists
45- # if so, then enable existing, else add
46- if type is None :
47- type = DbgEng .DEBUG_BREAKPOINT_CODE
48- if isinstance (expr , int ):
49- expr = b"0x%x" % expr
50- elif isinstance (expr , str ):
51- expr = expr .encode ()
52- bp = self ._control .AddBreakpoint (type )
53- id = bp .GetId ()
54- bp .SetOffsetExpression (expr )
55- if windbgcmd :
56- pass
46+ passcount = None , threadid = None , size = None , access = None ,
47+ count = 0xffffffff ):
48+
49+ existingid = self .find (expr )
50+ if existingid != - 1 :
51+ # Just enable
52+ self .enable (existingid )
53+ return
54+ else :
55+ if type is None :
56+ type = DbgEng .DEBUG_BREAKPOINT_CODE
57+ if isinstance (expr , int ):
58+ expr = b"0x%x" % expr
59+ elif isinstance (expr , str ):
60+ expr = expr .encode ()
61+ bp = self ._control .AddBreakpoint (type )
62+ id = bp .GetId ()
63+ bp .SetOffsetExpression (expr )
64+ if windbgcmd :
65+ pass
66+ if type == DbgEng .DEBUG_BREAKPOINT_DATA :
67+ bp .SetDataParameters (size , access )
5768 if passcount is not None :
5869 bp .SetPassCount (passcount )
5970 if threadid :
6071 bp .SetMatchThreadId (threadid )
61- if type == DbgEng .DEBUG_BREAKPOINT_DATA :
62- bp .SetDataParameters (size , access )
6372 if oneshot :
64- bp .AddFlags (DbgEng .DEBUG_BREAKPOINT_ONE_SHOT )
65- self ._bp [id ] = handler
73+ count = 1
74+ # comtypes can't properly handle true one shot
75+ #bp.AddFlags(DbgEng.DEBUG_BREAKPOINT_ONE_SHOT)
76+ self ._bp [id ] = (count ,handler )
6677 if not bp .GetFlags () & DbgEng .DEBUG_BREAKPOINT_DEFERRED :
6778 self .enable (id )
6879 return id
@@ -98,3 +109,45 @@ def remove_all(self):
98109 for bpid in self :
99110 self .remove (bpid )
100111
112+ def find_id (self , fid ):
113+ for bpid in self :
114+ if bpid == fid :
115+ return fid
116+ return - 1
117+
118+ def find_expr (self , expr ):
119+ ids = [bpid for bpid in self ]
120+ for bpid in ids :
121+ try :
122+ bp = self ._control .GetBreakpointById (bpid )
123+ except exception .E_NOINTERFACE_Error :
124+ self .breakpoints ._remove_stale (bpid )
125+ continue
126+
127+ bpexpr = bp .GetOffsetExpression ()
128+ print (bpexpr )
129+ #expr = self.get_name_by_offset(bp.GetOffset())
130+ if bpexpr == expr :
131+ return bpid
132+ return - 1
133+
134+ def find_offset (self , offset ):
135+ ids = [bpid for bpid in self ]
136+ for bpid in ids :
137+ try :
138+ bp = self ._control .GetBreakpointById (bpid )
139+ except exception .E_NOINTERFACE_Error :
140+ self .breakpoints ._remove_stale (bpid )
141+ continue
142+
143+ bpoff = bp .GetOffset ()
144+ if bpoff == offset :
145+ return bpid
146+ return - 1
147+
148+
149+ def find (self , expr ):
150+ bpid = self .find_expr (expr )
151+ if bpid == - 1 :
152+ bpid = self .find_offset (expr )
153+ return bpid
0 commit comments