Esempio n. 1
0
    def handle_exception(self, frame, event, arg):
        try:
            # print 'handle_exception', frame.f_lineno, frame.f_code.co_name

            # We have 3 things in arg: exception type, description, traceback object
            trace_obj = arg[2]
            mainDebugger = self._args[0]

            if not hasattr(trace_obj, 'tb_next'):
                return  #Not always there on Jython...

            initial_trace_obj = trace_obj
            if trace_obj.tb_next is None and trace_obj.tb_frame is frame:
                #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).

                if mainDebugger.break_on_exceptions_thrown_in_same_context:
                    #Option: Don't break if an exception is caught in the same function from which it is thrown
                    return
            else:
                #Get the trace_obj from where the exception was raised...
                while trace_obj.tb_next is not None:
                    trace_obj = trace_obj.tb_next


            if mainDebugger.ignore_exceptions_thrown_in_lines_with_ignore_exception:
                for check_trace_obj in (initial_trace_obj, trace_obj):
                    filename = GetFilenameAndBase(check_trace_obj.tb_frame)[0]


                    filename_to_lines_where_exceptions_are_ignored = self.filename_to_lines_where_exceptions_are_ignored


                    lines_ignored = filename_to_lines_where_exceptions_are_ignored.get(filename)
                    if lines_ignored is None:
                        lines_ignored = filename_to_lines_where_exceptions_are_ignored[filename] = {}

                    try:
                        curr_stat = os.stat(filename)
                        curr_stat = (curr_stat.st_size, curr_stat.st_mtime)
                    except:
                        curr_stat = None

                    last_stat = self.filename_to_stat_info.get(filename)
                    if last_stat != curr_stat:
                        self.filename_to_stat_info[filename] = curr_stat
                        lines_ignored.clear()
                        try:
                            linecache.checkcache(filename)
                        except:
                            #Jython 2.1
                            linecache.checkcache()

                    from_user_input = mainDebugger.filename_to_lines_where_exceptions_are_ignored.get(filename)
                    if from_user_input:
                        merged = {}
                        merged.update(lines_ignored)
                        #Override what we have with the related entries that the user entered
                        merged.update(from_user_input)
                    else:
                        merged = lines_ignored

                    exc_lineno = check_trace_obj.tb_lineno

                    # print ('lines ignored', lines_ignored)
                    # print ('user input', from_user_input)
                    # print ('merged', merged, 'curr', exc_lineno)

                    if not DictContains(merged, exc_lineno):  #Note: check on merged but update lines_ignored.
                        try:
                            line = linecache.getline(filename, exc_lineno, check_trace_obj.tb_frame.f_globals)
                        except:
                            #Jython 2.1
                            line = linecache.getline(filename, exc_lineno)

                        if IGNORE_EXCEPTION_TAG.match(line) is not None:
                            lines_ignored[exc_lineno] = 1
                            return
                        else:
                            #Put in the cache saying not to ignore
                            lines_ignored[exc_lineno] = 0
                    else:
                        #Ok, dict has it already cached, so, let's check it...
                        if merged.get(exc_lineno, 0):
                            return


            thread = self._args[3]

            try:
                frame_id_to_frame = {}
                frame_id_to_frame[id(frame)] = frame
                f = trace_obj.tb_frame
                while f is not None:
                    frame_id_to_frame[id(f)] = f
                    f = f.f_back
                f = None

                thread_id = GetThreadId(thread)
                pydevd_vars.addAdditionalFrameById(thread_id, frame_id_to_frame)
                try:
                    mainDebugger.sendCaughtExceptionStack(thread, arg, id(frame))
                    self.setSuspend(thread, CMD_STEP_CAUGHT_EXCEPTION)
                    self.doWaitSuspend(thread, frame, event, arg)
                    mainDebugger.sendCaughtExceptionStackProceeded(thread)

                finally:
                    pydevd_vars.removeAdditionalFrameById(thread_id)
            except:
                traceback.print_exc()

            mainDebugger.SetTraceForFrameAndParents(frame)
        finally:
            #Clear some local variables...
            trace_obj = None
            initial_trace_obj = None
            check_trace_obj = None
            f = None
            frame_id_to_frame = None
            mainDebugger = None
            thread = None
Esempio n. 2
0
    def trace_dispatch(self, frame, event, arg):
        ''' This is the callback used when we enter some context in the debugger. 
        
        We also decorate the thread we are in with info about the debugging.
        The attributes added are:
            pydev_state
            pydev_step_stop
            pydev_step_cmd
            pydev_notify_kill 
        '''
        try:
            if self._finishDebuggingSession:
                #that was not working very well because jython gave some socket errors
                threads = threadingEnumerate()
                for t in threads: 
                    if hasattr(t, 'doKill'):
                        t.doKill()
                return None
    
            filename, base = GetFilenameAndBase(frame)
    
            is_file_to_ignore = DictContains(DONT_TRACE, base) #we don't want to debug threading or anything related to pydevd
            
            if not self.force_post_mortem_stop: #If we're in post mortem mode, we might not have another chance to show that info!
                if is_file_to_ignore:
                    return None
                
            #print('trace_dispatch', base, frame.f_lineno, event, frame.f_code.co_name)
            try:
                #this shouldn't give an exception, but it could happen... (python bug)
                #see http://mail.python.org/pipermail/python-bugs-list/2007-June/038796.html
                #and related bug: http://bugs.python.org/issue1733757
                t = threadingCurrentThread()
            except:
                frame.f_trace = self.trace_dispatch
                return self.trace_dispatch
            
            try:
                additionalInfo = t.additionalInfo
            except:
                additionalInfo = t.additionalInfo = PyDBAdditionalThreadInfo()
            
            if self.force_post_mortem_stop: #If we're in post mortem mode, we might not have another chance to show that info!
                if additionalInfo.pydev_force_stop_at_exception:
                    self.force_post_mortem_stop -= 1
                    frame, frames_byid = additionalInfo.pydev_force_stop_at_exception
                    thread_id = GetThreadId(t)
                    used_id = pydevd_vars.addAdditionalFrameById(thread_id, frames_byid)
                    try:
                        self.setSuspend(t, CMD_STEP_INTO)
                        self.doWaitSuspend(t, frame, 'exception', None)
                    finally:
                        additionalInfo.pydev_force_stop_at_exception = None
                        pydevd_vars.removeAdditionalFrameById(thread_id)
            
            # if thread is not alive, cancel trace_dispatch processing
            if not t.isAlive():
                self.processThreadNotAlive(GetThreadId(t))
                return None # suspend tracing
            
            if is_file_to_ignore:
                return None

            #each new frame...
            return additionalInfo.CreateDbFrame(self, filename, additionalInfo, t, frame).trace_dispatch(frame, event, arg)
        
        except SystemExit:
            return None
        
        except Exception:
            #Log it
            traceback.print_exc()
            return None