15 |
15 |
16 from DebugProtocol import * |
16 from DebugProtocol import * |
17 |
17 |
18 gRecursionLimit = 64 |
18 gRecursionLimit = 64 |
19 |
19 |
|
20 |
20 def printerr(s): |
21 def printerr(s): |
21 """ |
22 """ |
22 Module function used for debugging the debug client. |
23 Module function used for debugging the debug client. |
23 |
24 |
24 @param s data to be printed |
25 @param s data to be printed |
25 """ |
26 """ |
26 sys.__stderr__.write('{0!s}\n'.format(s)) |
27 sys.__stderr__.write('{0!s}\n'.format(s)) |
27 sys.__stderr__.flush() |
28 sys.__stderr__.flush() |
28 |
29 |
|
30 |
29 def setRecursionLimit(limit): |
31 def setRecursionLimit(limit): |
30 """ |
32 """ |
31 Module function to set the recursion limit. |
33 Module function to set the recursion limit. |
32 |
34 |
33 @param limit recursion limit (integer) |
35 @param limit recursion limit (integer) |
34 """ |
36 """ |
35 global gRecursionLimit |
37 global gRecursionLimit |
36 gRecursionLimit = limit |
38 gRecursionLimit = limit |
37 |
39 |
|
40 |
38 class DebugBase(bdb.Bdb): |
41 class DebugBase(bdb.Bdb): |
39 """ |
42 """ |
40 Class implementing base class of the debugger. |
43 Class implementing base class of the debugger. |
41 |
44 |
42 Provides simple wrapper methods around bdb for the 'owning' client to |
45 Provides simple wrapper methods around bdb for the 'owning' client to |
81 """ |
84 """ |
82 Public method to return the current frame. |
85 Public method to return the current frame. |
83 |
86 |
84 @return the current frame |
87 @return the current frame |
85 """ |
88 """ |
86 return self.currentFrame |
89 return self.currentFrame |
87 |
90 |
88 def getCurrentFrameLocals(self): |
91 def getCurrentFrameLocals(self): |
89 """ |
92 """ |
90 Public method to return the locals dictionary of the current frame. |
93 Public method to return the locals dictionary of the current frame. |
91 |
94 |
92 @return locals dictionary of the current frame |
95 @return locals dictionary of the current frame |
93 """ |
96 """ |
94 return self.currentFrameLocals |
97 return self.currentFrameLocals |
95 |
98 |
96 def step(self, traceMode): |
99 def step(self, traceMode): |
97 """ |
100 """ |
98 Public method to perform a step operation in this thread. |
101 Public method to perform a step operation in this thread. |
99 |
102 |
137 self.__recursionDepth += 1 |
140 self.__recursionDepth += 1 |
138 frame = frame.f_back |
141 frame = frame.f_back |
139 |
142 |
140 def profile(self, frame, event, arg): |
143 def profile(self, frame, event, arg): |
141 """ |
144 """ |
142 Public method used to trace some stuff independant of the debugger |
145 Public method used to trace some stuff independant of the debugger |
143 trace function. |
146 trace function. |
144 |
147 |
145 @param frame The current stack frame. |
148 @param frame The current stack frame. |
146 @param event The trace event (string) |
149 @param event The trace event (string) |
147 @param arg The arguments |
150 @param arg The arguments |
148 """ |
151 """ |
149 if event == 'return': |
152 if event == 'return': |
150 self.cFrame = frame.f_back |
153 self.cFrame = frame.f_back |
151 self.__recursionDepth -= 1 |
154 self.__recursionDepth -= 1 |
152 elif event == 'call': |
155 elif event == 'call': |
153 self.cFrame = frame |
156 self.cFrame = frame |
154 self.__recursionDepth += 1 |
157 self.__recursionDepth += 1 |
168 @param event The trace event (string) |
171 @param event The trace event (string) |
169 @param arg The arguments |
172 @param arg The arguments |
170 @return local trace function |
173 @return local trace function |
171 """ |
174 """ |
172 if self.quitting: |
175 if self.quitting: |
173 return # None |
176 return # None |
174 |
177 |
175 # give the client a chance to push through new break points. |
178 # give the client a chance to push through new break points. |
176 self._dbgClient.eventPoll() |
179 self._dbgClient.eventPoll() |
177 |
180 |
178 self.__event == event |
181 self.__event == event |
238 self.user_exception(frame, arg) |
241 self.user_exception(frame, arg) |
239 if self.quitting: |
242 if self.quitting: |
240 raise bdb.BdbQuit |
243 raise bdb.BdbQuit |
241 return self.trace_dispatch |
244 return self.trace_dispatch |
242 |
245 |
243 def set_trace(self, frame = None): |
246 def set_trace(self, frame=None): |
244 """ |
247 """ |
245 Overridden method of bdb.py to do some special setup. |
248 Overridden method of bdb.py to do some special setup. |
246 |
249 |
247 @param frame frame to start debugging from |
250 @param frame frame to start debugging from |
248 """ |
251 """ |
303 if os.path.exists(fixedName): |
306 if os.path.exists(fixedName): |
304 return fixedName |
307 return fixedName |
305 |
308 |
306 return frame.f_code.co_filename |
309 return frame.f_code.co_filename |
307 |
310 |
308 def set_watch(self, cond, temporary = False): |
311 def set_watch(self, cond, temporary=False): |
309 """ |
312 """ |
310 Public method to set a watch expression. |
313 Public method to set a watch expression. |
311 |
314 |
312 @param cond expression of the watch expression (string) |
315 @param cond expression of the watch expression (string) |
313 @param temporary flag indicating a temporary watch expression (boolean) |
316 @param temporary flag indicating a temporary watch expression (boolean) |
328 """ |
331 """ |
329 Public method to clear a watch expression. |
332 Public method to clear a watch expression. |
330 |
333 |
331 @param cond expression of the watch expression to be cleared (string) |
334 @param cond expression of the watch expression to be cleared (string) |
332 """ |
335 """ |
333 try: |
336 try: |
334 possibles = bdb.Breakpoint.bplist["Watch", 0] |
337 possibles = bdb.Breakpoint.bplist["Watch", 0] |
335 for i in range(0, len(possibles)): |
338 for i in range(0, len(possibles)): |
336 b = possibles[i] |
339 b = possibles[i] |
337 if b.cond == cond: |
340 if b.cond == cond: |
338 b.deleteMe() |
341 b.deleteMe() |
418 |
421 |
419 return (None, False) |
422 return (None, False) |
420 |
423 |
421 def break_here(self, frame): |
424 def break_here(self, frame): |
422 """ |
425 """ |
423 Reimplemented from bdb.py to fix the filename from the frame. |
426 Reimplemented from bdb.py to fix the filename from the frame. |
424 |
427 |
425 See fix_frame_filename for more info. |
428 See fix_frame_filename for more info. |
426 |
429 |
427 @param frame the frame object |
430 @param frame the frame object |
428 @return flag indicating the break status (boolean) |
431 @return flag indicating the break status (boolean) |
574 self.__isBroken = True |
577 self.__isBroken = True |
575 |
578 |
576 self._dbgClient.write('{0}{1}\n'.format(ResponseLine, str(stack))) |
579 self._dbgClient.write('{0}{1}\n'.format(ResponseLine, str(stack))) |
577 self._dbgClient.eventLoop() |
580 self._dbgClient.eventLoop() |
578 |
581 |
579 def user_exception(self, frame, excinfo, unhandled = False): |
582 def user_exception(self, frame, excinfo, unhandled=False): |
580 """ |
583 """ |
581 Reimplemented to report an exception to the debug server. |
584 Reimplemented to report an exception to the debug server. |
582 |
585 |
583 @param frame the frame object |
586 @param frame the frame object |
584 @param excinfo information about the exception |
587 @param excinfo information about the exception |
692 @return flag indicating whether the debugger should stop here |
695 @return flag indicating whether the debugger should stop here |
693 """ |
696 """ |
694 if self.__skip_it(frame): |
697 if self.__skip_it(frame): |
695 return False |
698 return False |
696 |
699 |
697 return bdb.Bdb.stop_here(self,frame) |
700 return bdb.Bdb.stop_here(self, frame) |
698 |
701 |
699 def __skip_it(self, frame): |
702 def __skip_it(self, frame): |
700 """ |
703 """ |
701 Private method to filter out debugger files. |
704 Private method to filter out debugger files. |
702 |
705 |
716 #debugging the debugger - when the debugger code is in the current |
719 #debugging the debugger - when the debugger code is in the current |
717 #directory. |
720 #directory. |
718 if os.path.basename(fn) in [\ |
721 if os.path.basename(fn) in [\ |
719 'AsyncFile.py', 'AsyncIO.py', |
722 'AsyncFile.py', 'AsyncIO.py', |
720 'DebugConfig.py', 'DCTestResult.py', |
723 'DebugConfig.py', 'DCTestResult.py', |
721 'DebugBase.py', 'DebugClientBase.py', |
724 'DebugBase.py', 'DebugClientBase.py', |
722 'DebugClientCapabilities.py', 'DebugClient.py', |
725 'DebugClientCapabilities.py', 'DebugClient.py', |
723 'DebugClientThreads.py', 'DebugProtocol.py', |
726 'DebugClientThreads.py', 'DebugProtocol.py', |
724 'DebugThread.py', 'FlexCompleter.py', |
727 'DebugThread.py', 'FlexCompleter.py', |
725 'PyProfile.py'] or \ |
728 'PyProfile.py'] or \ |
726 os.path.dirname(fn).endswith("coverage"): |
729 os.path.dirname(fn).endswith("coverage"): |
727 return True |
730 return True |