DebugClients/Python/DebugBase.py

branch
debugger speed
changeset 5209
cd058aa6af37
parent 5208
aa8045780ce4
child 5221
960afd19c1b6
equal deleted inserted replaced
5208:aa8045780ce4 5209:cd058aa6af37
72 72
73 @param dbgClient the owning client 73 @param dbgClient the owning client
74 """ 74 """
75 self._dbgClient = dbgClient 75 self._dbgClient = dbgClient
76 76
77 self._mainThread = True 77 # Some informations about the thread
78 self.isMainThread = False
78 self.quitting = False 79 self.quitting = False
79 self.id = -1 80 self.id = -1
80 self.name = '' 81 self.name = ''
81 82
82 self.tracePythonLibs(0) 83 self.tracePythonLibs(0)
319 if self.stop_here(frame) or frame == self.botframe: 320 if self.stop_here(frame) or frame == self.botframe:
320 # Ignore return events in generator except when stepping. 321 # Ignore return events in generator except when stepping.
321 if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: 322 if self.stopframe and frame.f_code.co_flags & CO_GENERATOR:
322 return 323 return
323 # The program has finished if we have just left the first frame 324 # The program has finished if we have just left the first frame
324 if (frame == self.botframe and 325 if frame == self.botframe:
325 self._mainThread): 326 if self.isMainThread:
326 atexit._run_exitfuncs() 327 atexit._run_exitfuncs()
327 self._dbgClient.progTerminated(arg) 328 self._dbgClient.progTerminated(arg)
329 else:
330 self._dbgClient.threadTerminated(self.id)
328 331
329 if self.quitting and not self._dbgClient.passive: 332 if self.quitting and not self._dbgClient.passive:
330 raise SystemExit 333 raise SystemExit
331 return 334 return
332 335
382 stopOnHandleLine = self._dbgClient.handleLine.__code__ 385 stopOnHandleLine = self._dbgClient.handleLine.__code__
383 bootstrap = 'bootstrap' 386 bootstrap = 'bootstrap'
384 387
385 frame.f_trace = self.trace_dispatch 388 frame.f_trace = self.trace_dispatch
386 while frame is not None: 389 while frame is not None:
387 # stop at erics debugger frame 390 # stop at erics debugger frame or the threading bootstrap
388 if frame.f_back.f_code == stopOnHandleLine: 391 if (frame.f_back.f_code == stopOnHandleLine or
392 frame.f_back.f_code.co_name == bootstrap):
389 frame.f_trace = self.trace_dispatch 393 frame.f_trace = self.trace_dispatch
390 self.botframe = frame 394 self.botframe = frame
391 break 395 break
392 396
393 frame = frame.f_back 397 frame = frame.f_back
394 398
395 self.stop_everywhere = True 399 self.stop_everywhere = True
396 sys.settrace(self.trace_dispatch) 400 sys.settrace(self.trace_dispatch)
397 sys.setprofile(self._dbgClient.callTraceEnabled) 401 sys.setprofile(self._dbgClient.callTraceEnabled)
398 402
399 def bootstrap(self): 403 def bootstrap(self, target, args, kwargs):
400 """ 404 """
401 Public method to bootstrap the thread. 405 Public method to bootstrap a thread.
402 406
403 It wraps the call to the user function to enable tracing 407 It wraps the call to the user function to enable tracing
404 before hand. 408 before hand.
409
410 @param target function which is called in the new created thread
411 @type function pointer
412 @param args arguments to pass to target
413 @type tuple
414 @param kwargs keyword arguments to pass to target
415 @type dict
405 """ 416 """
406 try: 417 try:
407 self._threadRunning = True 418 frame = sys._getframe()
408 self.traceThread() 419 self.botframe = frame
409 self._target(*self._args, **self._kwargs) 420 # First time the dispach function is called, a "base debug"
421 # function has to be returned, which is called at every user code
422 # function call. Because of setting botframe manually, the
423 # specific branch returning the trace_dispatch itself is skipped.
424 # Because the next step is always in threading.py and we assume
425 # that there is no breakpoint in it, it's save to return
426 # trace_dispatch unconditionally.
427 sys.settrace(lambda frame, event, arg: self.trace_dispatch)
428 frame.f_trace = self.trace_dispatch
429
430 target(*args, **kwargs)
410 except SystemExit: 431 except SystemExit:
411 pass 432 pass
412 finally: 433 finally:
413 self._threadRunning = False
414 self.quitting = True
415 self._dbgClient.threadTerminated(self)
416 sys.settrace(None)
417 sys.setprofile(None) 434 sys.setprofile(None)
418 435
419 def run(self, cmd, globals=None, locals=None): 436 def run(self, cmd, globals=None, locals=None):
420 """ 437 """
421 Public method to start a given command under debugger control. 438 Public method to start a given command under debugger control.

eric ide

mercurial