90 |
90 |
91 # current frame we are at |
91 # current frame we are at |
92 self.currentFrame = None |
92 self.currentFrame = None |
93 |
93 |
94 # frames, where we want to stop or release debugger |
94 # frames, where we want to stop or release debugger |
95 self.botframe = None |
|
96 self.stopframe = None |
95 self.stopframe = None |
97 self.returnframe = None |
96 self.returnframe = None |
98 self.stop_everywhere = False |
97 self.stop_everywhere = False |
99 |
98 |
100 self.__recursionDepth = -1 |
99 self.__recursionDepth = -1 |
310 if self.stop_here(frame) or self.break_here(frame): |
309 if self.stop_here(frame) or self.break_here(frame): |
311 self.user_line(frame) |
310 self.user_line(frame) |
312 return self.trace_dispatch |
311 return self.trace_dispatch |
313 |
312 |
314 if event == 'call': |
313 if event == 'call': |
315 if self.botframe is None and frame.f_lineno >= 1: |
314 if (self.stop_here(frame) or |
316 self.botframe = frame |
|
317 frame.f_trace = self.trace_dispatch |
|
318 |
|
319 self.user_line(frame) |
|
320 return self.trace_dispatch |
|
321 |
|
322 if not (self.stop_here(frame) or |
|
323 self.__checkBreakInFrame(frame) or |
315 self.__checkBreakInFrame(frame) or |
324 Watch.watches != []): |
316 Watch.watches != []): |
|
317 return self.trace_dispatch |
|
318 else: |
325 # No need to trace this function |
319 # No need to trace this function |
326 return |
320 return |
327 return self.trace_dispatch |
|
328 |
321 |
329 if event == 'return': |
322 if event == 'return': |
330 return |
323 return |
331 |
324 |
332 if event == 'exception': |
325 if event == 'exception': |
382 frame.f_trace = self.trace_dispatch |
375 frame.f_trace = self.trace_dispatch |
383 while frame.f_back is not None: |
376 while frame.f_back is not None: |
384 # stop at erics debugger frame or a threading bootstrap |
377 # stop at erics debugger frame or a threading bootstrap |
385 if (frame.f_back.f_code == stopOnHandleLine): |
378 if (frame.f_back.f_code == stopOnHandleLine): |
386 frame.f_trace = self.trace_dispatch |
379 frame.f_trace = self.trace_dispatch |
387 self.botframe = frame |
|
388 break |
380 break |
389 |
381 |
390 frame = frame.f_back |
382 frame = frame.f_back |
391 |
383 |
392 self.stop_everywhere = True |
384 self.stop_everywhere = True |
406 @type tuple |
398 @type tuple |
407 @param kwargs keyword arguments to pass to target |
399 @param kwargs keyword arguments to pass to target |
408 @type dict |
400 @type dict |
409 """ |
401 """ |
410 try: |
402 try: |
411 frame = sys._getframe() |
403 # Because in the initial run method the "base debug" function is |
412 self.botframe = frame |
404 # set up, it's also valid for the threads afterwards. |
413 # First time the dispach function is called, a "base debug" |
405 sys.settrace(self.trace_dispatch) |
414 # function has to be returned, which is called at every user code |
|
415 # function call. Because of setting botframe manually, the |
|
416 # specific branch returning the trace_dispatch itself is skipped. |
|
417 # Because the next step is always in threading.py and we assume |
|
418 # that there is no breakpoint in it, it's save to return |
|
419 # trace_dispatch unconditionally. |
|
420 sys.settrace(lambda frame, event, arg: self.trace_dispatch) |
|
421 frame.f_trace = self.trace_dispatch |
|
422 |
406 |
423 target(*args, **kwargs) |
407 target(*args, **kwargs) |
424 except Exception: |
408 except Exception: |
425 excinfo = sys.exc_info() |
409 excinfo = sys.exc_info() |
426 self.user_exception(excinfo, True) |
410 self.user_exception(excinfo, True) |
448 |
432 |
449 if not isinstance(cmd, types.CodeType): |
433 if not isinstance(cmd, types.CodeType): |
450 cmd = compile(cmd, "<string>", "exec") |
434 cmd = compile(cmd, "<string>", "exec") |
451 |
435 |
452 if debug: |
436 if debug: |
|
437 # First time the trace_dispatch function is called, a "base debug" |
|
438 # function has to be returned, which is called at every user code |
|
439 # function call. This is ensured by setting stop_everywhere. |
|
440 self.stop_everywhere = True |
453 sys.settrace(self.trace_dispatch) |
441 sys.settrace(self.trace_dispatch) |
454 |
442 |
455 try: |
443 try: |
456 exec(cmd, globals, locals) |
444 exec(cmd, globals, locals) |
457 atexit._run_exitfuncs() |
445 atexit._run_exitfuncs() |