1import linecache 2import os.path 3import re 4 5from _pydev_bundle import pydev_log 6from _pydevd_bundle import pydevd_dont_trace 7from _pydevd_bundle.pydevd_constants import (dict_iter_values, IS_PY3K, RETURN_VALUES_DICT, NO_FTRACE, 8 EXCEPTION_TYPE_HANDLED, EXCEPTION_TYPE_USER_UNHANDLED) 9from _pydevd_bundle.pydevd_frame_utils import add_exception_to_frame, just_raised, remove_exception_from_frame, ignore_exception_trace 10from _pydevd_bundle.pydevd_utils import get_clsname_for_code 11from pydevd_file_utils import get_abs_path_real_path_and_base_from_frame 12from _pydevd_bundle.pydevd_comm_constants import constant_to_str, CMD_SET_FUNCTION_BREAK 13try: 14 from _pydevd_bundle.pydevd_bytecode_utils import get_smart_step_into_variant_from_frame_offset 15except ImportError: 16 17 def get_smart_step_into_variant_from_frame_offset(*args, **kwargs): 18 return None 19 20# IFDEF CYTHON 21# cython_inline_constant: CMD_STEP_INTO = 107 22# cython_inline_constant: CMD_STEP_INTO_MY_CODE = 144 23# cython_inline_constant: CMD_STEP_RETURN = 109 24# cython_inline_constant: CMD_STEP_RETURN_MY_CODE = 160 25# cython_inline_constant: CMD_STEP_OVER = 108 26# cython_inline_constant: CMD_STEP_OVER_MY_CODE = 159 27# cython_inline_constant: CMD_STEP_CAUGHT_EXCEPTION = 137 28# cython_inline_constant: CMD_SET_BREAK = 111 29# cython_inline_constant: CMD_SMART_STEP_INTO = 128 30# cython_inline_constant: CMD_STEP_INTO_COROUTINE = 206 31# cython_inline_constant: STATE_RUN = 1 32# cython_inline_constant: STATE_SUSPEND = 2 33# ELSE 34# Note: those are now inlined on cython. 35CMD_STEP_INTO = 107 36CMD_STEP_INTO_MY_CODE = 144 37CMD_STEP_RETURN = 109 38CMD_STEP_RETURN_MY_CODE = 160 39CMD_STEP_OVER = 108 40CMD_STEP_OVER_MY_CODE = 159 41CMD_STEP_CAUGHT_EXCEPTION = 137 42CMD_SET_BREAK = 111 43CMD_SMART_STEP_INTO = 128 44CMD_STEP_INTO_COROUTINE = 206 45STATE_RUN = 1 46STATE_SUSPEND = 2 47# ENDIF 48 49basename = os.path.basename 50 51IGNORE_EXCEPTION_TAG = re.compile('[^#]*#.*@IgnoreException') 52DEBUG_START = ('pydevd.py', 'run') 53DEBUG_START_PY3K = ('_pydev_execfile.py', 'execfile') 54TRACE_PROPERTY = 'pydevd_traceproperty.py' 55 56import dis 57 58try: 59 StopAsyncIteration 60except NameError: 61 StopAsyncIteration = StopIteration 62 63 64# IFDEF CYTHON 65# cdef is_unhandled_exception(container_obj, py_db, frame, int last_raise_line, set raise_lines): 66# ELSE 67def is_unhandled_exception(container_obj, py_db, frame, last_raise_line, raise_lines): 68# ENDIF 69 if frame.f_lineno in raise_lines: 70 return True 71 72 else: 73 try_except_infos = container_obj.try_except_infos 74 if try_except_infos is None: 75 container_obj.try_except_infos = try_except_infos = py_db.collect_try_except_info(frame.f_code) 76 77 if not try_except_infos: 78 # Consider the last exception as unhandled because there's no try..except in it. 79 return True 80 else: 81 # Now, consider only the try..except for the raise 82 valid_try_except_infos = [] 83 for try_except_info in try_except_infos: 84 if try_except_info.is_line_in_try_block(last_raise_line): 85 valid_try_except_infos.append(try_except_info) 86 87 if not valid_try_except_infos: 88 return True 89 90 else: 91 # Note: check all, not only the "valid" ones to cover the case 92 # in "tests_python.test_tracing_on_top_level.raise_unhandled10" 93 # where one try..except is inside the other with only a raise 94 # and it's gotten in the except line. 95 for try_except_info in try_except_infos: 96 if try_except_info.is_line_in_except_block(frame.f_lineno): 97 if ( 98 frame.f_lineno == try_except_info.except_line or 99 frame.f_lineno in try_except_info.raise_lines_in_except 100 ): 101 # In a raise inside a try..except block or some except which doesn't 102 # match the raised exception. 103 return True 104 return False 105 106 107# IFDEF CYTHON 108# cdef class _TryExceptContainerObj: 109# cdef public list try_except_infos; 110# def __init__(self): 111# self.try_except_infos = None 112# ELSE 113class _TryExceptContainerObj(object): 114 ''' 115 A dumb container object just to containe the try..except info when needed. Meant to be 116 persisent among multiple PyDBFrames to the same code object. 117 ''' 118 try_except_infos = None 119# ENDIF 120 121 122#======================================================================================================================= 123# PyDBFrame 124#======================================================================================================================= 125# IFDEF CYTHON 126# cdef class PyDBFrame: 127# ELSE 128class PyDBFrame: 129 '''This makes the tracing for a given frame, so, the trace_dispatch 130 is used initially when we enter into a new context ('call') and then 131 is reused for the entire context. 132 ''' 133# ENDIF 134 135 # Note: class (and not instance) attributes. 136 137 # Same thing in the main debugger but only considering the file contents, while the one in the main debugger 138 # considers the user input (so, the actual result must be a join of both). 139 filename_to_lines_where_exceptions_are_ignored = {} 140 filename_to_stat_info = {} 141 142 # IFDEF CYTHON 143 # cdef tuple _args 144 # cdef int should_skip 145 # cdef object exc_info 146 # def __init__(self, tuple args): 147 # self._args = args # In the cython version we don't need to pass the frame 148 # self.should_skip = -1 # On cythonized version, put in instance. 149 # self.exc_info = () 150 # ELSE 151 should_skip = -1 # Default value in class (put in instance on set). 152 exc_info = () # Default value in class (put in instance on set). 153 154 def __init__(self, args): 155 # args = main_debugger, abs_path_canonical_path_and_base, base, info, t, frame 156 # yeap, much faster than putting in self and then getting it from self later on 157 self._args = args 158 # ENDIF 159 160 def set_suspend(self, *args, **kwargs): 161 self._args[0].set_suspend(*args, **kwargs) 162 163 def do_wait_suspend(self, *args, **kwargs): 164 self._args[0].do_wait_suspend(*args, **kwargs) 165 166 # IFDEF CYTHON 167 # def trace_exception(self, frame, str event, arg): 168 # cdef bint should_stop; 169 # cdef tuple exc_info; 170 # ELSE 171 def trace_exception(self, frame, event, arg): 172 # ENDIF 173 if event == 'exception': 174 should_stop, frame = self._should_stop_on_exception(frame, event, arg) 175 176 if should_stop: 177 if self._handle_exception(frame, event, arg, EXCEPTION_TYPE_HANDLED): 178 return self.trace_dispatch 179 180 elif event == 'return': 181 exc_info = self.exc_info 182 if exc_info and arg is None: 183 frame_skips_cache, frame_cache_key = self._args[4], self._args[5] 184 custom_key = (frame_cache_key, 'try_exc_info') 185 container_obj = frame_skips_cache.get(custom_key) 186 if container_obj is None: 187 container_obj = frame_skips_cache[custom_key] = _TryExceptContainerObj() 188 if is_unhandled_exception(container_obj, self._args[0], frame, exc_info[1], exc_info[2]) and \ 189 self.handle_user_exception(frame): 190 return self.trace_dispatch 191 192 return self.trace_exception 193 194 # IFDEF CYTHON 195 # cdef _should_stop_on_exception(self, frame, str event, arg): 196 # cdef PyDBAdditionalThreadInfo info; 197 # cdef bint should_stop; 198 # cdef bint was_just_raised; 199 # cdef list check_excs; 200 # ELSE 201 def _should_stop_on_exception(self, frame, event, arg): 202 # ENDIF 203 204 # main_debugger, _filename, info, _thread = self._args 205 main_debugger = self._args[0] 206 info = self._args[2] 207 should_stop = False 208 209 # STATE_SUSPEND = 2 210 if info.pydev_state != 2: # and breakpoint is not None: 211 exception, value, trace = arg 212 213 if trace is not None and hasattr(trace, 'tb_next'): 214 # on jython trace is None on the first event and it may not have a tb_next. 215 216 should_stop = False 217 exception_breakpoint = None 218 try: 219 if main_debugger.plugin is not None: 220 result = main_debugger.plugin.exception_break(main_debugger, self, frame, self._args, arg) 221 if result: 222 should_stop, frame = result 223 except: 224 pydev_log.exception() 225 226 if not should_stop: 227 # Apply checks that don't need the exception breakpoint (where we shouldn't ever stop). 228 if exception == SystemExit and main_debugger.ignore_system_exit_code(value): 229 pass 230 231 elif exception in (GeneratorExit, StopIteration, StopAsyncIteration): 232 # These exceptions are control-flow related (they work as a generator 233 # pause), so, we shouldn't stop on them. 234 pass 235 236 elif ignore_exception_trace(trace): 237 pass 238 239 else: 240 was_just_raised = trace.tb_next is None 241 242 # It was not handled by any plugin, lets check exception breakpoints. 243 check_excs = [] 244 245 # Note: check user unhandled before regular exceptions. 246 exc_break_user = main_debugger.get_exception_breakpoint( 247 exception, main_debugger.break_on_user_uncaught_exceptions) 248 if exc_break_user is not None: 249 check_excs.append((exc_break_user, True)) 250 251 exc_break_caught = main_debugger.get_exception_breakpoint( 252 exception, main_debugger.break_on_caught_exceptions) 253 if exc_break_caught is not None: 254 check_excs.append((exc_break_caught, False)) 255 256 for exc_break, is_user_uncaught in check_excs: 257 # Initially mark that it should stop and then go into exclusions. 258 should_stop = True 259 260 if main_debugger.exclude_exception_by_filter(exc_break, trace): 261 pydev_log.debug("Ignore exception %s in library %s -- (%s)" % (exception, frame.f_code.co_filename, frame.f_code.co_name)) 262 should_stop = False 263 264 elif exc_break.condition is not None and \ 265 not main_debugger.handle_breakpoint_condition(info, exc_break, frame): 266 should_stop = False 267 268 elif is_user_uncaught: 269 # Note: we don't stop here, we just collect the exc_info to use later on... 270 should_stop = False 271 if not main_debugger.apply_files_filter(frame, frame.f_code.co_filename, True) \ 272 and (frame.f_back is None or main_debugger.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True)): 273 # User uncaught means that we're currently in user code but the code 274 # up the stack is library code. 275 exc_info = self.exc_info 276 if not exc_info: 277 exc_info = (arg, frame.f_lineno, set([frame.f_lineno])) 278 else: 279 lines = exc_info[2] 280 lines.add(frame.f_lineno) 281 exc_info = (arg, frame.f_lineno, lines) 282 self.exc_info = exc_info 283 else: 284 # I.e.: these are only checked if we're not dealing with user uncaught exceptions. 285 if exc_break.notify_on_first_raise_only and main_debugger.skip_on_exceptions_thrown_in_same_context \ 286 and not was_just_raised and not just_raised(trace.tb_next): 287 # In this case we never stop if it was just raised, so, to know if it was the first we 288 # need to check if we're in the 2nd method. 289 should_stop = False # I.e.: we stop only when we're at the caller of a method that throws an exception 290 291 elif exc_break.notify_on_first_raise_only and not main_debugger.skip_on_exceptions_thrown_in_same_context \ 292 and not was_just_raised: 293 should_stop = False # I.e.: we stop only when it was just raised 294 295 elif was_just_raised and main_debugger.skip_on_exceptions_thrown_in_same_context: 296 # Option: Don't break if an exception is caught in the same function from which it is thrown 297 should_stop = False 298 299 if should_stop: 300 exception_breakpoint = exc_break 301 try: 302 info.pydev_message = exc_break.qname 303 except: 304 info.pydev_message = exc_break.qname.encode('utf-8') 305 break 306 307 if should_stop: 308 # Always add exception to frame (must remove later after we proceed). 309 add_exception_to_frame(frame, (exception, value, trace)) 310 311 if exception_breakpoint is not None and exception_breakpoint.expression is not None: 312 main_debugger.handle_breakpoint_expression(exception_breakpoint, info, frame) 313 314 return should_stop, frame 315 316 def handle_user_exception(self, frame): 317 exc_info = self.exc_info 318 if exc_info: 319 return self._handle_exception(frame, 'exception', exc_info[0], EXCEPTION_TYPE_USER_UNHANDLED) 320 return False 321 322 # IFDEF CYTHON 323 # cdef _handle_exception(self, frame, str event, arg, str exception_type): 324 # cdef bint stopped; 325 # cdef tuple abs_real_path_and_base; 326 # cdef str absolute_filename; 327 # cdef str canonical_normalized_filename; 328 # cdef dict filename_to_lines_where_exceptions_are_ignored; 329 # cdef dict lines_ignored; 330 # cdef dict frame_id_to_frame; 331 # cdef dict merged; 332 # cdef object trace_obj; 333 # cdef object main_debugger; 334 # ELSE 335 def _handle_exception(self, frame, event, arg, exception_type): 336 # ENDIF 337 stopped = False 338 try: 339 # print('_handle_exception', frame.f_lineno, frame.f_code.co_name) 340 341 # We have 3 things in arg: exception type, description, traceback object 342 trace_obj = arg[2] 343 main_debugger = self._args[0] 344 345 initial_trace_obj = trace_obj 346 if trace_obj.tb_next is None and trace_obj.tb_frame is frame: 347 # 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). 348 pass 349 else: 350 # Get the trace_obj from where the exception was raised... 351 while trace_obj.tb_next is not None: 352 trace_obj = trace_obj.tb_next 353 354 if main_debugger.ignore_exceptions_thrown_in_lines_with_ignore_exception: 355 for check_trace_obj in (initial_trace_obj, trace_obj): 356 abs_real_path_and_base = get_abs_path_real_path_and_base_from_frame(check_trace_obj.tb_frame) 357 absolute_filename = abs_real_path_and_base[0] 358 canonical_normalized_filename = abs_real_path_and_base[1] 359 360 filename_to_lines_where_exceptions_are_ignored = self.filename_to_lines_where_exceptions_are_ignored 361 362 lines_ignored = filename_to_lines_where_exceptions_are_ignored.get(canonical_normalized_filename) 363 if lines_ignored is None: 364 lines_ignored = filename_to_lines_where_exceptions_are_ignored[canonical_normalized_filename] = {} 365 366 try: 367 curr_stat = os.stat(absolute_filename) 368 curr_stat = (curr_stat.st_size, curr_stat.st_mtime) 369 except: 370 curr_stat = None 371 372 last_stat = self.filename_to_stat_info.get(absolute_filename) 373 if last_stat != curr_stat: 374 self.filename_to_stat_info[absolute_filename] = curr_stat 375 lines_ignored.clear() 376 try: 377 linecache.checkcache(absolute_filename) 378 except: 379 # Jython 2.1 380 linecache.checkcache() 381 382 from_user_input = main_debugger.filename_to_lines_where_exceptions_are_ignored.get(canonical_normalized_filename) 383 if from_user_input: 384 merged = {} 385 merged.update(lines_ignored) 386 # Override what we have with the related entries that the user entered 387 merged.update(from_user_input) 388 else: 389 merged = lines_ignored 390 391 exc_lineno = check_trace_obj.tb_lineno 392 393 # print ('lines ignored', lines_ignored) 394 # print ('user input', from_user_input) 395 # print ('merged', merged, 'curr', exc_lineno) 396 397 if exc_lineno not in merged: # Note: check on merged but update lines_ignored. 398 try: 399 line = linecache.getline(absolute_filename, exc_lineno, check_trace_obj.tb_frame.f_globals) 400 except: 401 # Jython 2.1 402 line = linecache.getline(absolute_filename, exc_lineno) 403 404 if IGNORE_EXCEPTION_TAG.match(line) is not None: 405 lines_ignored[exc_lineno] = 1 406 return False 407 else: 408 # Put in the cache saying not to ignore 409 lines_ignored[exc_lineno] = 0 410 else: 411 # Ok, dict has it already cached, so, let's check it... 412 if merged.get(exc_lineno, 0): 413 return False 414 415 thread = self._args[3] 416 417 try: 418 frame_id_to_frame = {} 419 frame_id_to_frame[id(frame)] = frame 420 f = trace_obj.tb_frame 421 while f is not None: 422 frame_id_to_frame[id(f)] = f 423 f = f.f_back 424 f = None 425 426 stopped = True 427 main_debugger.send_caught_exception_stack(thread, arg, id(frame)) 428 try: 429 self.set_suspend(thread, CMD_STEP_CAUGHT_EXCEPTION) 430 self.do_wait_suspend(thread, frame, event, arg, exception_type=exception_type) 431 finally: 432 main_debugger.send_caught_exception_stack_proceeded(thread) 433 except: 434 pydev_log.exception() 435 436 main_debugger.set_trace_for_frame_and_parents(frame) 437 finally: 438 # Make sure the user cannot see the '__exception__' we added after we leave the suspend state. 439 remove_exception_from_frame(frame) 440 # Clear some local variables... 441 frame = None 442 trace_obj = None 443 initial_trace_obj = None 444 check_trace_obj = None 445 f = None 446 frame_id_to_frame = None 447 main_debugger = None 448 thread = None 449 450 return stopped 451 452 # IFDEF CYTHON 453 # cdef get_func_name(self, frame): 454 # cdef str func_name 455 # ELSE 456 def get_func_name(self, frame): 457 # ENDIF 458 code_obj = frame.f_code 459 func_name = code_obj.co_name 460 try: 461 cls_name = get_clsname_for_code(code_obj, frame) 462 if cls_name is not None: 463 return "%s.%s" % (cls_name, func_name) 464 else: 465 return func_name 466 except: 467 pydev_log.exception() 468 return func_name 469 470 # IFDEF CYTHON 471 # cdef _show_return_values(self, frame, arg): 472 # ELSE 473 def _show_return_values(self, frame, arg): 474 # ENDIF 475 try: 476 try: 477 f_locals_back = getattr(frame.f_back, "f_locals", None) 478 if f_locals_back is not None: 479 return_values_dict = f_locals_back.get(RETURN_VALUES_DICT, None) 480 if return_values_dict is None: 481 return_values_dict = {} 482 f_locals_back[RETURN_VALUES_DICT] = return_values_dict 483 name = self.get_func_name(frame) 484 return_values_dict[name] = arg 485 except: 486 pydev_log.exception() 487 finally: 488 f_locals_back = None 489 490 # IFDEF CYTHON 491 # cdef _remove_return_values(self, main_debugger, frame): 492 # ELSE 493 def _remove_return_values(self, main_debugger, frame): 494 # ENDIF 495 try: 496 try: 497 # Showing return values was turned off, we should remove them from locals dict. 498 # The values can be in the current frame or in the back one 499 frame.f_locals.pop(RETURN_VALUES_DICT, None) 500 501 f_locals_back = getattr(frame.f_back, "f_locals", None) 502 if f_locals_back is not None: 503 f_locals_back.pop(RETURN_VALUES_DICT, None) 504 except: 505 pydev_log.exception() 506 finally: 507 f_locals_back = None 508 509 # IFDEF CYTHON 510 # cdef _get_unfiltered_back_frame(self, main_debugger, frame): 511 # ELSE 512 def _get_unfiltered_back_frame(self, main_debugger, frame): 513 # ENDIF 514 f = frame.f_back 515 while f is not None: 516 if not main_debugger.is_files_filter_enabled: 517 return f 518 519 else: 520 if main_debugger.apply_files_filter(f, f.f_code.co_filename, False): 521 f = f.f_back 522 523 else: 524 return f 525 526 return f 527 528 # IFDEF CYTHON 529 # cpdef trace_dispatch(self, frame, str event, arg): 530 # cdef tuple abs_path_canonical_path_and_base; 531 # cdef bint is_exception_event; 532 # cdef bint has_exception_breakpoints; 533 # cdef bint can_skip; 534 # cdef bint stop; 535 # cdef PyDBAdditionalThreadInfo info; 536 # cdef int step_cmd; 537 # cdef int line; 538 # cdef bint is_line; 539 # cdef bint is_call; 540 # cdef bint is_return; 541 # cdef bint should_stop; 542 # cdef dict breakpoints_for_file; 543 # cdef dict stop_info; 544 # cdef str curr_func_name; 545 # cdef bint exist_result; 546 # cdef dict frame_skips_cache; 547 # cdef tuple frame_cache_key; 548 # cdef tuple line_cache_key; 549 # cdef int breakpoints_in_line_cache; 550 # cdef int breakpoints_in_frame_cache; 551 # cdef bint has_breakpoint_in_frame; 552 # cdef bint is_coroutine_or_generator; 553 # cdef int bp_line; 554 # cdef object bp; 555 # cdef int pydev_smart_parent_offset 556 # cdef int pydev_smart_child_offset 557 # cdef tuple pydev_smart_step_into_variants 558 # ELSE 559 def trace_dispatch(self, frame, event, arg): 560 # ENDIF 561 # Note: this is a big function because most of the logic related to hitting a breakpoint and 562 # stepping is contained in it. Ideally this could be split among multiple functions, but the 563 # problem in this case is that in pure-python function calls are expensive and even more so 564 # when tracing is on (because each function call will get an additional tracing call). We 565 # try to address this by using the info.is_tracing for the fastest possible return, but the 566 # cost is still high (maybe we could use code-generation in the future and make the code 567 # generation be better split among what each part does). 568 569 # DEBUG = '_debugger_case_generator.py' in frame.f_code.co_filename 570 main_debugger, abs_path_canonical_path_and_base, info, thread, frame_skips_cache, frame_cache_key = self._args 571 # if DEBUG: print('frame trace_dispatch %s %s %s %s %s %s, stop: %s' % (frame.f_lineno, frame.f_code.co_name, frame.f_code.co_filename, event, constant_to_str(info.pydev_step_cmd), arg, info.pydev_step_stop)) 572 try: 573 info.is_tracing += 1 574 line = frame.f_lineno 575 line_cache_key = (frame_cache_key, line) 576 577 if main_debugger.pydb_disposed: 578 return None if event == 'call' else NO_FTRACE 579 580 plugin_manager = main_debugger.plugin 581 has_exception_breakpoints = ( 582 main_debugger.break_on_caught_exceptions 583 or main_debugger.break_on_user_uncaught_exceptions 584 or main_debugger.has_plugin_exception_breaks) 585 586 stop_frame = info.pydev_step_stop 587 step_cmd = info.pydev_step_cmd 588 function_breakpoint_on_call_event = None 589 590 if frame.f_code.co_flags & 0xa0: # 0xa0 == CO_GENERATOR = 0x20 | CO_COROUTINE = 0x80 591 # Dealing with coroutines and generators: 592 # When in a coroutine we change the perceived event to the debugger because 593 # a call, StopIteration exception and return are usually just pausing/unpausing it. 594 if event == 'line': 595 is_line = True 596 is_call = False 597 is_return = False 598 is_exception_event = False 599 600 elif event == 'return': 601 is_line = False 602 is_call = False 603 is_return = True 604 is_exception_event = False 605 606 returns_cache_key = (frame_cache_key, 'returns') 607 return_lines = frame_skips_cache.get(returns_cache_key) 608 if return_lines is None: 609 # Note: we're collecting the return lines by inspecting the bytecode as 610 # there are multiple returns and multiple stop iterations when awaiting and 611 # it doesn't give any clear indication when a coroutine or generator is 612 # finishing or just pausing. 613 return_lines = set() 614 for x in main_debugger.collect_return_info(frame.f_code): 615 # Note: cython does not support closures in cpdefs (so we can't use 616 # a list comprehension). 617 return_lines.add(x.return_line) 618 619 frame_skips_cache[returns_cache_key] = return_lines 620 621 if line not in return_lines: 622 # Not really a return (coroutine/generator paused). 623 return self.trace_dispatch 624 else: 625 if self.exc_info: 626 self.handle_user_exception(frame) 627 return self.trace_dispatch 628 629 # Tricky handling: usually when we're on a frame which is about to exit 630 # we set the step mode to step into, but in this case we'd end up in the 631 # asyncio internal machinery, which is not what we want, so, we just 632 # ask the stop frame to be a level up. 633 # 634 # Note that there's an issue here which we may want to fix in the future: if 635 # the back frame is a frame which is filtered, we won't stop properly. 636 # Solving this may not be trivial as we'd need to put a scope in the step 637 # in, but we may have to do it anyways to have a step in which doesn't end 638 # up in asyncio). 639 if stop_frame is frame: 640 if step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE): 641 f = self._get_unfiltered_back_frame(main_debugger, frame) 642 if f is not None: 643 info.pydev_step_cmd = CMD_STEP_INTO_COROUTINE 644 info.pydev_step_stop = f 645 else: 646 if step_cmd == CMD_STEP_OVER: 647 info.pydev_step_cmd = CMD_STEP_INTO 648 info.pydev_step_stop = None 649 650 elif step_cmd == CMD_STEP_OVER_MY_CODE: 651 info.pydev_step_cmd = CMD_STEP_INTO_MY_CODE 652 info.pydev_step_stop = None 653 654 elif step_cmd == CMD_STEP_INTO_COROUTINE: 655 # We're exiting this one, so, mark the new coroutine context. 656 f = self._get_unfiltered_back_frame(main_debugger, frame) 657 if f is not None: 658 info.pydev_step_stop = f 659 else: 660 info.pydev_step_cmd = CMD_STEP_INTO 661 info.pydev_step_stop = None 662 663 elif event == 'exception': 664 breakpoints_for_file = None 665 if has_exception_breakpoints: 666 should_stop, frame = self._should_stop_on_exception(frame, event, arg) 667 if should_stop: 668 if self._handle_exception(frame, event, arg, EXCEPTION_TYPE_HANDLED): 669 return self.trace_dispatch 670 671 return self.trace_dispatch 672 else: 673 # event == 'call' or event == 'c_XXX' 674 return self.trace_dispatch 675 676 else: 677 if event == 'line': 678 is_line = True 679 is_call = False 680 is_return = False 681 is_exception_event = False 682 683 elif event == 'return': 684 is_line = False 685 is_return = True 686 is_call = False 687 is_exception_event = False 688 689 # If we are in single step mode and something causes us to exit the current frame, we need to make sure we break 690 # eventually. Force the step mode to step into and the step stop frame to None. 691 # I.e.: F6 in the end of a function should stop in the next possible position (instead of forcing the user 692 # to make a step in or step over at that location). 693 # Note: this is especially troublesome when we're skipping code with the 694 # @DontTrace comment. 695 if stop_frame is frame and is_return and step_cmd in (CMD_STEP_OVER, CMD_STEP_RETURN, CMD_STEP_OVER_MY_CODE, CMD_STEP_RETURN_MY_CODE, CMD_SMART_STEP_INTO): 696 if step_cmd in (CMD_STEP_OVER, CMD_STEP_RETURN, CMD_SMART_STEP_INTO): 697 info.pydev_step_cmd = CMD_STEP_INTO 698 else: 699 info.pydev_step_cmd = CMD_STEP_INTO_MY_CODE 700 info.pydev_step_stop = None 701 702 if self.exc_info: 703 if self.handle_user_exception(frame): 704 return self.trace_dispatch 705 706 elif event == 'call': 707 is_line = False 708 is_call = True 709 is_return = False 710 is_exception_event = False 711 if frame.f_code.co_firstlineno == frame.f_lineno: # Check line to deal with async/await. 712 function_breakpoint_on_call_event = main_debugger.function_breakpoint_name_to_breakpoint.get(frame.f_code.co_name) 713 714 elif event == 'exception': 715 is_exception_event = True 716 breakpoints_for_file = None 717 if has_exception_breakpoints: 718 should_stop, frame = self._should_stop_on_exception(frame, event, arg) 719 if should_stop: 720 if self._handle_exception(frame, event, arg, EXCEPTION_TYPE_HANDLED): 721 return self.trace_dispatch 722 is_line = False 723 is_return = False 724 is_call = False 725 726 else: 727 # Unexpected: just keep the same trace func (i.e.: event == 'c_XXX'). 728 return self.trace_dispatch 729 730 if not is_exception_event: 731 breakpoints_for_file = main_debugger.breakpoints.get(abs_path_canonical_path_and_base[1]) 732 733 can_skip = False 734 735 if info.pydev_state == 1: # STATE_RUN = 1 736 # we can skip if: 737 # - we have no stop marked 738 # - we should make a step return/step over and we're not in the current frame 739 # - we're stepping into a coroutine context and we're not in that context 740 if step_cmd == -1: 741 can_skip = True 742 743 elif step_cmd in (CMD_STEP_OVER, CMD_STEP_RETURN, CMD_STEP_OVER_MY_CODE, CMD_STEP_RETURN_MY_CODE) and stop_frame is not frame: 744 can_skip = True 745 746 elif step_cmd == CMD_SMART_STEP_INTO and ( 747 stop_frame is not None and 748 stop_frame is not frame and 749 stop_frame is not frame.f_back and 750 (frame.f_back is None or stop_frame is not frame.f_back.f_back)): 751 can_skip = True 752 753 elif step_cmd == CMD_STEP_INTO_MY_CODE: 754 if ( 755 main_debugger.apply_files_filter(frame, frame.f_code.co_filename, True) 756 and (frame.f_back is None or main_debugger.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True)) 757 ): 758 can_skip = True 759 760 elif step_cmd == CMD_STEP_INTO_COROUTINE: 761 f = frame 762 while f is not None: 763 if f is stop_frame: 764 break 765 f = f.f_back 766 else: 767 can_skip = True 768 769 if can_skip: 770 if plugin_manager is not None and ( 771 main_debugger.has_plugin_line_breaks or main_debugger.has_plugin_exception_breaks): 772 can_skip = plugin_manager.can_skip(main_debugger, frame) 773 774 if can_skip and main_debugger.show_return_values and info.pydev_step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE) and frame.f_back is stop_frame: 775 # trace function for showing return values after step over 776 can_skip = False 777 778 # Let's check to see if we are in a function that has a breakpoint. If we don't have a breakpoint, 779 # we will return nothing for the next trace 780 # also, after we hit a breakpoint and go to some other debugging state, we have to force the set trace anyway, 781 # so, that's why the additional checks are there. 782 783 if function_breakpoint_on_call_event: 784 pass # Do nothing here (just keep on going as we can't skip it). 785 786 elif not breakpoints_for_file: 787 if can_skip: 788 if has_exception_breakpoints: 789 return self.trace_exception 790 else: 791 return None if is_call else NO_FTRACE 792 793 else: 794 # When cached, 0 means we don't have a breakpoint and 1 means we have. 795 if can_skip: 796 breakpoints_in_line_cache = frame_skips_cache.get(line_cache_key, -1) 797 if breakpoints_in_line_cache == 0: 798 return self.trace_dispatch 799 800 breakpoints_in_frame_cache = frame_skips_cache.get(frame_cache_key, -1) 801 if breakpoints_in_frame_cache != -1: 802 # Gotten from cache. 803 has_breakpoint_in_frame = breakpoints_in_frame_cache == 1 804 805 else: 806 has_breakpoint_in_frame = False 807 808 try: 809 func_lines = set() 810 for offset_and_lineno in dis.findlinestarts(frame.f_code): 811 func_lines.add(offset_and_lineno[1]) 812 except: 813 # This is a fallback for implementations where we can't get the function 814 # lines -- i.e.: jython (in this case clients need to provide the function 815 # name to decide on the skip or we won't be able to skip the function 816 # completely). 817 818 # Checks the breakpoint to see if there is a context match in some function. 819 curr_func_name = frame.f_code.co_name 820 821 # global context is set with an empty name 822 if curr_func_name in ('?', '<module>', '<lambda>'): 823 curr_func_name = '' 824 825 for bp in dict_iter_values(breakpoints_for_file): # jython does not support itervalues() 826 # will match either global or some function 827 if bp.func_name in ('None', curr_func_name): 828 has_breakpoint_in_frame = True 829 break 830 else: 831 for bp_line in breakpoints_for_file: # iterate on keys 832 if bp_line in func_lines: 833 has_breakpoint_in_frame = True 834 break 835 836 # Cache the value (1 or 0 or -1 for default because of cython). 837 if has_breakpoint_in_frame: 838 frame_skips_cache[frame_cache_key] = 1 839 else: 840 frame_skips_cache[frame_cache_key] = 0 841 842 if can_skip and not has_breakpoint_in_frame: 843 if has_exception_breakpoints: 844 return self.trace_exception 845 else: 846 return None if is_call else NO_FTRACE 847 848 # 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 849 # if DEBUG: print('NOT skipped: %s %s %s %s' % (frame.f_lineno, frame.f_code.co_name, event, frame.__class__.__name__)) 850 851 try: 852 flag = False 853 # return is not taken into account for breakpoint hit because we'd have a double-hit in this case 854 # (one for the line and the other for the return). 855 856 stop_info = {} 857 breakpoint = None 858 exist_result = False 859 stop = False 860 stop_reason = CMD_SET_BREAK 861 bp_type = None 862 863 if function_breakpoint_on_call_event: 864 breakpoint = function_breakpoint_on_call_event 865 stop = True 866 new_frame = frame 867 stop_reason = CMD_SET_FUNCTION_BREAK 868 869 elif not is_return and info.pydev_state != STATE_SUSPEND and breakpoints_for_file is not None and line in breakpoints_for_file: 870 breakpoint = breakpoints_for_file[line] 871 new_frame = frame 872 stop = True 873 if step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE) and (stop_frame is frame and is_line): 874 stop = False # we don't stop on breakpoint if we have to stop by step-over (it will be processed later) 875 elif plugin_manager is not None and main_debugger.has_plugin_line_breaks: 876 result = plugin_manager.get_breakpoint(main_debugger, self, frame, event, self._args) 877 if result: 878 exist_result = True 879 flag, breakpoint, new_frame, bp_type = result 880 881 if breakpoint: 882 # ok, hit breakpoint, now, we have to discover if it is a conditional breakpoint 883 # lets do the conditional stuff here 884 if stop or exist_result: 885 eval_result = False 886 if breakpoint.has_condition: 887 eval_result = main_debugger.handle_breakpoint_condition(info, breakpoint, new_frame) 888 889 if breakpoint.expression is not None: 890 main_debugger.handle_breakpoint_expression(breakpoint, info, new_frame) 891 if breakpoint.is_logpoint and info.pydev_message is not None and len(info.pydev_message) > 0: 892 cmd = main_debugger.cmd_factory.make_io_message(info.pydev_message + os.linesep, '1') 893 main_debugger.writer.add_command(cmd) 894 895 if breakpoint.has_condition: 896 if not eval_result: 897 stop = False 898 elif breakpoint.is_logpoint: 899 stop = False 900 901 if is_call and frame.f_code.co_name in ('<module>', '<lambda>'): 902 # If we find a call for a module, it means that the module is being imported/executed for the 903 # first time. In this case we have to ignore this hit as it may later duplicated by a 904 # line event at the same place (so, if there's a module with a print() in the first line 905 # the user will hit that line twice, which is not what we want). 906 # 907 # As for lambda, as it only has a single statement, it's not interesting to trace 908 # its call and later its line event as they're usually in the same line. 909 910 return self.trace_dispatch 911 912 if main_debugger.show_return_values: 913 if is_return and ( 914 (info.pydev_step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, CMD_SMART_STEP_INTO) and (frame.f_back is stop_frame)) or 915 (info.pydev_step_cmd in (CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE) and (frame is stop_frame)) or 916 (info.pydev_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_COROUTINE)) or 917 ( 918 info.pydev_step_cmd == CMD_STEP_INTO_MY_CODE 919 and frame.f_back is not None 920 and not main_debugger.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True) 921 ) 922 ): 923 self._show_return_values(frame, arg) 924 925 elif main_debugger.remove_return_values_flag: 926 try: 927 self._remove_return_values(main_debugger, frame) 928 finally: 929 main_debugger.remove_return_values_flag = False 930 931 if stop: 932 self.set_suspend( 933 thread, 934 stop_reason, 935 suspend_other_threads=breakpoint and breakpoint.suspend_policy == "ALL", 936 ) 937 938 elif flag and plugin_manager is not None: 939 result = plugin_manager.suspend(main_debugger, thread, frame, bp_type) 940 if result: 941 frame = result 942 943 # if thread has a suspend flag, we suspend with a busy wait 944 if info.pydev_state == STATE_SUSPEND: 945 self.do_wait_suspend(thread, frame, event, arg) 946 return self.trace_dispatch 947 else: 948 if not breakpoint and is_line: 949 # No stop from anyone and no breakpoint found in line (cache that). 950 frame_skips_cache[line_cache_key] = 0 951 952 except: 953 pydev_log.exception() 954 raise 955 956 # step handling. We stop when we hit the right frame 957 try: 958 should_skip = 0 959 if pydevd_dont_trace.should_trace_hook is not None: 960 if self.should_skip == -1: 961 # I.e.: cache the result on self.should_skip (no need to evaluate the same frame multiple times). 962 # Note that on a code reload, we won't re-evaluate this because in practice, the frame.f_code 963 # Which will be handled by this frame is read-only, so, we can cache it safely. 964 if not pydevd_dont_trace.should_trace_hook(frame, abs_path_canonical_path_and_base[0]): 965 # -1, 0, 1 to be Cython-friendly 966 should_skip = self.should_skip = 1 967 else: 968 should_skip = self.should_skip = 0 969 else: 970 should_skip = self.should_skip 971 972 plugin_stop = False 973 if should_skip: 974 stop = False 975 976 elif step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE, CMD_STEP_INTO_COROUTINE): 977 force_check_project_scope = step_cmd == CMD_STEP_INTO_MY_CODE 978 if is_line: 979 if force_check_project_scope or main_debugger.is_files_filter_enabled: 980 stop = not main_debugger.apply_files_filter(frame, frame.f_code.co_filename, force_check_project_scope) 981 else: 982 stop = True 983 984 elif is_return and frame.f_back is not None: 985 if main_debugger.get_file_type(frame.f_back) == main_debugger.PYDEV_FILE: 986 stop = False 987 else: 988 if force_check_project_scope or main_debugger.is_files_filter_enabled: 989 stop = not main_debugger.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, force_check_project_scope) 990 if stop: 991 # Prevent stopping in a return to the same location we were initially 992 # (i.e.: double-stop at the same place due to some filtering). 993 if info.step_in_initial_location == (frame.f_back, frame.f_back.f_lineno): 994 stop = False 995 else: 996 stop = True 997 else: 998 stop = False 999 1000 if stop: 1001 if step_cmd == CMD_STEP_INTO_COROUTINE: 1002 # i.e.: Check if we're stepping into the proper context. 1003 f = frame 1004 while f is not None: 1005 if f is stop_frame: 1006 break 1007 f = f.f_back 1008 else: 1009 stop = False 1010 1011 if plugin_manager is not None: 1012 result = plugin_manager.cmd_step_into(main_debugger, frame, event, self._args, stop_info, stop) 1013 if result: 1014 stop, plugin_stop = result 1015 1016 elif step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE): 1017 # Note: when dealing with a step over my code it's the same as a step over (the 1018 # difference is that when we return from a frame in one we go to regular step 1019 # into and in the other we go to a step into my code). 1020 stop = stop_frame is frame and is_line 1021 # Note: don't stop on a return for step over, only for line events 1022 # i.e.: don't stop in: (stop_frame is frame.f_back and is_return) as we'd stop twice in that line. 1023 1024 if plugin_manager is not None: 1025 result = plugin_manager.cmd_step_over(main_debugger, frame, event, self._args, stop_info, stop) 1026 if result: 1027 stop, plugin_stop = result 1028 1029 elif step_cmd == CMD_SMART_STEP_INTO: 1030 stop = False 1031 back = frame.f_back 1032 if stop_frame is frame and is_return: 1033 # We're exiting the smart step into initial frame (so, we probably didn't find our target). 1034 stop = True 1035 1036 elif stop_frame is back and is_line: 1037 if info.pydev_smart_child_offset != -1: 1038 # i.e.: in this case, we're not interested in the pause in the parent, rather 1039 # we're interested in the pause in the child (when the parent is at the proper place). 1040 stop = False 1041 1042 else: 1043 pydev_smart_parent_offset = info.pydev_smart_parent_offset 1044 1045 pydev_smart_step_into_variants = info.pydev_smart_step_into_variants 1046 if pydev_smart_parent_offset >= 0 and pydev_smart_step_into_variants: 1047 # Preferred mode (when the smart step into variants are available 1048 # and the offset is set). 1049 stop = get_smart_step_into_variant_from_frame_offset(back.f_lasti, pydev_smart_step_into_variants) is \ 1050 get_smart_step_into_variant_from_frame_offset(pydev_smart_parent_offset, pydev_smart_step_into_variants) 1051 1052 else: 1053 # Only the name/line is available, so, check that. 1054 curr_func_name = frame.f_code.co_name 1055 1056 # global context is set with an empty name 1057 if curr_func_name in ('?', '<module>') or curr_func_name is None: 1058 curr_func_name = '' 1059 if curr_func_name == info.pydev_func_name and stop_frame.f_lineno == info.pydev_next_line: 1060 stop = True 1061 1062 if not stop: 1063 # In smart step into, if we didn't hit it in this frame once, that'll 1064 # not be the case next time either, so, disable tracing for this frame. 1065 return None if is_call else NO_FTRACE 1066 1067 elif back is not None and stop_frame is back.f_back and is_line: 1068 # Ok, we have to track 2 stops at this point, the parent and the child offset. 1069 # This happens when handling a step into which targets a function inside a list comprehension 1070 # or generator (in which case an intermediary frame is created due to an internal function call). 1071 pydev_smart_parent_offset = info.pydev_smart_parent_offset 1072 pydev_smart_child_offset = info.pydev_smart_child_offset 1073 # print('matched back frame', pydev_smart_parent_offset, pydev_smart_child_offset) 1074 # print('parent f_lasti', back.f_back.f_lasti) 1075 # print('child f_lasti', back.f_lasti) 1076 stop = False 1077 if pydev_smart_child_offset >= 0 and pydev_smart_child_offset >= 0: 1078 pydev_smart_step_into_variants = info.pydev_smart_step_into_variants 1079 1080 if pydev_smart_parent_offset >= 0 and pydev_smart_step_into_variants: 1081 # Note that we don't really check the parent offset, only the offset of 1082 # the child (because this is a generator, the parent may have moved forward 1083 # already -- and that's ok, so, we just check that the parent frame 1084 # matches in this case). 1085 smart_step_into_variant = get_smart_step_into_variant_from_frame_offset(pydev_smart_parent_offset, pydev_smart_step_into_variants) 1086 # print('matched parent offset', pydev_smart_parent_offset) 1087 # Ok, now, check the child variant 1088 children_variants = smart_step_into_variant.children_variants 1089 stop = children_variants and ( 1090 get_smart_step_into_variant_from_frame_offset(back.f_lasti, children_variants) is \ 1091 get_smart_step_into_variant_from_frame_offset(pydev_smart_child_offset, children_variants) 1092 ) 1093 # print('stop at child', stop) 1094 1095 if not stop: 1096 # In smart step into, if we didn't hit it in this frame once, that'll 1097 # not be the case next time either, so, disable tracing for this frame. 1098 return None if is_call else NO_FTRACE 1099 1100 elif step_cmd in (CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE): 1101 stop = is_return and stop_frame is frame 1102 1103 else: 1104 stop = False 1105 1106 if stop and step_cmd != -1 and is_return and IS_PY3K and hasattr(frame, "f_back"): 1107 f_code = getattr(frame.f_back, 'f_code', None) 1108 if f_code is not None: 1109 if main_debugger.get_file_type(frame.f_back) == main_debugger.PYDEV_FILE: 1110 stop = False 1111 1112 if plugin_stop: 1113 stopped_on_plugin = plugin_manager.stop(main_debugger, frame, event, self._args, stop_info, arg, step_cmd) 1114 elif stop: 1115 if is_line: 1116 self.set_suspend(thread, step_cmd, original_step_cmd=info.pydev_original_step_cmd) 1117 self.do_wait_suspend(thread, frame, event, arg) 1118 elif is_return: # return event 1119 back = frame.f_back 1120 if back is not None: 1121 # When we get to the pydevd run function, the debugging has actually finished for the main thread 1122 # (note that it can still go on for other threads, but for this one, we just make it finish) 1123 # So, just setting it to None should be OK 1124 back_absolute_filename, _, base = get_abs_path_real_path_and_base_from_frame(back) 1125 if (base, back.f_code.co_name) in (DEBUG_START, DEBUG_START_PY3K): 1126 back = None 1127 1128 elif base == TRACE_PROPERTY: 1129 # We dont want to trace the return event of pydevd_traceproperty (custom property for debugging) 1130 # if we're in a return, we want it to appear to the user in the previous frame! 1131 return None if is_call else NO_FTRACE 1132 1133 elif pydevd_dont_trace.should_trace_hook is not None: 1134 if not pydevd_dont_trace.should_trace_hook(back, back_absolute_filename): 1135 # In this case, we'll have to skip the previous one because it shouldn't be traced. 1136 # Also, we have to reset the tracing, because if the parent's parent (or some 1137 # other parent) has to be traced and it's not currently, we wouldn't stop where 1138 # we should anymore (so, a step in/over/return may not stop anywhere if no parent is traced). 1139 # Related test: _debugger_case17a.py 1140 main_debugger.set_trace_for_frame_and_parents(back) 1141 return None if is_call else NO_FTRACE 1142 1143 if back is not None: 1144 # if we're in a return, we want it to appear to the user in the previous frame! 1145 self.set_suspend(thread, step_cmd, original_step_cmd=info.pydev_original_step_cmd) 1146 self.do_wait_suspend(thread, back, event, arg) 1147 else: 1148 # in jython we may not have a back frame 1149 info.pydev_step_stop = None 1150 info.pydev_original_step_cmd = -1 1151 info.pydev_step_cmd = -1 1152 info.pydev_state = STATE_RUN 1153 1154 except KeyboardInterrupt: 1155 raise 1156 except: 1157 try: 1158 pydev_log.exception() 1159 info.pydev_original_step_cmd = -1 1160 info.pydev_step_cmd = -1 1161 info.pydev_step_stop = None 1162 except: 1163 return None if is_call else NO_FTRACE 1164 1165 # if we are quitting, let's stop the tracing 1166 if main_debugger.quitting: 1167 return None if is_call else NO_FTRACE 1168 1169 return self.trace_dispatch 1170 finally: 1171 info.is_tracing -= 1 1172 1173 # end trace_dispatch 1174