84 # current frame we are at |
85 # current frame we are at |
85 self.currentFrame = None |
86 self.currentFrame = None |
86 |
87 |
87 # frame that we are stepping in, can be different than currentFrame |
88 # frame that we are stepping in, can be different than currentFrame |
88 self.stepFrame = None |
89 self.stepFrame = None |
|
90 |
|
91 self.botframe = None |
|
92 self.stopframe = None |
|
93 self.returnframe = None |
|
94 self.stop_everywhere = False |
89 |
95 |
90 # provide a hook to perform a hard breakpoint |
96 # provide a hook to perform a hard breakpoint |
91 # Use it like this: |
97 # Use it like this: |
92 # if hasattr(sys, 'breakpoint): sys.breakpoint() |
98 # if hasattr(sys, 'breakpoint): sys.breakpoint() |
93 sys.breakpoint = self.set_trace |
99 sys.breakpoint = self.set_trace |
291 if self.stop_here(frame) or self.break_here(frame): |
297 if self.stop_here(frame) or self.break_here(frame): |
292 self.user_line(frame) |
298 self.user_line(frame) |
293 return |
299 return |
294 |
300 |
295 if event == 'call': |
301 if event == 'call': |
296 if self.botframe is None: |
302 if self.botframe is None and frame.f_lineno > 1: |
297 # First call of dispatch since reset() |
|
298 # (CT) Note that this may also be None! |
|
299 self.botframe = frame.f_back |
303 self.botframe = frame.f_back |
|
304 frame.f_trace = self.trace_dispatch |
|
305 self._dbgClient.mainFrame = frame |
|
306 |
|
307 self.user_line(frame) |
300 return self.trace_dispatch |
308 return self.trace_dispatch |
301 |
309 |
302 if not (self.stop_here(frame) or |
310 if not (self.stop_here(frame) or |
303 self.__checkBreakInFrame(frame) or |
311 self.__checkBreakInFrame(frame) or |
304 Watch.watches != []): |
312 Watch.watches != []): |
305 # No need to trace this function |
313 # No need to trace this function |
306 return |
314 return |
307 return self.trace_dispatch |
315 return self.trace_dispatch |
308 |
316 |
309 if event == 'return': |
317 if event == 'return': |
310 if self.stop_here(frame) or frame == self.returnframe: |
318 if self.stop_here(frame): |
311 # Ignore return events in generator except when stepping. |
319 # Ignore return events in generator except when stepping. |
312 if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: |
320 if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: |
313 return |
321 return |
314 # The program has finished if we have just left the first frame |
322 # The program has finished if we have just left the first frame |
315 if frame == self._dbgClient.mainFrame and \ |
323 if frame == self._dbgClient.mainFrame and \ |
316 self._mainThread: |
324 self._mainThread: |
317 atexit._run_exitfuncs() |
325 atexit._run_exitfuncs() |
318 self._dbgClient.progTerminated(arg) |
326 self._dbgClient.progTerminated(arg) |
319 elif frame is not self.stepFrame: |
327 |
320 self.stepFrame = None |
|
321 self.user_line(frame) |
|
322 |
|
323 if self.quitting and not self._dbgClient.passive: |
328 if self.quitting and not self._dbgClient.passive: |
324 raise SystemExit |
329 raise SystemExit |
325 return |
330 return |
326 |
331 |
327 if event == 'exception': |
332 if event == 'exception': |
405 pass |
410 pass |
406 finally: |
411 finally: |
407 self.quitting = 1 |
412 self.quitting = 1 |
408 sys.settrace(None) |
413 sys.settrace(None) |
409 |
414 |
|
415 def _set_stopinfo(self, stopframe, returnframe): |
|
416 """ |
|
417 Protected method to update the frame pointers. |
|
418 |
|
419 @param stopframe the frame object where to stop |
|
420 @type frame object |
|
421 @param returnframe the frame object where to stop on a function return |
|
422 @type frame object |
|
423 """ |
|
424 self.stopframe = stopframe |
|
425 self.returnframe = returnframe |
|
426 self.stop_everywhere = False |
|
427 |
410 def set_continue(self, special): |
428 def set_continue(self, special): |
411 """ |
429 """ |
412 Public method reimplemented from bdb.py to always get informed of |
430 Public method to stop only on next breakpoint. |
413 exceptions. |
|
414 |
431 |
415 @param special flag indicating a special continue operation |
432 @param special flag indicating a special continue operation |
416 """ |
433 @type bool |
417 # Modified version of the one found in bdb.py |
434 """ |
418 # Here we only set a new stop frame if it is a normal continue. |
435 # Here we only set a new stop frame if it is a normal continue. |
419 if not special: |
436 if not special: |
420 self._set_stopinfo(self.botframe, None) |
437 self._set_stopinfo(self.botframe, None) |
|
438 |
421 # Disable tracing if not started in debug mode |
439 # Disable tracing if not started in debug mode |
422 if not self._dbgClient.debugging: |
440 if not self._dbgClient.debugging: |
423 sys.settrace(None) |
441 sys.settrace(None) |
424 sys.setprofile(None) |
442 sys.setprofile(None) |
|
443 |
|
444 def set_step(self): |
|
445 """ |
|
446 Public method to stop after one line of code. |
|
447 """ |
|
448 self._set_stopinfo(None, None) |
|
449 self.stop_everywhere = True |
425 |
450 |
426 def set_quit(self): |
451 def set_quit(self): |
427 """ |
452 """ |
428 Public method to quit. |
453 Public method to quit. |
429 |
454 |
830 |
855 |
831 Tracing is turned off for files that are part of the |
856 Tracing is turned off for files that are part of the |
832 debugger that are called from the application being debugged. |
857 debugger that are called from the application being debugged. |
833 |
858 |
834 @param frame the frame object |
859 @param frame the frame object |
|
860 @type frame object |
835 @return flag indicating whether the debugger should stop here |
861 @return flag indicating whether the debugger should stop here |
|
862 @rtype bool |
836 """ |
863 """ |
837 if self.__skipFrame(frame): |
864 if self.__skipFrame(frame): |
838 return False |
865 return False |
839 |
866 |
840 return bdb.Bdb.stop_here(self, frame) |
867 return (self.stop_everywhere or |
|
868 frame is self.stopframe or |
|
869 frame is self.returnframe or |
|
870 frame is self.botframe) |
841 |
871 |
842 def tracePythonLibs(self, enable): |
872 def tracePythonLibs(self, enable): |
843 """ |
873 """ |
844 Public method to update the settings to trace into Python libraries. |
874 Public method to update the settings to trace into Python libraries. |
845 |
875 |