Пример #1
0
 def __init__(self):
     self._statProcessTree = StatProcessTree()
     self._unfinishedResult = {}
     self._futexHolderPid = {}
     self._futexWaiterPids = defaultdict(list)
     self._pluginOptionDict = {}
     self._outputFile = sys.stdout
Пример #2
0
 def __init__(self):
     self._statProcessTree = StatProcessTree()
     self._lastSyscallStore = defaultdict(deque)
     self._lastSyscallTime = {}
Пример #3
0
class StatLastSyscall(StatBase):
    """ Find the last few unfinished syscall of process  """
    def __init__(self):
        self._statProcessTree = StatProcessTree()
        self._lastSyscallStore = defaultdict(deque)
        self._lastSyscallTime = {}

    def isOperational(self, straceOptions):
        self._straceOptions = straceOptions
        return True

    def getSyscallHooks(self):
        if self._straceOptions["havePid"]:
            return self._statProcessTree.getSyscallHooks()
        else:
            return None

    def getRawSyscallHooks(self):
        return {"ALL": self.funcHandleALLSyscall}

    def _reconstructStraceLine(self, result):
        # recontruct the strace line
        if self._straceOptions["haveTime"]:
            syscallLine = result["startTime"].strftime("%H:%M:%S.%f") + " "
        else:
            syscallLine = ""
        syscallLine += "{0} (".format(result["syscall"]) + ", ".join(
            [str(a) for a in result["args"]])
        if result["type"] == "unfinished":
            syscallLine += " <unfinished ...>"
        else:
            syscallLine += ")"
            # pad some space before return value if it is too short
            # in order to match to original strace output
            syscallLine = "{0:<39} = {1}".format(syscallLine, result["return"])
        return syscallLine

    def funcHandleALLSyscall(self, result):
        if self._straceOptions["havePid"]:
            pid = result["pid"]
        else:
            pid = 0

        # store the last syscall time
        if self._straceOptions["haveTime"]:
            syscallTime = result["startTime"]
            self._lastSyscallTime[pid] = syscallTime
            self._latestTime = syscallTime

        self._lastSyscallStore[pid].append(result)
        if len(self._lastSyscallStore[pid]) > 3:  # store last 3 syscalls
            self._lastSyscallStore[pid].popleft()

    def printOutput(self):
        for pid, syscallList in self._lastSyscallStore.iteritems():
            if self._straceOptions["haveTime"]:
                waitTime = self._latestTime - self._lastSyscallTime[pid]
            else:
                waitTime = ""
            # Ignore all the exited process
            if "exit" not in syscallList[-1]["syscall"]:
                #print pid, self._statProcessTree.getProcessExecName(pid), waitTime
                #for syscallResult in syscallList:
                #    print "   ", self._reconstructStraceLine(syscallResult)
                print pid, waitTime, self._reconstructStraceLine(
                    syscallList[-1])
Пример #4
0
 def __init__(self):
     self._statProcessTree = StatProcessTree()
     self._lastSyscallStore = defaultdict(deque)
     self._lastSyscallTime = {}
Пример #5
0
class StatLastSyscall(StatBase):
    """ Find the last few unfinished syscall of process  """

    def __init__(self):
        self._statProcessTree = StatProcessTree()
        self._lastSyscallStore = defaultdict(deque)
        self._lastSyscallTime = {}

    def isOperational(self, straceOptions):
        self._straceOptions = straceOptions
        return True

    def getSyscallHooks(self):
        if self._straceOptions["havePid"]:
            return self._statProcessTree.getSyscallHooks()
        else:
            return None

    def getRawSyscallHooks(self):
        return {"ALL": self.funcHandleALLSyscall}

    def _reconstructStraceLine(self, result):
        # recontruct the strace line
        if self._straceOptions["haveTime"]:
            syscallLine = result["startTime"].strftime("%H:%M:%S.%f") + " "
        else:
            syscallLine = ""
        syscallLine += "{0} (".format(result["syscall"]) + ", ".join([str(a) for a in result["args"]])
        if result["type"] == "unfinished":
            syscallLine += " <unfinished ...>"
        else:
            syscallLine += ")"
            # pad some space before return value if it is too short
            # in order to match to original strace output
            syscallLine = "{0:<39} = {1}".format(syscallLine, result["return"])
        return syscallLine


    def funcHandleALLSyscall(self, result):
        if self._straceOptions["havePid"]:
            pid = result["pid"]
        else:
            pid = 0
        
        # store the last syscall time
        if self._straceOptions["haveTime"]:
            syscallTime = result["startTime"]
            self._lastSyscallTime[pid] = syscallTime
            self._latestTime = syscallTime

        self._lastSyscallStore[pid].append(result)
        if len(self._lastSyscallStore[pid]) > 3:    # store last 3 syscalls
            self._lastSyscallStore[pid].popleft()


    def printOutput(self):
        for pid, syscallList in self._lastSyscallStore.iteritems():
            if self._straceOptions["haveTime"]:
                waitTime = self._latestTime - self._lastSyscallTime[pid]
            else:
                waitTime = ""
            # Ignore all the exited process
            if "exit" not in syscallList[-1]["syscall"]:
                #print pid, self._statProcessTree.getProcessExecName(pid), waitTime
                #for syscallResult in syscallList:
                #    print "   ", self._reconstructStraceLine(syscallResult)
                print pid, waitTime, self._reconstructStraceLine(syscallList[-1])
Пример #6
0
 def __init__(self):
     self._statProcessTree = StatProcessTree()
     self._unfinishedResult = {}
     self._futexHolderPid = {}
     self._futexWaiterPids = defaultdict(list)
Пример #7
0
class StatFutex(StatBase):
    """ Get futex related info  """

    def __init__(self):
        self._statProcessTree = StatProcessTree()
        self._unfinishedResult = {}
        self._futexHolderPid = {}
        self._futexWaiterPids = defaultdict(list)

    def isOperational(self, straceOptions):
        self._straceOptions = straceOptions
        return True

    def getSyscallHooks(self):
        if self._straceOptions["havePid"]:
            return self._statProcessTree.getSyscallHooks()
        else:
            return None

    def getRawSyscallHooks(self):
        if self._straceOptions["havePid"]:
            return {"futex": self.funcHandleFutexSyscall}
        return None

    def funcHandleFutexSyscall(self, result):
        #print result
        pid = result["pid"]
        syscallType = result["type"]
        timeStr = result["startTime"].time()

        if syscallType == "resumed":
            # if this is a resume syscall, combine it with last unfinished syscall of this pid
            lastResult = self._unfinishedResult[pid]
            lastResult["return"] = result["return"]
            lastResult["args"].append(result["args"])
            lastResult["type"] = "completed"
            result = lastResult
        elif syscallType == "unfinished":
            self._unfinishedResult[pid] = result

        futexAddress = result["args"][0]
        futexOp = result["args"][1]
        if "FUTEX_WAIT" in futexOp:
            if syscallType == "unfinished": # wait on a futex
                # add myself in waiter list
                self._futexWaiterPids[futexAddress].append(pid)

                print "{0} pid:{1} wait        futex:{2}, current holder:{3}, waiting list:{4}".format(
                       timeStr, pid, futexAddress, 
                       self._futexHolderPid[futexAddress] if futexAddress in self._futexHolderPid else "Unknown", 
                       self._futexWaiterPids[futexAddress])

            else: # completed or resumed = being wake up or timeout
                # remove myself from futexWaiterPids
                if futexAddress in self._futexWaiterPids:
                    if pid in self._futexWaiterPids[futexAddress]:
                        self._futexWaiterPids[futexAddress].remove(pid)

                returnValue = result["return"]
                if int(returnValue) == 0: # being wake up
                    self._futexHolderPid[futexAddress] = pid    # I am the holder now
                    print "{0} pid:{1} hold        futex:{2}, waiting list:{3}".format(
                           timeStr, pid, futexAddress, 
                           self._futexWaiterPids[futexAddress])
                else:                # timeout 
                    print "{0} pid:{1} timeout     futex:{2}".format(timeStr, pid, futexAddress)
                    #TODO: many different cases in man page

        if "FUTEX_WAKE" in futexOp:
            self._futexHolderPid[futexAddress] = None
            print "{0} pid:{1} release     futex:{2}, waiting list:{3}".format(
                   timeStr, pid, futexAddress, 
                   self._futexWaiterPids[futexAddress])


    def printOutput(self):
        futexAddressSet = set(self._futexHolderPid.keys() + self._futexWaiterPids.keys())

        print "Futex Address,Holder,Waiters"
        for addr in futexAddressSet:
            print "{0},{1},{2}".format(addr, 
                   self._futexHolderPid[addr] if addr in self._futexHolderPid else "Unknown",
                   self._futexWaiterPids[addr])