DebugClients/Python3/DebugBase.py

branch
debugger speed
changeset 5005
684f5ba04f0b
parent 4830
f609a22f43bd
child 5007
e2fa12bb0f53
equal deleted inserted replaced
5004:556528860c7a 5005:684f5ba04f0b
47 Class implementing base class of the debugger. 47 Class implementing base class of the debugger.
48 48
49 Provides simple wrapper methods around bdb for the 'owning' client to 49 Provides simple wrapper methods around bdb for the 'owning' client to
50 call to step etc. 50 call to step etc.
51 """ 51 """
52 # Don't thrust distutils.sysconfig.get_python_lib: possible case mismatch
53 # on Windows
54 lib = os.path.dirname(bdb.__file__)
55 # tuple required because it's accessed a lot of times by startswith method
56 pathsToSkip = ('<', os.path.dirname(__file__), bdb.__file__[:-1])
57 filesToSkip = {}
58
52 def __init__(self, dbgClient): 59 def __init__(self, dbgClient):
53 """ 60 """
54 Constructor 61 Constructor
55 62
56 @param dbgClient the owning client 63 @param dbgClient the owning client
59 66
60 self._dbgClient = dbgClient 67 self._dbgClient = dbgClient
61 self._mainThread = True 68 self._mainThread = True
62 69
63 self.breaks = self._dbgClient.breakpoints 70 self.breaks = self._dbgClient.breakpoints
71 self.tracePythonLibs(0)
64 72
65 self.__event = "" 73 self.__event = ""
66 self.__isBroken = "" 74 self.__isBroken = ""
67 self.cFrame = None 75 self.cFrame = None
68 76
196 @param event trace event (string) 204 @param event trace event (string)
197 @param fromFrame originating frame (frame) 205 @param fromFrame originating frame (frame)
198 @param toFrame destination frame (frame) 206 @param toFrame destination frame (frame)
199 """ 207 """
200 if self._dbgClient.callTraceEnabled: 208 if self._dbgClient.callTraceEnabled:
201 if not self.__skip_it(fromFrame) and not self.__skip_it(toFrame): 209 if (not self.__skipFrame(fromFrame) and
210 not self.__skipFrame(toFrame)):
202 if event in ["call", "return"]: 211 if event in ["call", "return"]:
203 fr = fromFrame 212 fr = fromFrame
204 fromStr = "{0}:{1}:{2}".format( 213 fromStr = "{0}:{1}:{2}".format(
205 self._dbgClient.absPath(self.fix_frame_filename(fr)), 214 self._dbgClient.absPath(self.fix_frame_filename(fr)),
206 fr.f_lineno, 215 fr.f_lineno,
295 @param frame The current stack frame. 304 @param frame The current stack frame.
296 @param arg The arguments 305 @param arg The arguments
297 @return local trace function 306 @return local trace function
298 @exception bdb.BdbQuit raised to indicate the end of the debug session 307 @exception bdb.BdbQuit raised to indicate the end of the debug session
299 """ 308 """
300 if not self.__skip_it(frame): 309 if not self.__skipFrame(frame):
301 # When stepping with next/until/return in a generator frame, 310 # When stepping with next/until/return in a generator frame,
302 # skip the internal StopIteration exception (with no traceback) 311 # skip the internal StopIteration exception (with no traceback)
303 # triggered by a subiterator run with the 'yield from' 312 # triggered by a subiterator run with the 'yield from'
304 # statement. 313 # statement.
305 if not (frame.f_code.co_flags & CO_GENERATOR and 314 if not (frame.f_code.co_flags & CO_GENERATOR and
843 debugger that are called from the application being debugged. 852 debugger that are called from the application being debugged.
844 853
845 @param frame the frame object 854 @param frame the frame object
846 @return flag indicating whether the debugger should stop here 855 @return flag indicating whether the debugger should stop here
847 """ 856 """
848 if self.__skip_it(frame): 857 if self.__skipFrame(frame):
849 return False 858 return False
850 859
851 return bdb.Bdb.stop_here(self, frame) 860 return bdb.Bdb.stop_here(self, frame)
852 861
853 def __skip_it(self, frame): 862 def tracePythonLibs(self, enable):
863 """
864 Public methode to update the settings to trace into Python libraries.
865
866 @param enable let's debug into Python libraries (int)
867 """
868 pathsToSkip = list(self.pathsToSkip)
869 # don't trace into Python library?
870 if enable:
871 pathsToSkip = [x for x in pathsToSkip if not x.endswith(
872 ("site-packages", "dist-packages", self.lib))]
873 else:
874 pathsToSkip.append(self.lib)
875 localLib = [x for x in sys.path if x.endswith(("site-packages",
876 "dist-packages")) and not x.startswith(self.lib)]
877 pathsToSkip.extend(localLib)
878
879 self.pathsToSkip = tuple(pathsToSkip)
880
881 def __skipFrame(self, frame):
854 """ 882 """
855 Private method to filter out debugger files. 883 Private method to filter out debugger files.
856 884
857 Tracing is turned off for files that are part of the 885 Tracing is turned off for files that are part of the
858 debugger that are called from the application being debugged. 886 debugger that are called from the application being debugged.
859 887
860 @param frame the frame object 888 @param frame the frame object
861 @return flag indicating whether the debugger should skip this frame 889 @return flag indicating whether the debugger should skip this frame
862 """ 890 """
863 if frame is None: 891 try:
892 return self.filesToSkip[frame.f_code.co_filename]
893 except KeyError:
894 ret = frame.f_code.co_filename.startswith(self.pathsToSkip)
895 self.filesToSkip[frame.f_code.co_filename] = ret
896 return ret
897 except AttributeError:
898 # if frame is None
864 return True 899 return True
865
866 fn = self.fix_frame_filename(frame)
867
868 # Eliminate things like <string> and <stdin>.
869 if fn[0] == '<':
870 return True
871
872 #XXX - think of a better way to do this. It's only a convenience for
873 #debugging the debugger - when the debugger code is in the current
874 #directory.
875 if os.path.basename(fn) in [
876 'AsyncFile.py', 'AsyncIO.py',
877 'DebugConfig.py', 'DCTestResult.py',
878 'DebugBase.py', 'DebugClientBase.py',
879 'DebugClientCapabilities.py', 'DebugClient.py',
880 'DebugClientThreads.py', 'DebugProtocol.py',
881 'DebugThread.py', 'FlexCompleter.py',
882 'PyProfile.py'] or \
883 os.path.dirname(fn).endswith("coverage"):
884 return True
885
886 if self._dbgClient.shouldSkip(fn):
887 return True
888
889 return False
890 900
891 def isBroken(self): 901 def isBroken(self):
892 """ 902 """
893 Public method to return the broken state of the debugger. 903 Public method to return the broken state of the debugger.
894 904

eric ide

mercurial