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 |
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 |