blob: 922133ba1512874b28fb4397175f3b21841f2af2 [file] [log] [blame]
Tor Norbye1aa2e092014-08-20 17:01:23 -07001import linecache
Tor Norbye3a2425a2013-11-04 10:16:08 -08002import os.path
Tor Norbye1aa2e092014-08-20 17:01:23 -07003import re
4import traceback # @Reimport
5
Tor Norbye3a2425a2013-11-04 10:16:08 -08006import pydev_log
Tor Norbye1aa2e092014-08-20 17:01:23 -07007from pydevd_breakpoints import get_exception_breakpoint, get_exception_name
Tor Norbyee782c572014-09-18 11:43:07 -07008from pydevd_comm import CMD_STEP_CAUGHT_EXCEPTION, CMD_STEP_RETURN, CMD_STEP_OVER, CMD_SET_BREAK, \
Tor Norbye1aa2e092014-08-20 17:01:23 -07009 CMD_STEP_INTO, CMD_SMART_STEP_INTO, CMD_RUN_TO_LINE, CMD_SET_NEXT_STATEMENT
10from pydevd_constants import * # @UnusedWildImport
11from pydevd_file_utils import GetFilenameAndBase
Tor Norbyee782c572014-09-18 11:43:07 -070012
13from pydevd_frame_utils import add_exception_to_frame, just_raised
14
Tor Norbyec3d3a902014-09-04 13:24:04 -070015try:
16 from pydevd_signature import sendSignatureCallTrace
17except ImportError:
18 def sendSignatureCallTrace(*args, **kwargs):
19 pass
Tor Norbye1aa2e092014-08-20 17:01:23 -070020import pydevd_vars
21import pydevd_dont_trace
Tor Norbye3a2425a2013-11-04 10:16:08 -080022
23basename = os.path.basename
24
Tor Norbye1aa2e092014-08-20 17:01:23 -070025IGNORE_EXCEPTION_TAG = re.compile('[^#]*#.*@IgnoreException')
26
27
Tor Norbye3a2425a2013-11-04 10:16:08 -080028#=======================================================================================================================
29# PyDBFrame
30#=======================================================================================================================
31class PyDBFrame:
32 '''This makes the tracing for a given frame, so, the trace_dispatch
33 is used initially when we enter into a new context ('call') and then
34 is reused for the entire context.
35 '''
36
Tor Norbye1aa2e092014-08-20 17:01:23 -070037 #Note: class (and not instance) attributes.
38
39 #Same thing in the main debugger but only considering the file contents, while the one in the main debugger
40 #considers the user input (so, the actual result must be a join of both).
41 filename_to_lines_where_exceptions_are_ignored = {}
42 filename_to_stat_info = {}
43
Tor Norbye3a2425a2013-11-04 10:16:08 -080044 def __init__(self, args):
45 #args = mainDebugger, filename, base, info, t, frame
46 #yeap, much faster than putting in self and then getting it from self later on
47 self._args = args[:-1]
48
49 def setSuspend(self, *args, **kwargs):
50 self._args[0].setSuspend(*args, **kwargs)
51
52 def doWaitSuspend(self, *args, **kwargs):
53 self._args[0].doWaitSuspend(*args, **kwargs)
54
55 def trace_exception(self, frame, event, arg):
56 if event == 'exception':
Tor Norbye1aa2e092014-08-20 17:01:23 -070057 flag, frame = self.should_stop_on_exception(frame, event, arg)
Tor Norbye3a2425a2013-11-04 10:16:08 -080058
59 if flag:
Tor Norbye1aa2e092014-08-20 17:01:23 -070060 self.handle_exception(frame, event, arg)
61 return self.trace_dispatch
Tor Norbye3a2425a2013-11-04 10:16:08 -080062
63 return self.trace_exception
64
Tor Norbye1aa2e092014-08-20 17:01:23 -070065 def should_stop_on_exception(self, frame, event, arg):
66 mainDebugger, _filename, info, thread = self._args
67 flag = False
Tor Norbye3a2425a2013-11-04 10:16:08 -080068
Tor Norbye1aa2e092014-08-20 17:01:23 -070069 if info.pydev_state != STATE_SUSPEND: #and breakpoint is not None:
70 exception, value, trace = arg
Tor Norbye3a2425a2013-11-04 10:16:08 -080071
Tor Norbye1aa2e092014-08-20 17:01:23 -070072 if trace is not None: #on jython trace is None on the first event
73 exception_breakpoint = get_exception_breakpoint(
74 exception, mainDebugger.break_on_caught_exceptions)
Tor Norbye3a2425a2013-11-04 10:16:08 -080075
Tor Norbye1aa2e092014-08-20 17:01:23 -070076 if exception_breakpoint is not None:
77 if not exception_breakpoint.notify_on_first_raise_only or just_raised(trace):
78 # print frame.f_code.co_name
79 add_exception_to_frame(frame, (exception, value, trace))
80 thread.additionalInfo.message = exception_breakpoint.qname
81 flag = True
82 else:
83 flag = False
84 else:
85 try:
Tor Norbyee782c572014-09-18 11:43:07 -070086 result = mainDebugger.plugin.exception_break(mainDebugger, self, frame, self._args, arg)
87 if result:
88 (flag, frame) = result
Tor Norbye3a2425a2013-11-04 10:16:08 -080089
Tor Norbyee782c572014-09-18 11:43:07 -070090 except:
Tor Norbye1aa2e092014-08-20 17:01:23 -070091 flag = False
92
93 return flag, frame
Tor Norbye3a2425a2013-11-04 10:16:08 -080094
95 def handle_exception(self, frame, event, arg):
Tor Norbye1aa2e092014-08-20 17:01:23 -070096 try:
97 # print 'handle_exception', frame.f_lineno, frame.f_code.co_name
98
99 # We have 3 things in arg: exception type, description, traceback object
100 trace_obj = arg[2]
101 mainDebugger = self._args[0]
102
103 if not hasattr(trace_obj, 'tb_next'):
104 return #Not always there on Jython...
105
106 initial_trace_obj = trace_obj
107 if trace_obj.tb_next is None and trace_obj.tb_frame is frame:
108 #I.e.: tb_next should be only None in the context it was thrown (trace_obj.tb_frame is frame is just a double check).
109
110 if mainDebugger.break_on_exceptions_thrown_in_same_context:
111 #Option: Don't break if an exception is caught in the same function from which it is thrown
112 return
113 else:
114 #Get the trace_obj from where the exception was raised...
115 while trace_obj.tb_next is not None:
116 trace_obj = trace_obj.tb_next
117
118
119 if mainDebugger.ignore_exceptions_thrown_in_lines_with_ignore_exception:
120 for check_trace_obj in (initial_trace_obj, trace_obj):
121 filename = GetFilenameAndBase(check_trace_obj.tb_frame)[0]
122
123
124 filename_to_lines_where_exceptions_are_ignored = self.filename_to_lines_where_exceptions_are_ignored
125
126
127 lines_ignored = filename_to_lines_where_exceptions_are_ignored.get(filename)
128 if lines_ignored is None:
129 lines_ignored = filename_to_lines_where_exceptions_are_ignored[filename] = {}
130
131 try:
132 curr_stat = os.stat(filename)
133 curr_stat = (curr_stat.st_size, curr_stat.st_mtime)
134 except:
135 curr_stat = None
136
137 last_stat = self.filename_to_stat_info.get(filename)
138 if last_stat != curr_stat:
139 self.filename_to_stat_info[filename] = curr_stat
140 lines_ignored.clear()
141 try:
142 linecache.checkcache(filename)
143 except:
144 #Jython 2.1
145 linecache.checkcache()
146
147 from_user_input = mainDebugger.filename_to_lines_where_exceptions_are_ignored.get(filename)
148 if from_user_input:
149 merged = {}
150 merged.update(lines_ignored)
151 #Override what we have with the related entries that the user entered
152 merged.update(from_user_input)
153 else:
154 merged = lines_ignored
155
156 exc_lineno = check_trace_obj.tb_lineno
157
158 # print ('lines ignored', lines_ignored)
159 # print ('user input', from_user_input)
160 # print ('merged', merged, 'curr', exc_lineno)
161
162 if not DictContains(merged, exc_lineno): #Note: check on merged but update lines_ignored.
163 try:
164 line = linecache.getline(filename, exc_lineno, check_trace_obj.tb_frame.f_globals)
165 except:
166 #Jython 2.1
167 line = linecache.getline(filename, exc_lineno)
168
169 if IGNORE_EXCEPTION_TAG.match(line) is not None:
170 lines_ignored[exc_lineno] = 1
171 return
172 else:
173 #Put in the cache saying not to ignore
174 lines_ignored[exc_lineno] = 0
175 else:
176 #Ok, dict has it already cached, so, let's check it...
177 if merged.get(exc_lineno, 0):
178 return
179
180
181 thread = self._args[3]
182
183 try:
184 frame_id_to_frame = {}
185 frame_id_to_frame[id(frame)] = frame
186 f = trace_obj.tb_frame
187 while f is not None:
188 frame_id_to_frame[id(f)] = f
189 f = f.f_back
190 f = None
191
192 thread_id = GetThreadId(thread)
193 pydevd_vars.addAdditionalFrameById(thread_id, frame_id_to_frame)
194 try:
195 mainDebugger.sendCaughtExceptionStack(thread, arg, id(frame))
196 self.setSuspend(thread, CMD_STEP_CAUGHT_EXCEPTION)
197 self.doWaitSuspend(thread, frame, event, arg)
198 mainDebugger.sendCaughtExceptionStackProceeded(thread)
199
200 finally:
201 pydevd_vars.removeAdditionalFrameById(thread_id)
202 except:
203 traceback.print_exc()
204
205 mainDebugger.SetTraceForFrameAndParents(frame)
206 finally:
207 #Clear some local variables...
208 trace_obj = None
209 initial_trace_obj = None
210 check_trace_obj = None
211 f = None
212 frame_id_to_frame = None
213 mainDebugger = None
214 thread = None
Tor Norbye3a2425a2013-11-04 10:16:08 -0800215
216 def trace_dispatch(self, frame, event, arg):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700217 main_debugger, filename, info, thread = self._args
Tor Norbye3a2425a2013-11-04 10:16:08 -0800218 try:
219 info.is_tracing = True
220
Tor Norbye1aa2e092014-08-20 17:01:23 -0700221 if main_debugger._finishDebuggingSession:
Tor Norbye3a2425a2013-11-04 10:16:08 -0800222 return None
223
224 if getattr(thread, 'pydev_do_not_trace', None):
225 return None
226
Tor Norbye1aa2e092014-08-20 17:01:23 -0700227 if event == 'call' and main_debugger.signature_factory:
228 sendSignatureCallTrace(main_debugger, frame, filename)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800229
Tor Norbye1aa2e092014-08-20 17:01:23 -0700230 is_exception_event = event == 'exception'
Tor Norbyee782c572014-09-18 11:43:07 -0700231 has_exception_breakpoints = main_debugger.break_on_caught_exceptions \
232 or main_debugger.plugin.has_exception_breaks(main_debugger)
Tor Norbye1aa2e092014-08-20 17:01:23 -0700233
234 if is_exception_event:
235 if has_exception_breakpoints:
236 flag, frame = self.should_stop_on_exception(frame, event, arg)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800237 if flag:
238 self.handle_exception(frame, event, arg)
239 return self.trace_dispatch
Tor Norbye3a2425a2013-11-04 10:16:08 -0800240
Tor Norbye1aa2e092014-08-20 17:01:23 -0700241 elif event not in ('line', 'call', 'return'):
242 #I believe this can only happen in jython on some frontiers on jython and java code, which we don't want to trace.
243 return None
244
245 stop_frame = info.pydev_step_stop
246 step_cmd = info.pydev_step_cmd
247
248 if is_exception_event:
249 breakpoints_for_file = None
250 else:
251 # If we are in single step mode and something causes us to exit the current frame, we need to make sure we break
252 # eventually. Force the step mode to step into and the step stop frame to None.
253 # I.e.: F6 in the end of a function should stop in the next possible position (instead of forcing the user
254 # to make a step in or step over at that location).
255 # Note: this is especially troublesome when we're skipping code with the
256 # @DontTrace comment.
257 if stop_frame is frame and event in ('return', 'exception') and step_cmd in (CMD_STEP_RETURN, CMD_STEP_OVER):
258 info.pydev_step_cmd = CMD_STEP_INTO
259 info.pydev_step_stop = None
260
261 breakpoints_for_file = main_debugger.breakpoints.get(filename)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800262
263 can_skip = False
264
265 if info.pydev_state == STATE_RUN:
266 #we can skip if:
267 #- we have no stop marked
268 #- we should make a step return/step over and we're not in the current frame
Tor Norbye1aa2e092014-08-20 17:01:23 -0700269 can_skip = (step_cmd is None and stop_frame is None)\
270 or (step_cmd in (CMD_STEP_RETURN, CMD_STEP_OVER) and stop_frame is not frame)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800271
Tor Norbyee782c572014-09-18 11:43:07 -0700272 if can_skip:
273 can_skip = not main_debugger.plugin.can_not_skip(main_debugger, self, frame)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800274
275 # Let's check to see if we are in a function that has a breakpoint. If we don't have a breakpoint,
276 # we will return nothing for the next trace
277 #also, after we hit a breakpoint and go to some other debugging state, we have to force the set trace anyway,
278 #so, that's why the additional checks are there.
279 if not breakpoints_for_file:
280 if can_skip:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700281 if has_exception_breakpoints:
Tor Norbye3a2425a2013-11-04 10:16:08 -0800282 return self.trace_exception
283 else:
284 return None
285
286 else:
287 #checks the breakpoint to see if there is a context match in some function
288 curr_func_name = frame.f_code.co_name
289
290 #global context is set with an empty name
291 if curr_func_name in ('?', '<module>'):
292 curr_func_name = ''
293
Tor Norbye1aa2e092014-08-20 17:01:23 -0700294 for breakpoint in DictIterValues(breakpoints_for_file): #jython does not support itervalues()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800295 #will match either global or some function
296 if breakpoint.func_name in ('None', curr_func_name):
297 break
298
299 else: # if we had some break, it won't get here (so, that's a context that we want to skip)
300 if can_skip:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700301 if has_exception_breakpoints:
302 return self.trace_exception
303 else:
304 return None
305
Tor Norbye3a2425a2013-11-04 10:16:08 -0800306
307 #We may have hit a breakpoint or we are already in step mode. Either way, let's check what we should do in this frame
308 #print 'NOT skipped', frame.f_lineno, frame.f_code.co_name, event
309
310 try:
311 line = frame.f_lineno
Tor Norbye3a2425a2013-11-04 10:16:08 -0800312 flag = False
Tor Norbye3a2425a2013-11-04 10:16:08 -0800313 #return is not taken into account for breakpoint hit because we'd have a double-hit in this case
314 #(one for the line and the other for the return).
315
Tor Norbyee782c572014-09-18 11:43:07 -0700316 stop_info = {}
317 breakpoint = None
318 exist_result = False
319 stop_info['stop'] = False
320 if not flag and event != 'return' and info.pydev_state != STATE_SUSPEND and breakpoints_for_file is not None \
321 and DictContains(breakpoints_for_file, line):
322 breakpoint = breakpoints_for_file[line]
323 new_frame = frame
324 stop_info['stop'] = True
325 if step_cmd == CMD_STEP_OVER and stop_frame is frame and event in ('line', 'return'):
326 stop_info['stop'] = False #we don't stop on breakpoint if we have to stop by step-over (it will be processed later)
327 else:
328 result = main_debugger.plugin.get_breakpoint(main_debugger, self, frame, event, self._args)
329 if result:
330 exist_result = True
331 (flag, breakpoint, new_frame) = result
332
333 if breakpoint:
Tor Norbye3a2425a2013-11-04 10:16:08 -0800334 #ok, hit breakpoint, now, we have to discover if it is a conditional breakpoint
335 # lets do the conditional stuff here
Tor Norbyee782c572014-09-18 11:43:07 -0700336 if stop_info['stop'] or exist_result:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700337 condition = breakpoint.condition
338 if condition is not None:
Tor Norbye3a2425a2013-11-04 10:16:08 -0800339 try:
Tor Norbyee782c572014-09-18 11:43:07 -0700340 val = eval(condition, new_frame.f_globals, new_frame.f_locals)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800341 if not val:
342 return self.trace_dispatch
343
344 except:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700345 if type(condition) != type(''):
346 if hasattr(condition, 'encode'):
347 condition = condition.encode('utf-8')
Tor Norbye3a2425a2013-11-04 10:16:08 -0800348
Tor Norbye1aa2e092014-08-20 17:01:23 -0700349 msg = 'Error while evaluating expression: %s\n' % (condition,)
350 sys.stderr.write(msg)
351 traceback.print_exc()
352 if not main_debugger.suspend_on_breakpoint_exception:
353 return self.trace_dispatch
354 else:
Tor Norbyee782c572014-09-18 11:43:07 -0700355 stop_info['stop'] = True
Tor Norbye1aa2e092014-08-20 17:01:23 -0700356 try:
357 additional_info = None
358 try:
359 additional_info = thread.additionalInfo
360 except AttributeError:
361 pass #that's ok, no info currently set
362
363 if additional_info is not None:
364 # add exception_type and stacktrace into thread additional info
365 etype, value, tb = sys.exc_info()
366 try:
367 error = ''.join(traceback.format_exception_only(etype, value))
368 stack = traceback.extract_stack(f=tb.tb_frame.f_back)
369
370 # On self.setSuspend(thread, CMD_SET_BREAK) this info will be
371 # sent to the client.
372 additional_info.conditional_breakpoint_exception = \
373 ('Condition:\n' + condition + '\n\nError:\n' + error, stack)
374 finally:
375 etype, value, tb = None, None, None
376 except:
377 traceback.print_exc()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800378
Tor Norbyee782c572014-09-18 11:43:07 -0700379 if breakpoint.expression is not None:
Tor Norbye3a2425a2013-11-04 10:16:08 -0800380 try:
Tor Norbyee782c572014-09-18 11:43:07 -0700381 try:
382 val = eval(breakpoint.expression, new_frame.f_globals, new_frame.f_locals)
383 except:
384 val = sys.exc_info()[1]
385 finally:
386 if val is not None:
387 thread.additionalInfo.message = val
388 if stop_info['stop']:
389 self.setSuspend(thread, CMD_SET_BREAK)
390 elif flag:
391 result = main_debugger.plugin.suspend(main_debugger, thread, frame)
392 if result:
393 frame = result
Tor Norbye3a2425a2013-11-04 10:16:08 -0800394
395 # if thread has a suspend flag, we suspend with a busy wait
396 if info.pydev_state == STATE_SUSPEND:
397 self.doWaitSuspend(thread, frame, event, arg)
398 return self.trace_dispatch
399
400 except:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700401 traceback.print_exc()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800402 raise
403
404 #step handling. We stop when we hit the right frame
405 try:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700406 should_skip = False
407 if pydevd_dont_trace.should_trace_hook is not None:
408 if not hasattr(self, 'should_skip'):
409 # I.e.: cache the result on self.should_skip (no need to evaluate the same frame multiple times).
410 # Note that on a code reload, we won't re-evaluate this because in practice, the frame.f_code
411 # Which will be handled by this frame is read-only, so, we can cache it safely.
412 should_skip = self.should_skip = not pydevd_dont_trace.should_trace_hook(frame, filename)
413 else:
414 should_skip = self.should_skip
415
416 if should_skip:
Tor Norbyee782c572014-09-18 11:43:07 -0700417 stop_info['stop'] = False
Tor Norbye1aa2e092014-08-20 17:01:23 -0700418
419 elif step_cmd == CMD_STEP_INTO:
Tor Norbyee782c572014-09-18 11:43:07 -0700420 stop_info['stop'] = event in ('line', 'return')
421 main_debugger.plugin.cmd_step_into(main_debugger, frame, event, self._args, stop_info)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800422
Tor Norbye1aa2e092014-08-20 17:01:23 -0700423 elif step_cmd == CMD_STEP_OVER:
Tor Norbyee782c572014-09-18 11:43:07 -0700424 stop_info['stop'] = stop_frame is frame and event in ('line', 'return')
425 main_debugger.plugin.cmd_step_over(main_debugger, frame, event, self._args, stop_info)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800426
Tor Norbye1aa2e092014-08-20 17:01:23 -0700427 elif step_cmd == CMD_SMART_STEP_INTO:
Tor Norbyee782c572014-09-18 11:43:07 -0700428 stop_info['stop'] = False
Tor Norbye3a2425a2013-11-04 10:16:08 -0800429 if info.pydev_smart_step_stop is frame:
430 info.pydev_func_name = None
431 info.pydev_smart_step_stop = None
432
433 if event == 'line' or event == 'exception':
434 curr_func_name = frame.f_code.co_name
435
436 #global context is set with an empty name
437 if curr_func_name in ('?', '<module>') or curr_func_name is None:
438 curr_func_name = ''
439
440 if curr_func_name == info.pydev_func_name:
Tor Norbyee782c572014-09-18 11:43:07 -0700441 stop_info['stop'] = True
Tor Norbye3a2425a2013-11-04 10:16:08 -0800442
Tor Norbye1aa2e092014-08-20 17:01:23 -0700443 elif step_cmd == CMD_STEP_RETURN:
Tor Norbyee782c572014-09-18 11:43:07 -0700444 stop_info['stop'] = event == 'return' and stop_frame is frame
Tor Norbye3a2425a2013-11-04 10:16:08 -0800445
Tor Norbye1aa2e092014-08-20 17:01:23 -0700446 elif step_cmd == CMD_RUN_TO_LINE or step_cmd == CMD_SET_NEXT_STATEMENT:
Tor Norbyee782c572014-09-18 11:43:07 -0700447 stop_info['stop'] = False
Tor Norbye3a2425a2013-11-04 10:16:08 -0800448
449 if event == 'line' or event == 'exception':
450 #Yes, we can only act on line events (weird hum?)
451 #Note: This code is duplicated at pydevd.py
452 #Acting on exception events after debugger breaks with exception
453 curr_func_name = frame.f_code.co_name
454
455 #global context is set with an empty name
456 if curr_func_name in ('?', '<module>'):
457 curr_func_name = ''
458
459 if curr_func_name == info.pydev_func_name:
460 line = info.pydev_next_line
461 if frame.f_lineno == line:
Tor Norbyee782c572014-09-18 11:43:07 -0700462 stop_info['stop'] = True
Tor Norbye3a2425a2013-11-04 10:16:08 -0800463 else:
464 if frame.f_trace is None:
465 frame.f_trace = self.trace_dispatch
466 frame.f_lineno = line
467 frame.f_trace = None
Tor Norbyee782c572014-09-18 11:43:07 -0700468 stop_info['stop'] = True
Tor Norbye3a2425a2013-11-04 10:16:08 -0800469
470 else:
Tor Norbyee782c572014-09-18 11:43:07 -0700471 stop_info['stop'] = False
Tor Norbye3a2425a2013-11-04 10:16:08 -0800472
Tor Norbyee782c572014-09-18 11:43:07 -0700473 if True in DictIterValues(stop_info):
474 stopped_on_plugin = main_debugger.plugin.stop(main_debugger, frame, event, self._args, stop_info, arg, step_cmd)
475 if DictContains(stop_info, 'stop') and stop_info['stop'] and not stopped_on_plugin:
476 if event == 'line':
Tor Norbye1aa2e092014-08-20 17:01:23 -0700477 self.setSuspend(thread, step_cmd)
Tor Norbyee782c572014-09-18 11:43:07 -0700478 self.doWaitSuspend(thread, frame, event, arg)
479 else: #return event
480 back = frame.f_back
481 if back is not None:
482 #When we get to the pydevd run function, the debugging has actually finished for the main thread
483 #(note that it can still go on for other threads, but for this one, we just make it finish)
484 #So, just setting it to None should be OK
485 base = basename(back.f_code.co_filename)
486 if base == 'pydevd.py' and back.f_code.co_name == 'run':
487 back = None
488
489 elif base == 'pydevd_traceproperty.py':
490 # We dont want to trace the return event of pydevd_traceproperty (custom property for debugging)
491 #if we're in a return, we want it to appear to the user in the previous frame!
492 return None
493
494 if back is not None:
495 #if we're in a return, we want it to appear to the user in the previous frame!
496 self.setSuspend(thread, step_cmd)
497 self.doWaitSuspend(thread, back, event, arg)
498 else:
499 #in jython we may not have a back frame
500 info.pydev_step_stop = None
501 info.pydev_step_cmd = None
502 info.pydev_state = STATE_RUN
Tor Norbye3a2425a2013-11-04 10:16:08 -0800503
504
505 except:
506 traceback.print_exc()
507 info.pydev_step_cmd = None
508
509 #if we are quitting, let's stop the tracing
510 retVal = None
Tor Norbye1aa2e092014-08-20 17:01:23 -0700511 if not main_debugger.quitting:
Tor Norbye3a2425a2013-11-04 10:16:08 -0800512 retVal = self.trace_dispatch
513
514 return retVal
515 finally:
516 info.is_tracing = False
517
518 #end trace_dispatch
519
520 if USE_PSYCO_OPTIMIZATION:
521 try:
522 import psyco
523
524 trace_dispatch = psyco.proxy(trace_dispatch)
525 except ImportError:
526 if hasattr(sys, 'exc_clear'): #jython does not have it
527 sys.exc_clear() #don't keep the traceback
Tor Norbyee782c572014-09-18 11:43:07 -0700528 pass #ok, psyco not available