231 |
230 |
232 This specialty is to check the connection to the debug server |
231 This specialty is to check the connection to the debug server |
233 for new events (i.e. new breakpoints) while we are going through |
232 for new events (i.e. new breakpoints) while we are going through |
234 the code. |
233 the code. |
235 |
234 |
236 @param frame The current stack frame. |
235 @param frame The current stack frame |
237 @param event The trace event (string) |
236 @type frame object |
|
237 @param event The trace event |
|
238 @type str |
238 @param arg The arguments |
239 @param arg The arguments |
|
240 @type depends on the previous event parameter |
239 @return local trace function |
241 @return local trace function |
|
242 @rtype trace function or None |
|
243 @exception bdb.BdbQuit |
240 """ |
244 """ |
241 if self.quitting: |
245 if self.quitting: |
242 return # None |
246 return # None |
243 |
247 |
244 # give the client a chance to push through new break points. |
248 # give the client a chance to push through new break points. |
245 self._dbgClient.eventPoll() |
249 self._dbgClient.eventPoll() |
246 |
250 |
247 self.__event == event |
|
248 self.__isBroken = False |
|
249 |
|
250 if event == 'line': |
251 if event == 'line': |
251 return self.dispatch_line(frame) |
252 if self.stop_here(frame) or self.break_here(frame): |
|
253 self.user_line(frame) |
|
254 if self.quitting: |
|
255 raise bdb.BdbQuit |
|
256 return |
|
257 |
252 if event == 'call': |
258 if event == 'call': |
253 return self.dispatch_call(frame, arg) |
259 if self.botframe is None: |
254 if event == 'return': |
260 # First call of dispatch since reset() |
255 return self.dispatch_return(frame, arg) |
261 # (CT) Note that this may also be None! |
256 if event == 'exception': |
262 self.botframe = frame.f_back |
257 return self.dispatch_exception(frame, arg) |
263 return self.trace_dispatch |
258 if event == 'c_call': |
264 |
259 return self.trace_dispatch |
265 if not (self.stop_here(frame) or self.break_anywhere(frame)): |
260 if event == 'c_exception': |
266 # No need to trace this function |
261 return self.trace_dispatch |
267 return |
262 if event == 'c_return': |
|
263 return self.trace_dispatch |
|
264 print('bdb.Bdb.dispatch: unknown debugging event: ', repr(event)) # __IGNORE_WARNING__ |
|
265 return self.trace_dispatch |
|
266 |
|
267 def dispatch_line(self, frame): |
|
268 """ |
|
269 Public method reimplemented from bdb.py to do some special things. |
|
270 |
|
271 This speciality is to check the connection to the debug server |
|
272 for new events (i.e. new breakpoints) while we are going through |
|
273 the code. |
|
274 |
|
275 @param frame The current stack frame. |
|
276 @return local trace function |
|
277 @exception bdb.BdbQuit raised to indicate the end of the debug session |
|
278 """ |
|
279 if self.stop_here(frame) or self.break_here(frame): |
|
280 self.user_line(frame) |
|
281 if self.quitting: |
268 if self.quitting: |
282 raise bdb.BdbQuit |
269 raise bdb.BdbQuit |
283 return self.trace_dispatch |
270 return self.trace_dispatch |
284 |
271 |
285 def dispatch_return(self, frame, arg): |
272 if event == 'return': |
286 """ |
273 if self.stop_here(frame) or frame == self.returnframe: |
287 Public method reimplemented from bdb.py to handle passive mode cleanly. |
274 # Ignore return events in generator except when stepping. |
288 |
275 if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: |
289 @param frame The current stack frame. |
276 return |
290 @param arg The arguments |
277 # The program has finished if we have just left the first frame |
291 @return local trace function |
278 if frame == self._dbgClient.mainFrame and \ |
292 @exception bdb.BdbQuit raised to indicate the end of the debug session |
279 self._mainThread: |
293 """ |
280 atexit._run_exitfuncs() |
294 if self.stop_here(frame) or frame == self.returnframe: |
281 self._dbgClient.progTerminated(arg) |
295 # Ignore return events in generator except when stepping. |
282 elif frame is not self.stepFrame: |
296 if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: |
283 self.stepFrame = None |
297 return self.trace_dispatch |
284 self.user_line(frame) |
298 self.user_return(frame, arg) |
285 |
299 if self.quitting and not self._dbgClient.passive: |
286 if self.quitting and not self._dbgClient.passive: |
300 raise bdb.BdbQuit |
287 raise bdb.BdbQuit |
301 return self.trace_dispatch |
288 return |
302 |
289 |
303 def dispatch_exception(self, frame, arg): |
290 if event == 'exception': |
304 """ |
291 if not self.__skipFrame(frame): |
305 Public method reimplemented from bdb.py to always call user_exception. |
292 # When stepping with next/until/return in a generator frame, |
306 |
293 # skip the internal StopIteration exception (with no traceback) |
307 @param frame The current stack frame. |
294 # triggered by a subiterator run with the 'yield from' |
308 @param arg The arguments |
295 # statement. |
309 @return local trace function |
296 if not (frame.f_code.co_flags & CO_GENERATOR and |
310 @exception bdb.BdbQuit raised to indicate the end of the debug session |
297 arg[0] is StopIteration and arg[2] is None): |
311 """ |
298 self.user_exception(frame, arg) |
312 if not self.__skipFrame(frame): |
299 if self.quitting: |
313 # When stepping with next/until/return in a generator frame, |
300 raise bdb.BdbQuit |
314 # skip the internal StopIteration exception (with no traceback) |
301 # Stop at the StopIteration or GeneratorExit exception when the user |
315 # triggered by a subiterator run with the 'yield from' |
302 # has set stopframe in a generator by issuing a return command, or a |
316 # statement. |
303 # next/until command at the last statement in the generator before the |
317 if not (frame.f_code.co_flags & CO_GENERATOR and |
304 # exception. |
318 arg[0] is StopIteration and arg[2] is None): |
305 elif (self.stopframe and frame is not self.stopframe and |
|
306 self.stopframe.f_code.co_flags & CO_GENERATOR and |
|
307 arg[0] in (StopIteration, GeneratorExit)): |
319 self.user_exception(frame, arg) |
308 self.user_exception(frame, arg) |
320 if self.quitting: |
309 if self.quitting: |
321 raise bdb.BdbQuit |
310 raise bdb.BdbQuit |
322 # Stop at the StopIteration or GeneratorExit exception when the user |
311 return |
323 # has set stopframe in a generator by issuing a return command, or a |
312 |
324 # next/until command at the last statement in the generator before the |
313 if event == 'c_call': |
325 # exception. |
314 return |
326 elif (self.stopframe and frame is not self.stopframe and |
315 if event == 'c_exception': |
327 self.stopframe.f_code.co_flags & CO_GENERATOR and |
316 return |
328 arg[0] in (StopIteration, GeneratorExit)): |
317 if event == 'c_return': |
329 self.user_exception(frame, arg) |
318 return |
330 if self.quitting: |
319 print('bdb.Bdb.dispatch: unknown debugging event: ', repr(event)) # __IGNORE_WARNING__ |
331 raise bdb.BdbQuit |
|
332 |
|
333 return self.trace_dispatch |
320 return self.trace_dispatch |
334 |
321 |
335 def set_trace(self, frame=None): |
322 def set_trace(self, frame=None): |
336 """ |
323 """ |
337 Public method reimplemented from bdb.py to do some special setup. |
324 Public method reimplemented from bdb.py to do some special setup. |