Exemplo n.º 1
0
 def getThreadDebugLog(s, thread):
     if s.debugmessages.has_key(thread):
         message = "\nLast %d debug messages logged for %s prior to exception:\n"\
                    % (len(s.debugmessages[thread]), thread.getName())
         message += "\n".join(s.debugmessages[thread])
     else:
         message = "\nNo debug messages were logged for %s." % \
                   thread.getName()
     return message
Exemplo n.º 2
0
 def getThreadDebugLog(s, thread):
     if s.debugmessages.has_key(thread):
         message = "\nLast %d debug messages logged for %s prior to exception:\n"\
                    % (len(s.debugmessages[thread]), thread.getName())
         message += "\n".join(s.debugmessages[thread])
     else:
         message = "\nNo debug messages were logged for %s." % \
                   thread.getName()
     return message
Exemplo n.º 3
0
 def _registerThread(self, thread):
   "Called by thread classes when a thread is created."
   assert(isinstance(thread, ManagedThread))
   self._listLock.acquire()
   try:
     assert(not thread.getName() in self._activeThreads)
     debug(Debug, "Registering " + thread.getName() + " thread")
     self._activeThreads[thread.getName()] = thread
     debug(Debug, self.summary())
   finally:
     self._listLock.release()
Exemplo n.º 4
0
 def _registerThread(self, thread):
     "Called by thread classes when a thread is created."
     assert (isinstance(thread, ManagedThread))
     self._listLock.acquire()
     try:
         assert (not thread.getName() in self._activeThreads)
         debug(Debug, "Registering " + thread.getName() + " thread")
         self._activeThreads[thread.getName()] = thread
         debug(Debug, self.summary())
     finally:
         self._listLock.release()
Exemplo n.º 5
0
    def active_threads(self):
        """Returns an iterator over all current stack frames for all
        active threads in the process. The result for each is a tuple
        consisting of the thread identifier, a categorisation of the
        type of thread, and the stack frame. Note that we actually treat
        any greenlets as threads as well. In that case the thread ID is
        the id() of the greenlet.

        This is in this class for convenience as needs to access the
        currently active transactions to categorise transaction threads
        as being for web transactions or background tasks.

        """
        # TODO  返回活线程信息

        # First yield up those for real Python threads.
        # TODO 返回一个字典,将每个线程的标识符映射到调用该函数时该线程中当前活动的最顶层堆栈帧
        for thread_id, frame in sys._current_frames().items():
            trace = self._cache.get(thread_id)
            transaction = trace and trace.transaction
            if transaction is not None:
                if transaction.background_task:  # TODO 如果是后台队列任务,非Web事物
                    yield transaction, thread_id, 'BACKGROUND', frame
                else:
                    yield transaction, thread_id, 'REQUEST', frame  # TODO Web事物
            else:
                # Note that there may not always be a thread object.
                # This is because thread could have been created direct
                # against the thread module rather than via the high
                # level threading module. Categorise anything we can't
                # obtain a name for as being 'OTHER'.

                thread = threading._active.get(thread_id)
                if thread is not None and thread.getName().startswith('NR-'):
                    yield None, thread_id, 'AGENT', frame
                else:
                    yield None, thread_id, 'OTHER', frame

        # Now yield up those corresponding to greenlets. Right now only
        # doing this for greenlets in which any active transactions are
        # running. We don't have a way of knowing what non transaction
        # threads are running.

        debug = global_settings().debug

        # TODO 启用协程分析
        if debug.enable_coroutine_profiling:
            for thread_id, trace in self._cache.items():
                transaction = trace.transaction
                if transaction and transaction._greenlet is not None:
                    gr = transaction._greenlet(
                    )  # TODO !!!!!!这一块要弄懂,还是要仔细了解下greenlet框架
                    if gr and gr.gr_frame is not None:
                        if transaction.background_task:
                            yield (transaction, thread_id, 'BACKGROUND',
                                   gr.gr_frame)
                        else:
                            yield (transaction, thread_id, 'REQUEST',
                                   gr.gr_frame)
Exemplo n.º 6
0
 def unstartedThreads(self):
   self._listLock.acquire()
   try:
     ret = []
     for thread in self._activeThreads.values():
       if not thread.getName() in self._startedThreads:
         ret.append(thread)
     return ret
   finally:
     self._listLock.release()
Exemplo n.º 7
0
 def unstartedThreads(self):
     self._listLock.acquire()
     try:
         ret = []
         for thread in self._activeThreads.values():
             if not thread.getName() in self._startedThreads:
                 ret.append(thread)
         return ret
     finally:
         self._listLock.release()
    def active_threads(self):
        """Returns an iterator over all current stack frames for all
        active threads in the process. The result for each is a tuple
        consisting of the thread identifier, a categorisation of the
        type of thread, and the stack frame. Note that we actually treat
        any greenlets as threads as well. In that case the thread ID is
        the id() of the greenlet.

        This is in this class for convenience as needs to access the
        currently active transactions to categorise transaction threads
        as being for web transactions or background tasks.

        """

        # First yield up those for real Python threads.

        for thread_id, frame in sys._current_frames().items():
            transaction = self._cache.get(thread_id)
            if transaction is not None:
                if transaction.background_task:
                    yield transaction, thread_id, 'BACKGROUND', frame
                else:
                    yield transaction, thread_id, 'REQUEST', frame
            else:
                # Note that there may not always be a thread object.
                # This is because thread could have been created direct
                # against the thread module rather than via the high
                # level threading module. Categorise anything we can't
                # obtain a name for as being 'OTHER'.

                thread = threading._active.get(thread_id)
                if thread is not None and thread.getName().startswith('NR-'):
                    yield None, thread_id, 'AGENT', frame
                else:
                    yield None, thread_id, 'OTHER', frame

        # Now yield up those corresponding to greenlets. Right now only
        # doing this for greenlets in which any active transactions are
        # running. We don't have a way of knowing what non transaction
        # threads are running.

        debug = global_settings().debug

        if debug.enable_coroutine_profiling:
            for thread_id, transaction in self._cache.items():
                if transaction._greenlet is not None:
                    gr = transaction._greenlet()
                    if gr and gr.gr_frame is not None:
                        if transaction.background_task:
                            yield (transaction, thread_id,
                                    'BACKGROUND', gr.gr_frame)
                        else:
                            yield (transaction, thread_id,
                                    'REQUEST', gr.gr_frame)
Exemplo n.º 9
0
 def runningThreads(self):
   self._listLock.acquire()
   try:
     ret = []
     for thread in self._startedThreads.values():
       if not thread.getName() in [
         te[0].getName() for te in self._threadTerminations]:
         ret.append(thread)
     return ret
   finally:
     self._listLock.release()
Exemplo n.º 10
0
 def runningThreads(self):
     self._listLock.acquire()
     try:
         ret = []
         for thread in self._startedThreads.values():
             if not thread.getName() in [
                     te[0].getName() for te in self._threadTerminations
             ]:
                 ret.append(thread)
         return ret
     finally:
         self._listLock.release()
Exemplo n.º 11
0
    def store_exception(exc_info=None, thread=None):
        if exc_info == None:
            exc_info = sys.exc_info()

        if thread == None:
            thread = threading.currentThread()

        name = thread.getName()
        info = ""
        if hasattr(thread, 'threadinfo'):
            info = thread.threadinfo
        desc = "%s (%s)" % (name, info)

        maxtracebacks = 10
        CrashStore.exceptions.append((exc_info, time.time(), desc), )
        while len(CrashStore.exceptions) > maxtracebacks:
            CrashStore.exceptions.pop(0)
Exemplo n.º 12
0
    def store_exception(exc_info=None, thread=None):
        if exc_info == None:
            exc_info = sys.exc_info()

        if thread == None:
            thread = threading.currentThread()

        name = thread.getName()
        info = ""
        if hasattr(thread, 'threadinfo'):
            info = thread.threadinfo
        desc = "%s (%s)" % (name, info)

        maxtracebacks = 10
        CrashStore.exceptions.append((exc_info, time.time(), desc),)
        while len(CrashStore.exceptions) > maxtracebacks:
            CrashStore.exceptions.pop(0)
Exemplo n.º 13
0
 def threadException(s, thread):
     print s.getThreadExceptionString(thread)
     s._printData('threadException', "%s\n%s" % \
                  (thread.getName(), s.getThreadExceptionString(thread)))
     s.delThreadDebugLog(thread)
     s.terminate(100)
Exemplo n.º 14
0
 def getThreadExceptionString(s, thread):
     message = "Thread '%s' terminated with exception:\n%s" % \
               (thread.getName(), thread.getExitStackTrace())
     message += "\n" + s.getThreadDebugLog(thread)
     return message
Exemplo n.º 15
0
class ThreadManager(object):
    """Singleton class for managing active python threads."""
    def __init__(self):
        self._activeThreads = {}
        self._startedThreads = {}
        self._threadTerminations = []
        self._pidErrors = 0
        # Protects the three lists above
        self._listLock = threading.RLock()
        self._threadTerminationQueue = Queue.Queue()
        debug(Debug, self.summary())

    def _registerThread(self, thread):
        "Called by thread classes when a thread is created."
        assert (isinstance(thread, ManagedThread))
        self._listLock.acquire()
        try:
            assert (not thread.getName() in self._activeThreads)
            debug(Debug, "Registering " + thread.getName() + " thread")
            self._activeThreads[thread.getName()] = thread
            debug(Debug, self.summary())
        finally:
            self._listLock.release()

    def _registerThreadStart(self, thread):
        "Called by the thread classes' run method."
        assert (isinstance(thread, ManagedThread))
        self._listLock.acquire()
        try:
            assert (thread.getName() in self._activeThreads)
            assert (not thread.getName() in self._startedThreads)
            debug(Debug, "Registering " + thread.getName() + " thread start")
            self._startedThreads[thread.getName()] = thread
            debug(Debug, self.summary())
        finally:
            self._listLock.release()

    def _registerResult(self, thread, exceptionInfo):
        self._threadTerminationQueue.put((thread.getName(), exceptionInfo))

    def runningThreads(self):
        self._listLock.acquire()
        try:
            ret = []
            for thread in self._startedThreads.values():
                if not thread.getName() in [
                        te[0].getName() for te in self._threadTerminations
                ]:
                    ret.append(thread)
            return ret
        finally:
            self._listLock.release()

    def unstartedThreads(self):
        self._listLock.acquire()
        try:
            ret = []
            for thread in self._activeThreads.values():
                if not thread.getName() in self._startedThreads:
                    ret.append(thread)
            return ret
        finally:
            self._listLock.release()

    def numThreadsLeft(self):
        return len(self.unfinishedThreads())

    def unfinishedThreads(self):
        "Return created threads that have not terminated."
        self._listLock.acquire()
        try:
            return self._activeThreads.values()
        finally:
            self._listLock.release()

    def waitAll(self, timeout=3600, mourningTime=5):
        "Wait for all threads to terminate."
        debug(MajorEvent, "Waiting for all test threads to terminate")
        debug(MinorEvent, self.summary())
        limit = time.time() + timeout
        while self.numThreadsLeft() > 0:
            try:
                nextTimeout = limit - time.time()
                if nextTimeout <= 0:
                    raise chakana.error.Timeout(self.unfinishedThreads()[0],
                                                timeout)
                else:
                    self.waitOne(nextTimeout)
            except chakana.error.Timeout, err:
                debug(
                    Error, "Timeout waiting for " + err.child.getName() +
                    " thread, killing subprocesses.")
                self.killAll()
                while self.numThreadsLeft() > 0:
                    try:
                        self.waitOne(mourningTime)
                    except chakana.error.Timeout:
                        debug(Error,
                              "Timeout while mourning threads, aborting")
                        signal.signal(signal.SIGABRT, signal.SIG_DFL)
                        os.abort()
                raise
        debug(
            MinorEvent,
            "Done waiting for " + str(len(self._startedThreads)) + " threads")
        debug(Debug, self.summary())
        for (thread, excInfo) in self._threadTerminations:
            if not excInfo is None:
                debug(
                    MinorEvent, "Rethrowing exception from " +
                    thread.getName() + " thread")
                raise chakana.error.ChildException(excInfo[1], excInfo)
Exemplo n.º 16
0
 def threadExited(s, thread):
     s._printData('threadExited', thread.getName())
     UIBase.threadExited(s, thread)
Exemplo n.º 17
0
 def unregisterthread(s, thread):
     UIBase.unregisterthread(s, thread)
     s._printData('unregisterthread', thread.getName())
Exemplo n.º 18
0
 def _registerResult(self, thread, exceptionInfo):
   self._threadTerminationQueue.put((thread.getName(), exceptionInfo))
Exemplo n.º 19
0
 def getThreadExceptionString(s, thread):
     message = "Thread '%s' terminated with exception:\n%s" % \
               (thread.getName(), thread.getExitStackTrace())
     message += "\n" + s.getThreadDebugLog(thread)
     return message
Exemplo n.º 20
0
 def _registerResult(self, thread, exceptionInfo):
     self._threadTerminationQueue.put((thread.getName(), exceptionInfo))