DebugClients/Python/DebugBase.py

branch
debugger speed
changeset 5005
684f5ba04f0b
parent 4683
1ba6ba86b383
child 5007
e2fa12bb0f53
equal deleted inserted replaced
5004:556528860c7a 5005:684f5ba04f0b
46 Class implementing base class of the debugger. 46 Class implementing base class of the debugger.
47 47
48 Provides simple wrapper methods around bdb for the 'owning' client to 48 Provides simple wrapper methods around bdb for the 'owning' client to
49 call to step etc. 49 call to step etc.
50 """ 50 """
51 # Don't thrust distutils.sysconfig.get_python_lib: possible case mismatch
52 # on Windows
53 lib = os.path.dirname(bdb.__file__)
54 # tuple required because it's accessed a lot of times by startswith method
55 pathsToSkip = ('<', os.path.dirname(__file__), bdb.__file__[:-1])
56 filesToSkip = {}
57
51 def __init__(self, dbgClient): 58 def __init__(self, dbgClient):
52 """ 59 """
53 Constructor 60 Constructor
54 61
55 @param dbgClient the owning client 62 @param dbgClient the owning client
58 65
59 self._dbgClient = dbgClient 66 self._dbgClient = dbgClient
60 self._mainThread = 1 67 self._mainThread = 1
61 68
62 self.breaks = self._dbgClient.breakpoints 69 self.breaks = self._dbgClient.breakpoints
70 self.tracePythonLibs(0)
63 71
64 self.__event = "" 72 self.__event = ""
65 self.__isBroken = "" 73 self.__isBroken = ""
66 self.cFrame = None 74 self.cFrame = None
67 75
195 @param event trace event (string) 203 @param event trace event (string)
196 @param fromFrame originating frame (frame) 204 @param fromFrame originating frame (frame)
197 @param toFrame destination frame (frame) 205 @param toFrame destination frame (frame)
198 """ 206 """
199 if self._dbgClient.callTraceEnabled: 207 if self._dbgClient.callTraceEnabled:
200 if not self.__skip_it(fromFrame) and not self.__skip_it(toFrame): 208 if (not self.__skipFrame(fromFrame) and
209 not self.__skipFrame(toFrame)):
201 if event in ["call", "return"]: 210 if event in ["call", "return"]:
202 fr = fromFrame 211 fr = fromFrame
203 fromStr = "%s:%s:%s" % ( 212 fromStr = "%s:%s:%s" % (
204 self._dbgClient.absPath(self.fix_frame_filename(fr)), 213 self._dbgClient.absPath(self.fix_frame_filename(fr)),
205 fr.f_lineno, 214 fr.f_lineno,
246 return self.trace_dispatch 255 return self.trace_dispatch
247 if event == 'c_exception': 256 if event == 'c_exception':
248 return self.trace_dispatch 257 return self.trace_dispatch
249 if event == 'c_return': 258 if event == 'c_return':
250 return self.trace_dispatch 259 return self.trace_dispatch
251 print 'DebugBase.trace_dispatch: unknown debugging event:', repr(event) # __IGNORE_WARNING__ 260 print 'DebugBase.trace_dispatch: unknown debugging event:', repr(event) # __IGNORE_WARNING__
252 return self.trace_dispatch 261 return self.trace_dispatch
253 262
254 def dispatch_line(self, frame): 263 def dispatch_line(self, frame):
255 """ 264 """
256 Public method reimplemented from bdb.py to do some special things. 265 Public method reimplemented from bdb.py to do some special things.
291 @param frame The current stack frame. 300 @param frame The current stack frame.
292 @param arg The arguments 301 @param arg The arguments
293 @return local trace function 302 @return local trace function
294 @exception bdb.BdbQuit raised to indicate the end of the debug session 303 @exception bdb.BdbQuit raised to indicate the end of the debug session
295 """ 304 """
296 if not self.__skip_it(frame): 305 if not self.__skipFrame(frame):
297 self.user_exception(frame, arg) 306 self.user_exception(frame, arg)
298 if self.quitting: 307 if self.quitting:
299 raise bdb.BdbQuit 308 raise bdb.BdbQuit
300 return self.trace_dispatch 309 return self.trace_dispatch
301 310
532 a particular line. 541 a particular line.
533 542
534 Because eric6 supports only one breakpoint per line, this overwritten 543 Because eric6 supports only one breakpoint per line, this overwritten
535 method will return this one and only breakpoint. 544 method will return this one and only breakpoint.
536 545
537 @param filename filename of the bp to retrieve (string) 546 @param filename the filename of the bp to retrieve (string)
538 @param lineno linenumber of the bp to retrieve (integer) 547 @param lineno the linenumber of the bp to retrieve (integer)
539 @return breakpoint or None, if there is no bp 548 @return breakpoint or None, if there is no bp
540 """ 549 """
541 filename = self.canonic(filename) 550 filename = self.canonic(filename)
542 return filename in self.breaks and \ 551 return filename in self.breaks and \
543 lineno in self.breaks[filename] and \ 552 lineno in self.breaks[filename] and \
770 tb = None 779 tb = None
771 return stack 780 return stack
772 781
773 def user_return(self, frame, retval): 782 def user_return(self, frame, retval):
774 """ 783 """
775 Public method reimplemented to report program termination to the 784 Public method reimplemented to report program termination to the debug
776 debug server. 785 server.
777 786
778 @param frame the frame object 787 @param frame the frame object
779 @param retval the return value of the program 788 @param retval the return value of the program
780 """ 789 """
781 # The program has finished if we have just left the first frame. 790 # The program has finished if we have just left the first frame.
795 debugger that are called from the application being debugged. 804 debugger that are called from the application being debugged.
796 805
797 @param frame the frame object 806 @param frame the frame object
798 @return flag indicating whether the debugger should stop here 807 @return flag indicating whether the debugger should stop here
799 """ 808 """
800 if self.__skip_it(frame): 809 if self.__skipFrame(frame):
801 return 0 810 return 0
802 return bdb.Bdb.stop_here(self, frame) 811 return bdb.Bdb.stop_here(self, frame)
803 812
804 def __skip_it(self, frame): 813 def tracePythonLibs(self, enable):
814 """
815 Public methode to update the settings to trace into Python libraries.
816
817 @param enable let's debug into Python libraries (int)
818 """
819 pathsToSkip = list(self.pathsToSkip)
820 # don't trace into Python library?
821 if enable:
822 pathsToSkip = [x for x in pathsToSkip if not x.endswith(
823 ("site-packages", "dist-packages", self.lib))]
824 else:
825 pathsToSkip.append(self.lib)
826 localLib = [x for x in sys.path if x.endswith(("site-packages",
827 "dist-packages")) and not x.startswith(self.lib)]
828 pathsToSkip.extend(localLib)
829
830 self.pathsToSkip = tuple(pathsToSkip)
831
832 def __skipFrame(self, frame):
805 """ 833 """
806 Private method to filter out debugger files. 834 Private method to filter out debugger files.
807 835
808 Tracing is turned off for files that are part of the 836 Tracing is turned off for files that are part of the
809 debugger that are called from the application being debugged. 837 debugger that are called from the application being debugged.
810 838
811 @param frame the frame object 839 @param frame the frame object
812 @return flag indicating whether the debugger should skip this frame 840 @return flag indicating whether the debugger should skip this frame
813 """ 841 """
814 if frame is None: 842 try:
815 return 1 843 return self.filesToSkip[frame.f_code.co_filename]
816 844 except KeyError:
817 fn = self.fix_frame_filename(frame) 845 ret = frame.f_code.co_filename.startswith(self.pathsToSkip)
818 846 self.filesToSkip[frame.f_code.co_filename] = ret
819 # Eliminate things like <string> and <stdin>. 847 return ret
820 if fn[0] == '<': 848 except AttributeError:
821 return 1 849 # if frame is None
822 850 return True
823 #XXX - think of a better way to do this. It's only a convenience for
824 #debugging the debugger - when the debugger code is in the current
825 #directory.
826 if os.path.basename(fn) in [
827 'AsyncFile.py', 'AsyncIO.py',
828 'DebugConfig.py', 'DCTestResult.py',
829 'DebugBase.py', 'DebugClientBase.py',
830 'DebugClientCapabilities.py', 'DebugClient.py',
831 'DebugClientThreads.py', 'DebugProtocol.py',
832 'DebugThread.py', 'FlexCompleter.py',
833 'PyProfile.py'] or \
834 os.path.dirname(fn).endswith("coverage"):
835 return 1
836
837 if self._dbgClient.shouldSkip(fn):
838 return 1
839
840 return 0
841 851
842 def isBroken(self): 852 def isBroken(self):
843 """ 853 """
844 Public method to return the broken state of the debugger. 854 Public method to return the broken state of the debugger.
845 855

eric ide

mercurial