├── .gitignore ├── test ├── run_test.sh ├── ls_no_f.out ├── ls_f.out ├── thread-ex.out └── ls.out ├── statPlugins ├── __init__.py ├── VerifyParser.py ├── StatSummary.py ├── StatProcessTree.py ├── StatBase.py ├── StatLastSyscall.py ├── StatFutex.py ├── StatFileIO.py └── StatStreams.py ├── straceParserLib ├── __init__.py └── StraceParser.py └── strace_analyser /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /test/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Just a very simple test that run all the plugins on all the files. We should improve this later and 4 | # may be using a better framework. 5 | # 6 | for plugin in $(ls ../statPlugins/*.py | grep -v init | grep -v Base | sed 's#.*/\([^\.]*\).*#\1#'); do 7 | for file in $(ls *.out); do 8 | echo "Testing plugin $plugin on $file..." 9 | ../strace_analyser -e $plugin $file > /tmp/${plugin}.${file}.output_old # we should compare the output too 10 | exit_val=$? 11 | if [ ! $exit_val -eq 0 ]; then 12 | exit 1 13 | fi 14 | done 15 | done 16 | 17 | -------------------------------------------------------------------------------- /statPlugins/__init__.py: -------------------------------------------------------------------------------- 1 | # This program is free software; you can redistribute it and/or modify 2 | # it under the terms of the GNU General Public License as published by 3 | # the Free Software Foundation; either version 2 of the License, or 4 | # (at your option) any later version. 5 | 6 | # This program is distributed in the hope that it will be useful, 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | # GNU General Public License for more details. 10 | 11 | # You should have received a copy of the GNU General Public License 12 | # along with this program; if not, write to the Free Software 13 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 14 | 15 | __all__ = [] 16 | -------------------------------------------------------------------------------- /straceParserLib/__init__.py: -------------------------------------------------------------------------------- 1 | # This program is free software; you can redistribute it and/or modify 2 | # it under the terms of the GNU General Public License as published by 3 | # the Free Software Foundation; either version 2 of the License, or 4 | # (at your option) any later version. 5 | 6 | # This program is distributed in the hope that it will be useful, 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | # GNU General Public License for more details. 10 | 11 | # You should have received a copy of the GNU General Public License 12 | # along with this program; if not, write to the Free Software 13 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 14 | 15 | __all__ = ["StraceParser"] 16 | -------------------------------------------------------------------------------- /statPlugins/VerifyParser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | 17 | from StatBase import StatBase 18 | 19 | class VerifyParser(StatBase): 20 | """ For verify parser output """ 21 | 22 | def getRawSyscallHooks(self): 23 | return {"ALL": self.funcHandleALLSyscall} 24 | 25 | def funcHandleALLSyscall(self, result): 26 | if "pid" in result: 27 | pid = result["pid"] 28 | else: 29 | pid = "" 30 | if "startTime" in result: 31 | startTime = result["startTime"].time() 32 | else: 33 | startTime = "" 34 | 35 | if result["type"] == "resumed": 36 | output = "{0:<5} {1} <... {2} resumed> ".format(pid, startTime, result["syscall"]) 37 | else: 38 | output = "{0:<5} {1} {2}(".format(pid, startTime, result["syscall"]) 39 | output += ", ".join([str(a) for a in result["args"]]) 40 | if result["type"] == "unfinished": 41 | output = output + " " 42 | else: 43 | output += ")" 44 | # pad some space before return value if it is too short 45 | # in order to match to original strace output 46 | output = "{0:<39} = {1}".format(output, result["return"]) 47 | if "timeSpent" in result and result["timeSpent"]: 48 | output += " <%d.%06d>" % (result["timeSpent"].seconds, result["timeSpent"].microseconds) 49 | 50 | print output 51 | ## Print arg for check 52 | #for arg in result["args"]: 53 | # print " '%s'" % arg 54 | 55 | def printOutput(self): 56 | pass 57 | -------------------------------------------------------------------------------- /statPlugins/StatSummary.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | from StatBase import StatBase 17 | from collections import defaultdict 18 | from datetime import timedelta 19 | 20 | class StatSummary(StatBase): 21 | """ Summarize of syscall of strace, like strace -c output""" 22 | 23 | def __init__(self): 24 | self._syscallCount = defaultdict(int) 25 | self._syscallTime = defaultdict(timedelta) 26 | #self._syscallErrorCount = {} 27 | return 28 | 29 | def getSyscallHooks(self): 30 | return {"ALL": self.record} 31 | 32 | def isOperational(self, straceOptions): 33 | if not straceOptions["haveTimeSpent"]: 34 | return False 35 | return True 36 | 37 | def record(self, result): 38 | self._syscallCount[result["syscall"]] += 1 39 | if result["timeSpent"]: 40 | self._syscallTime[result["syscall"]] += result["timeSpent"] 41 | 42 | 43 | 44 | def printOutput(self): 45 | print "% time seconds usecs/call calls syscall" 46 | print "------ ----------- ----------- --------- ----------------" 47 | 48 | totalCount = sum(self._syscallCount.values()) 49 | totalTime = reduce(lambda x,y: x+y, self._syscallTime.values()) 50 | for syscall in sorted(self._syscallTime, key=self._syscallTime.get, 51 | reverse=True): 52 | percent = self._syscallTime[syscall].total_seconds() * 100 / \ 53 | totalTime.total_seconds() 54 | usecsPerCall = self._syscallTime[syscall] / \ 55 | self._syscallCount[syscall] 56 | print "%6.2f %11.6f %11d %9d %s" % \ 57 | (percent, self._syscallTime[syscall].total_seconds(), 58 | usecsPerCall.total_seconds()*(10**6), 59 | self._syscallCount[syscall], syscall) 60 | 61 | print "------ ----------- ----------- --------- ----------------" 62 | print "%6.2f %11.6f %11d %9d %s" % (100, totalTime.total_seconds(), 63 | totalTime.total_seconds()*(10**6) / totalCount, totalCount, "total") 64 | 65 | -------------------------------------------------------------------------------- /statPlugins/StatProcessTree.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | 17 | import logging 18 | from collections import defaultdict 19 | from StatBase import StatBase 20 | 21 | 22 | class StatProcessTree(StatBase): 23 | """ Print the process fork tree in the strace file """ 24 | 25 | def __init__(self): 26 | self._allPid = set() 27 | self._childDict = defaultdict(list) 28 | self._childExecName = {} 29 | return 30 | 31 | def isOperational(self, straceOptions): 32 | if not straceOptions["havePid"]: 33 | return False 34 | return True 35 | 36 | def getSyscallHooks(self): 37 | return {"ALL": self.statProcessTree} 38 | 39 | def statProcessTree(self, result): 40 | if "pid" not in result: 41 | logging.warning("statProcessTree: no pid info in line") 42 | return 43 | 44 | pid = result["pid"] 45 | self._allPid.add(pid) 46 | if result["syscall"] == "clone": 47 | childPid = result["return"] 48 | self._childDict[pid].append(childPid) 49 | # Copy the execuation name of parent process to child process. 50 | # It will be overwritten by next execve call of child 51 | if pid in self._childExecName: 52 | self._childExecName[childPid] = self._childExecName[pid] 53 | 54 | if result["syscall"] == "execve": 55 | self._childExecName[pid] = result["args"][0] 56 | 57 | def getProcessChildern(self, pid): 58 | return self._childDict[pid] 59 | 60 | def getProcessExecName(self, pid): 61 | return self._childExecName[pid] 62 | 63 | def printOutput(self): 64 | # headPid = remove child pid in _allPid, so it contains only head pid 65 | headPid = self._allPid 66 | for childPidList in self._childDict.values(): 67 | for childPid in childPidList: 68 | headPid.remove(childPid) 69 | 70 | print "====== Process Tree ======" 71 | for pid in headPid: 72 | self._printTree(pid, 0) 73 | print "" 74 | 75 | 76 | def _printTree(self, pid, indent): 77 | for i in xrange(0, indent): 78 | print " ", 79 | 80 | if pid in self._childExecName: 81 | print "%s [%s]" % (pid, self._childExecName[pid]) 82 | else: 83 | print "%s [unknown]" % pid 84 | 85 | for childPid in self._childDict[pid]: 86 | self._printTree(childPid, indent+1) 87 | return 88 | -------------------------------------------------------------------------------- /statPlugins/StatBase.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | 17 | 18 | class StatBase(object): 19 | """ The base class of stat plugins """ 20 | 21 | def optionHelp(self): 22 | """ Should return a dict for all options for this plugin. 23 | The dict keys are the option names and dict Values are the 24 | description of the options. 25 | E.g. {"output":"Write the output to this file instead of stdout"} 26 | 27 | It will be used for a help text in the command line. And it will 28 | be used to check if user input a correct option: If an 29 | option is specified for this plugin by user but it is not specified 30 | here, the command line will show error. 31 | """ 32 | return {} 33 | 34 | def setOption(self, pluginOptionDict): 35 | """ The pluginOptionDict contains the key value pair of options for 36 | specified by user in the command line for this plugin. 37 | E.g. {"output":"/tmp/output.txt"} 38 | 39 | If no option specified, pluginOptionDict will be an empty dict ({}). 40 | Return False if there is some problem in the options so that this 41 | plugin would not be used. 42 | """ 43 | return True 44 | 45 | def isOperational(self, straceOptions): 46 | """ Should return true if this plugin works in the current strace 47 | options. 48 | The straceOptions should be a dict contains at least: 49 | straceOptions["havePid"] = 1/0 50 | straceOptions["haveTime"] = "", "t", "tt", or "ttt" 51 | straceOptions["haveTimeSpent"] = 1/0 52 | 53 | If isOperational return false, the register function will not be 54 | called. 55 | """ 56 | return True 57 | 58 | def getSyscallHooks(self): 59 | """ Hook the processing function for each completed syscall. 60 | 61 | The uncomplete/resumed syscall will be merged before passing to the 62 | hook function. And if it cannot merged then it will be ignored. 63 | (If you want to get uncomplete/resumed saperately, use 64 | getRawSyscallHooks instead.) 65 | 66 | Should return a dict with key = syscall name and value = hook function 67 | E.g. return_dict["open"] = self.funcHandleOpenSyscall 68 | return_dict["close"] = self.funcHandleCloseSyscall 69 | return_dict["ALL"] = self.funcHandleALLSyscall 70 | """ 71 | return None 72 | 73 | def getRawSyscallHooks(self): 74 | """ Hook the processing function for each syscall (which may be 75 | unfinished/resumed) 76 | 77 | Should return a dict similar to that of getSyscallHooks 78 | """ 79 | return None 80 | 81 | def printOutput(self): 82 | """ Should print the output to console. Would be called after parsing is 83 | finished. 84 | """ 85 | pass 86 | -------------------------------------------------------------------------------- /statPlugins/StatLastSyscall.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | from collections import deque, defaultdict 17 | from datetime import timedelta, datetime 18 | 19 | from StatBase import StatBase 20 | from StatProcessTree import StatProcessTree 21 | 22 | 23 | class StatLastSyscall(StatBase): 24 | """ Find the last few unfinished syscall of process """ 25 | 26 | def __init__(self): 27 | self._statProcessTree = StatProcessTree() 28 | self._lastSyscallStore = defaultdict(deque) 29 | self._lastSyscallTime = {} 30 | 31 | def isOperational(self, straceOptions): 32 | self._straceOptions = straceOptions 33 | return True 34 | 35 | def getSyscallHooks(self): 36 | if self._straceOptions["havePid"]: 37 | return self._statProcessTree.getSyscallHooks() 38 | else: 39 | return None 40 | 41 | def getRawSyscallHooks(self): 42 | return {"ALL": self.funcHandleALLSyscall} 43 | 44 | def _reconstructStraceLine(self, result): 45 | # recontruct the strace line 46 | if self._straceOptions["haveTime"]: 47 | syscallLine = result["startTime"].strftime("%H:%M:%S.%f") + " " 48 | else: 49 | syscallLine = "" 50 | syscallLine += "{0} (".format(result["syscall"]) + ", ".join([str(a) for a in result["args"]]) 51 | if result["type"] == "unfinished": 52 | syscallLine += " " 53 | else: 54 | syscallLine += ")" 55 | # pad some space before return value if it is too short 56 | # in order to match to original strace output 57 | syscallLine = "{0:<39} = {1}".format(syscallLine, result["return"]) 58 | return syscallLine 59 | 60 | 61 | def funcHandleALLSyscall(self, result): 62 | if self._straceOptions["havePid"]: 63 | pid = result["pid"] 64 | else: 65 | pid = 0 66 | 67 | # store the last syscall time 68 | if self._straceOptions["haveTime"]: 69 | syscallTime = result["startTime"] 70 | self._lastSyscallTime[pid] = syscallTime 71 | self._latestTime = syscallTime 72 | 73 | self._lastSyscallStore[pid].append(result) 74 | if len(self._lastSyscallStore[pid]) > 3: # store last 3 syscalls 75 | self._lastSyscallStore[pid].popleft() 76 | 77 | 78 | def printOutput(self): 79 | for pid, syscallList in self._lastSyscallStore.iteritems(): 80 | if self._straceOptions["haveTime"]: 81 | waitTime = self._latestTime - self._lastSyscallTime[pid] 82 | else: 83 | waitTime = "" 84 | # Ignore all the exited process 85 | if "exit" not in syscallList[-1]["syscall"]: 86 | #print pid, self._statProcessTree.getProcessExecName(pid), waitTime 87 | #for syscallResult in syscallList: 88 | # print " ", self._reconstructStraceLine(syscallResult) 89 | print pid, waitTime, self._reconstructStraceLine(syscallList[-1]) 90 | -------------------------------------------------------------------------------- /statPlugins/StatFutex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | import sys 17 | from datetime import timedelta, datetime 18 | from collections import defaultdict 19 | 20 | from StatBase import StatBase 21 | from StatProcessTree import StatProcessTree 22 | 23 | 24 | class StatFutex(StatBase): 25 | """ Get futex related info """ 26 | 27 | def __init__(self): 28 | self._statProcessTree = StatProcessTree() 29 | self._unfinishedResult = {} 30 | self._futexHolderPid = {} 31 | self._futexWaiterPids = defaultdict(list) 32 | self._pluginOptionDict = {} 33 | self._outputFile = sys.stdout 34 | 35 | def optionHelp(self): 36 | return {"output":"Write the output to this file instead of stdout"} 37 | 38 | def setOption(self, pluginOptionDict): 39 | self._pluginOptionDict = pluginOptionDict 40 | filename = self._pluginOptionDict.get("output", "") 41 | self._outputFile = open(filename, "w") if filename else sys.stdout 42 | return True 43 | 44 | def isOperational(self, straceOptions): 45 | self._straceOptions = straceOptions 46 | return True 47 | 48 | def getSyscallHooks(self): 49 | if self._straceOptions["havePid"]: 50 | return self._statProcessTree.getSyscallHooks() 51 | else: 52 | return None 53 | 54 | def getRawSyscallHooks(self): 55 | if self._straceOptions["havePid"]: 56 | return {"futex": self.funcHandleFutexSyscall} 57 | return None 58 | 59 | def funcHandleFutexSyscall(self, result): 60 | #print result 61 | pid = result["pid"] 62 | syscallType = result["type"] 63 | if "startTime" in result: 64 | timeStr = result["startTime"].time() 65 | else: 66 | timeStr = "" 67 | 68 | if syscallType == "resumed": 69 | # if this is a resume syscall, combine it with last unfinished syscall of this pid 70 | lastResult = self._unfinishedResult[pid] 71 | lastResult["return"] = result["return"] 72 | lastResult["args"].append(result["args"]) 73 | lastResult["type"] = "completed" 74 | result = lastResult 75 | elif syscallType == "unfinished": 76 | self._unfinishedResult[pid] = result 77 | 78 | futexAddress = result["args"][0] 79 | futexOp = result["args"][1] 80 | if "FUTEX_WAIT" in futexOp: 81 | if syscallType == "unfinished": # wait on a futex 82 | # add myself in waiter list 83 | self._futexWaiterPids[futexAddress].append(pid) 84 | 85 | self._outputFile.write("{0} pid:{1} wait futex:{2}, current holder:{3}, waiting list:{4}\n".format( 86 | timeStr, pid, futexAddress, 87 | self._futexHolderPid[futexAddress] if futexAddress in self._futexHolderPid else "Unknown", 88 | self._futexWaiterPids[futexAddress])) 89 | 90 | else: # completed or resumed = being wake up or timeout 91 | # remove myself from futexWaiterPids 92 | if futexAddress in self._futexWaiterPids: 93 | if pid in self._futexWaiterPids[futexAddress]: 94 | self._futexWaiterPids[futexAddress].remove(pid) 95 | 96 | returnValue = result["return"] 97 | if int(returnValue) == 0: # being wake up 98 | self._futexHolderPid[futexAddress] = pid # I am the holder now 99 | self._outputFile.write("{0} pid:{1} hold futex:{2}, waiting list:{3}\n".format( 100 | timeStr, pid, futexAddress, 101 | self._futexWaiterPids[futexAddress])) 102 | else: # timeout 103 | self._outputFile.write("{0} pid:{1} timeout futex:{2}\n".format(timeStr, pid, futexAddress)) 104 | #TODO: many different cases in man page 105 | 106 | if "FUTEX_WAKE" in futexOp: 107 | self._futexHolderPid[futexAddress] = None 108 | self._outputFile.write("{0} pid:{1} release futex:{2}, waiting list:{3}\n".format( 109 | timeStr, pid, futexAddress, 110 | self._futexWaiterPids[futexAddress])) 111 | 112 | 113 | def printOutput(self): 114 | futexAddressSet = set(self._futexHolderPid.keys() + self._futexWaiterPids.keys()) 115 | 116 | self._outputFile.write("Futex Address,Holder,Waiters\n") 117 | for addr in futexAddressSet: 118 | self._outputFile.write("{0},{1},{2}\n".format(addr, 119 | self._futexHolderPid[addr] if addr in self._futexHolderPid else "Unknown", 120 | self._futexWaiterPids[addr])) 121 | -------------------------------------------------------------------------------- /statPlugins/StatFileIO.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | import sys 17 | 18 | from StatBase import StatBase 19 | 20 | class StatFileIO(StatBase): 21 | """ Stat and print file IO of strace""" 22 | 23 | def __init__(self): 24 | self._fileStatList = {} 25 | self._fidStatList = {} 26 | self._pluginOptionDict = {} 27 | self._straceOptions = {} 28 | return 29 | 30 | def optionHelp(self): 31 | return {"output":"Write the output to this file instead of stdout"} 32 | 33 | def setOption(self, pluginOptionDict): 34 | self._pluginOptionDict = pluginOptionDict 35 | return True 36 | 37 | def getSyscallHooks(self): 38 | return_dict = {} 39 | for syscall in ["read", "write", "open", "openat", "close"]: 40 | return_dict[syscall] = self.statFileIO 41 | return return_dict 42 | 43 | def isOperational(self, straceOptions): 44 | self._straceOptions = straceOptions 45 | return True 46 | 47 | def statFileIO(self, result): 48 | if result["syscall"] in ["read", "write", "open", "openat", "close"]: 49 | if result["return"] == "-1": # ignore failed syscalls 50 | return 51 | 52 | if result["syscall"] in ["open", "openat"]: 53 | fid = result["return"] 54 | else: 55 | fid = result["args"][0] 56 | 57 | if self._straceOptions["havePid"]: 58 | pid = int(result["pid"]) 59 | else: 60 | pid = 0 61 | if pid not in self._fidStatList: 62 | self._fidStatList[pid] = {} 63 | if pid not in self._fileStatList: 64 | self._fileStatList[pid] = {} 65 | 66 | # file close 67 | if result["syscall"] == "close": 68 | if fid in self._fidStatList[pid]: 69 | #print self._fidStatList[fid] 70 | filename = self._fidStatList[pid][fid][0] 71 | if filename not in self._fileStatList[pid]: 72 | self._fileStatList[pid][filename] = [1, 73 | self._fidStatList[pid][fid][1], 74 | self._fidStatList[pid][fid][2], 75 | self._fidStatList[pid][fid][3], 76 | self._fidStatList[pid][fid][4]] 77 | else: 78 | self._fileStatList[pid][filename][0] += 1 79 | for i in [1, 2, 3, 4]: 80 | self._fileStatList[pid][filename][i] += self._fidStatList[pid][fid][i] 81 | 82 | del self._fidStatList[pid][fid] 83 | # else if fid not in self._fidStatList[pid] and this is a close syscall, just ignore and return 84 | return 85 | 86 | # if read/write/open 87 | if fid not in self._fidStatList[pid]: 88 | if result["syscall"] == "open": 89 | # self._fidStatList[pid][fid] = [filename, read count, read acc bytes, write count, write acc bytes] 90 | self._fidStatList[pid][fid] = [result["args"][0], 0, 0, 0, 0] 91 | elif result["syscall"] == "openat": 92 | self._fidStatList[pid][fid] = [result["args"][1], 0, 0, 0, 0] 93 | else: 94 | self._fidStatList[pid][fid] = ["unknown:"+fid, 0, 0, 0, 0] 95 | # ISSUE #8: if fid in self._fidStatList[pid] but the syscall is open/openat, that mean 96 | # we missed a close syscall, we should update _fileStatList before we move on 97 | 98 | # stat read/write 99 | if result["syscall"] == "read": 100 | self._fidStatList[pid][fid][1] += 1 101 | self._fidStatList[pid][fid][2] += int(result["return"]) 102 | if result["syscall"] == "write": 103 | self._fidStatList[pid][fid][3] += 1 104 | self._fidStatList[pid][fid][4] += int(result["return"]) 105 | return 106 | 107 | def printOutput(self): 108 | filename = self._pluginOptionDict.get("output", "") 109 | f = open(filename, "w") if filename else sys.stdout 110 | f.write("====== File IO summary (csv) ======\n") 111 | 112 | for pid in self._fidStatList: 113 | for fid in self._fidStatList[pid]: 114 | #print self._fidStatList[pid][fid] 115 | filename = self._fidStatList[pid][fid][0] 116 | if filename not in self._fileStatList[pid]: 117 | self._fileStatList[pid][filename] = [1] + self._fidStatList[pid][fid][1:5] 118 | else: 119 | self._fileStatList[pid][filename][0] += 1 120 | for i in [1, 2, 3, 4]: 121 | self._fileStatList[pid][filename][i] += self._fidStatList[pid][fid][i] 122 | 123 | if self._straceOptions["havePid"]: 124 | f.write("pid, ") 125 | f.write("filename, open/close count, read count, read bytes, write count, write bytes\n") 126 | 127 | for pid in self._fileStatList: 128 | for filename in self._fileStatList[pid]: 129 | if self._straceOptions["havePid"]: 130 | f.write("%d, " % pid) 131 | f.write("%s, %d, %d, %d, %d, %d\n" % tuple([filename] + self._fileStatList[pid][filename])) 132 | 133 | -------------------------------------------------------------------------------- /test/ls_no_f.out: -------------------------------------------------------------------------------- 1 | execve("/usr/bin/ls", ["ls"], 0x7ffd6c1617e0 /* 52 vars */) = 0 2 | brk(NULL) = 0x55558eb2e000 3 | access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) 4 | openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 5 | fstat(3, {st_mode=S_IFREG|0644, st_size=89138, ...}) = 0 6 | mmap(NULL, 89138, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7d45886000 7 | close(3) = 0 8 | openat(AT_FDCWD, "/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3 9 | read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240l\0\0\0\0\0\0"..., 832) = 832 10 | fstat(3, {st_mode=S_IFREG|0755, st_size=162520, ...}) = 0 11 | mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7d45884000 12 | mmap(NULL, 2262512, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7d4544f000 13 | mprotect(0x7f7d45474000, 2097152, PROT_NONE) = 0 14 | mmap(0x7f7d45674000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f7d45674000 15 | mmap(0x7f7d45676000, 5616, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7d45676000 16 | close(3) = 0 17 | openat(AT_FDCWD, "/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3 18 | read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\25\0\0\0\0\0\0"..., 832) = 832 19 | fstat(3, {st_mode=S_IFREG|0755, st_size=19720, ...}) = 0 20 | mmap(NULL, 2113848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7d4524a000 21 | mprotect(0x7f7d4524e000, 2093056, PROT_NONE) = 0 22 | mmap(0x7f7d4544d000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f7d4544d000 23 | close(3) = 0 24 | openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 25 | read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\20\2\0\0\0\0\0"..., 832) = 832 26 | fstat(3, {st_mode=S_IFREG|0755, st_size=2066456, ...}) = 0 27 | mmap(NULL, 3889792, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7d44e94000 28 | mprotect(0x7f7d45040000, 2097152, PROT_NONE) = 0 29 | mmap(0x7f7d45240000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ac000) = 0x7f7d45240000 30 | mmap(0x7f7d45246000, 14976, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7d45246000 31 | close(3) = 0 32 | openat(AT_FDCWD, "/lib64/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3 33 | read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 !\0\0\0\0\0\0"..., 832) = 832 34 | fstat(3, {st_mode=S_IFREG|0755, st_size=542008, ...}) = 0 35 | mmap(NULL, 2634280, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7d44c10000 36 | mprotect(0x7f7d44c93000, 2093056, PROT_NONE) = 0 37 | mmap(0x7f7d44e92000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x82000) = 0x7f7d44e92000 38 | close(3) = 0 39 | openat(AT_FDCWD, "/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 40 | read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\16\0\0\0\0\0\0"..., 832) = 832 41 | fstat(3, {st_mode=S_IFREG|0755, st_size=19264, ...}) = 0 42 | mmap(NULL, 2109680, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7d44a0c000 43 | mprotect(0x7f7d44a0f000, 2093056, PROT_NONE) = 0 44 | mmap(0x7f7d44c0e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f7d44c0e000 45 | close(3) = 0 46 | openat(AT_FDCWD, "/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 47 | read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240a\0\0\0\0\0\0"..., 832) = 832 48 | fstat(3, {st_mode=S_IFREG|0755, st_size=149360, ...}) = 0 49 | mmap(NULL, 2217064, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7d447ee000 50 | mprotect(0x7f7d44807000, 2093056, PROT_NONE) = 0 51 | mmap(0x7f7d44a06000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f7d44a06000 52 | mmap(0x7f7d44a08000, 13416, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7d44a08000 53 | close(3) = 0 54 | mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7d45882000 55 | arch_prctl(ARCH_SET_FS, 0x7f7d45883540) = 0 56 | mprotect(0x7f7d45240000, 16384, PROT_READ) = 0 57 | mprotect(0x7f7d44a06000, 4096, PROT_READ) = 0 58 | mprotect(0x7f7d44c0e000, 4096, PROT_READ) = 0 59 | mprotect(0x7f7d44e92000, 4096, PROT_READ) = 0 60 | mprotect(0x7f7d4544d000, 4096, PROT_READ) = 0 61 | mprotect(0x7f7d45674000, 4096, PROT_READ) = 0 62 | mprotect(0x55558e885000, 8192, PROT_READ) = 0 63 | mprotect(0x7f7d4589c000, 4096, PROT_READ) = 0 64 | munmap(0x7f7d45886000, 89138) = 0 65 | set_tid_address(0x7f7d45883810) = 8238 66 | set_robust_list(0x7f7d45883820, 24) = 0 67 | rt_sigaction(SIGRTMIN, {sa_handler=0x7f7d447f3c10, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f7d448001b0}, NULL, 8) = 0 68 | rt_sigaction(SIGRT_1, {sa_handler=0x7f7d447f3cb0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f7d448001b0}, NULL, 8) = 0 69 | rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 70 | prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0 71 | statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0 72 | statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0 73 | brk(NULL) = 0x55558eb2e000 74 | brk(0x55558eb4f000) = 0x55558eb4f000 75 | access("/etc/selinux/config", F_OK) = 0 76 | open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 77 | fstat(3, {st_mode=S_IFREG|0644, st_size=113045344, ...}) = 0 78 | mmap(NULL, 113045344, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7d3dc1f000 79 | close(3) = 0 80 | ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0 81 | ioctl(1, TIOCGWINSZ, {ws_row=21, ws_col=173, ws_xpixel=0, ws_ypixel=0}) = 0 82 | open(".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3 83 | fstat(3, {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 84 | getdents(3, /* 11 entries */, 32768) = 360 85 | getdents(3, /* 0 entries */, 32768) = 0 86 | close(3) = 0 87 | fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 88 | write(1, "firefox_no_t.out firefox.out l"..., 119) = 119 89 | close(1) = 0 90 | close(2) = 0 91 | exit_group(0) = ? 92 | +++ exited with 0 +++ 93 | -------------------------------------------------------------------------------- /test/ls_f.out: -------------------------------------------------------------------------------- 1 | 2997 execve("/usr/bin/ls", ["ls"], 0x7ffccc487db8 /* 50 vars */) = 0 2 | 2997 brk(NULL) = 0x563491d02000 3 | 2997 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) 4 | 2997 openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 5 | 2997 fstat(3, {st_mode=S_IFREG|0644, st_size=88921, ...}) = 0 6 | 2997 mmap(NULL, 88921, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8af4d2c000 7 | 2997 close(3) = 0 8 | 2997 openat(AT_FDCWD, "/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3 9 | 2997 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240l\0\0\0\0\0\0"..., 832) = 832 10 | 2997 fstat(3, {st_mode=S_IFREG|0755, st_size=162520, ...}) = 0 11 | 2997 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8af4d2a000 12 | 2997 mmap(NULL, 2262512, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af48f5000 13 | 2997 mprotect(0x7f8af491a000, 2097152, PROT_NONE) = 0 14 | 2997 mmap(0x7f8af4b1a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f8af4b1a000 15 | 2997 mmap(0x7f8af4b1c000, 5616, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8af4b1c000 16 | 2997 close(3) = 0 17 | 2997 openat(AT_FDCWD, "/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3 18 | 2997 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\25\0\0\0\0\0\0"..., 832) = 832 19 | 2997 fstat(3, {st_mode=S_IFREG|0755, st_size=19720, ...}) = 0 20 | 2997 mmap(NULL, 2113848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af46f0000 21 | 2997 mprotect(0x7f8af46f4000, 2093056, PROT_NONE) = 0 22 | 2997 mmap(0x7f8af48f3000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f8af48f3000 23 | 2997 close(3) = 0 24 | 2997 openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 25 | 2997 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\20\2\0\0\0\0\0"..., 832) = 832 26 | 2997 fstat(3, {st_mode=S_IFREG|0755, st_size=2066456, ...}) = 0 27 | 2997 mmap(NULL, 3889792, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af433a000 28 | 2997 mprotect(0x7f8af44e6000, 2097152, PROT_NONE) = 0 29 | 2997 mmap(0x7f8af46e6000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ac000) = 0x7f8af46e6000 30 | 2997 mmap(0x7f8af46ec000, 14976, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8af46ec000 31 | 2997 close(3) = 0 32 | 2997 openat(AT_FDCWD, "/lib64/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3 33 | 2997 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 !\0\0\0\0\0\0"..., 832) = 832 34 | 2997 fstat(3, {st_mode=S_IFREG|0755, st_size=542008, ...}) = 0 35 | 2997 mmap(NULL, 2634280, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af40b6000 36 | 2997 mprotect(0x7f8af4139000, 2093056, PROT_NONE) = 0 37 | 2997 mmap(0x7f8af4338000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x82000) = 0x7f8af4338000 38 | 2997 close(3) = 0 39 | 2997 openat(AT_FDCWD, "/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 40 | 2997 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\16\0\0\0\0\0\0"..., 832) = 832 41 | 2997 fstat(3, {st_mode=S_IFREG|0755, st_size=19264, ...}) = 0 42 | 2997 mmap(NULL, 2109680, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af3eb2000 43 | 2997 mprotect(0x7f8af3eb5000, 2093056, PROT_NONE) = 0 44 | 2997 mmap(0x7f8af40b4000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f8af40b4000 45 | 2997 close(3) = 0 46 | 2997 openat(AT_FDCWD, "/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 47 | 2997 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240a\0\0\0\0\0\0"..., 832) = 832 48 | 2997 fstat(3, {st_mode=S_IFREG|0755, st_size=149360, ...}) = 0 49 | 2997 mmap(NULL, 2217064, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af3c94000 50 | 2997 mprotect(0x7f8af3cad000, 2093056, PROT_NONE) = 0 51 | 2997 mmap(0x7f8af3eac000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f8af3eac000 52 | 2997 mmap(0x7f8af3eae000, 13416, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8af3eae000 53 | 2997 close(3) = 0 54 | 2997 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8af4d28000 55 | 2997 arch_prctl(ARCH_SET_FS, 0x7f8af4d29540) = 0 56 | 2997 mprotect(0x7f8af46e6000, 16384, PROT_READ) = 0 57 | 2997 mprotect(0x7f8af3eac000, 4096, PROT_READ) = 0 58 | 2997 mprotect(0x7f8af40b4000, 4096, PROT_READ) = 0 59 | 2997 mprotect(0x7f8af4338000, 4096, PROT_READ) = 0 60 | 2997 mprotect(0x7f8af48f3000, 4096, PROT_READ) = 0 61 | 2997 mprotect(0x7f8af4b1a000, 4096, PROT_READ) = 0 62 | 2997 mprotect(0x56349011c000, 8192, PROT_READ) = 0 63 | 2997 mprotect(0x7f8af4d42000, 4096, PROT_READ) = 0 64 | 2997 munmap(0x7f8af4d2c000, 88921) = 0 65 | 2997 set_tid_address(0x7f8af4d29810) = 2997 66 | 2997 set_robust_list(0x7f8af4d29820, 24) = 0 67 | 2997 rt_sigaction(SIGRTMIN, {sa_handler=0x7f8af3c99c10, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8af3ca61b0}, NULL, 8) = 0 68 | 2997 rt_sigaction(SIGRT_1, {sa_handler=0x7f8af3c99cb0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f8af3ca61b0}, NULL, 8) = 0 69 | 2997 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 70 | 2997 prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0 71 | 2997 statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0 72 | 2997 statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0 73 | 2997 brk(NULL) = 0x563491d02000 74 | 2997 brk(0x563491d23000) = 0x563491d23000 75 | 2997 access("/etc/selinux/config", F_OK) = 0 76 | 2997 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 77 | 2997 fstat(3, {st_mode=S_IFREG|0644, st_size=113045344, ...}) = 0 78 | 2997 mmap(NULL, 113045344, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8aed0c5000 79 | 2997 close(3) = 0 80 | 2997 ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0 81 | 2997 ioctl(1, TIOCGWINSZ, {ws_row=54, ws_col=105, ws_xpixel=0, ws_ypixel=0}) = 0 82 | 2997 open(".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3 83 | 2997 fstat(3, {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 84 | 2997 getdents(3, /* 9 entries */, 32768) = 296 85 | 2997 getdents(3, /* 0 entries */, 32768) = 0 86 | 2997 close(3) = 0 87 | 2997 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 88 | 2997 write(1, "firefox_no_t.out firefox.out l"..., 93) = 93 89 | 2997 close(1) = 0 90 | 2997 close(2) = 0 91 | 2997 exit_group(0) = ? 92 | 2997 +++ exited with 0 +++ 93 | -------------------------------------------------------------------------------- /statPlugins/StatStreams.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | 17 | import logging 18 | import re 19 | from StatBase import StatBase 20 | 21 | class streamList(list): 22 | """A list object extended to a _metadata dictionary""" 23 | def __init__(self,*args,**kwargs): 24 | self._metadata = {} 25 | list.__init__(self, args, **kwargs) 26 | 27 | class StatStreams(StatBase): 28 | """ Stat and follow streams in strace""" 29 | #Syscalls this object will be registered with 30 | SYSCALLS = "open openat socket connect read write close".split() 31 | 32 | #some regexp for extracting information out of the strace log lines 33 | RE_PAT = dict( 34 | ip_address=re.compile('.*[^0-9]((?:[0-9]{1,3}\.){3}[0-9]{1,3})[^0-9].*'), 35 | #set of printable unicode characters 36 | #(no control charaters and \t \n \r (:= 9,10,13) 37 | no_str=re.compile('[%s]' % re.escape(''.join(map(unichr, range(0,8) + [11, 12] + range (14,32) + range(127,256))))), 38 | no_ascii=re.compile('[^%s]' % re.escape(''.join(map(chr, range(33,126)))))) 39 | 40 | #markers for displaying the output 41 | OUT_MARKER = '>>>>' 42 | IN_MARKER = '<<<<' 43 | 44 | def __init__(self): 45 | #key = OF number 46 | self._open_streams = {} 47 | #store the finished streams 48 | self._closed_streams = [] 49 | 50 | #some defaults 51 | self.show_text = True #display streams contents 52 | self.show_binary = True #display binary streams 53 | self.show_online = False #display streams as soon as they are closed 54 | 55 | #define stdin, stdout and stderr 56 | names = ['STDIN', 'STDOUT', 'STDERR'] 57 | for num in range(3): 58 | self._open_streams[num] = streamList(names[num]) 59 | self._open_streams[num]._metadata = dict(type=names[num], out=0) 60 | self._open_streams[num]._metadata['in'] = 0 61 | 62 | 63 | def getSyscallHooks(self): 64 | return_dict = {} 65 | for syscall in StatStreams.SYSCALLS: 66 | return_dict[syscall] = self.statStreams 67 | return return_dict 68 | 69 | def isOperational(self, straceOptions): 70 | return True 71 | 72 | def openStream(self, syscall, retcode, args): 73 | if retcode == -1: 74 | #file not found, do nothing 75 | return 76 | 77 | stream_nr = retcode 78 | if syscall == "openat": 79 | file_name = args[1] 80 | else: 81 | file_name = args[0] 82 | 83 | if stream_nr in self._open_streams: 84 | #the filehandle should have been closed! we missed it 85 | logging.warn("Missed closing of stream %s", stream_nr) 86 | self.close_stream(stream_nr) 87 | 88 | st_type = dict(open="file",openat="file",socket="socket")[syscall] 89 | sl = streamList("%s(%s) %s" % (st_type , stream_nr, ', '.join(args))) 90 | sl._metadata['type'] = st_type 91 | sl._metadata['opening_args'] = args 92 | sl._metadata['in'] = 0 93 | sl._metadata['out'] = 0 94 | self._open_streams[stream_nr] = sl 95 | 96 | def socketConnect(self, syscall, retcode, args): 97 | stream_nr = int(args[0]) 98 | if stream_nr in self._open_streams: 99 | stream = self._open_streams[stream_nr] 100 | if args[1][0] == 'sa_family=AF_INET': 101 | stream.append('Connected to %s' % StatStreams.RE_PAT['ip_address'].match(args[1][2]).group(1)) 102 | elif args[1][0] == 'sa_family=AF_INET6': 103 | stream.append('Connected to %s' % args[1][3]) 104 | else: 105 | logging.error("Missed openning %s", stream_nr) 106 | 107 | 108 | def readStream(self, syscall, retcode, args): 109 | """Parse a read action on a stream""" 110 | stream_nr = int(args[0]) 111 | if stream_nr in self._open_streams: 112 | stream = self._open_streams[stream_nr] 113 | stream._metadata['in'] += retcode 114 | if self.show_text: 115 | read_str = self.parseString(syscall, retcode, args[1]) 116 | if len(stream) > 1 and stream[-2].startswith(StatStreams.IN_MARKER): 117 | #merge with last one 118 | stream[-1] += read_str 119 | else: 120 | stream.append(StatStreams.IN_MARKER) 121 | stream.append(read_str) 122 | else: 123 | logging.error("Missed openning %s", stream_nr) 124 | 125 | 126 | def writeStream(self, syscall, retcode, args): 127 | stream_nr = int(args[0]) 128 | if stream_nr in self._open_streams: 129 | stream = self._open_streams[stream_nr] 130 | stream._metadata['out'] += retcode 131 | 132 | if self.show_text: 133 | write_str = self.parseString(syscall, retcode, args[1]) 134 | if len(stream) > 1 and stream[-2].startswith(StatStreams.OUT_MARKER): 135 | #merge with last one 136 | stream[-1] += write_str 137 | else: 138 | #new communication direction, start new block 139 | stream.append(StatStreams.OUT_MARKER) 140 | stream.append(write_str) 141 | else: 142 | logging.error("Missed openning %s", stream_nr) 143 | 144 | def parseString(self, syscall, retcode, str_to_parse): 145 | """Parse a string from an read/write operation as output by strace""" 146 | #strip quotes and escape sequences 147 | str_arg = str_to_parse[1:-1].decode("string_escape") 148 | if StatStreams.RE_PAT['no_str'].search(str_arg): 149 | #handle a non printable string 150 | if self.show_binary: 151 | str_arg = self.prettyPrintHex(str_arg) 152 | else: 153 | str_arg = '' 154 | if retcode > len(str_arg): 155 | #we don't have everything. Mark missing 156 | str_arg += '...\n' 157 | return str_arg 158 | 159 | def prettyPrintHex(self, src, length=16): 160 | """Pretty print binary data passed from parseString""" 161 | offset=0 162 | result='' 163 | while src: 164 | s,src = src[:length],src[length:] 165 | hexa = ' '.join(["%02X"%ord(x) for x in s]) 166 | s_ascii = StatStreams.RE_PAT['no_ascii'].sub('.', s) 167 | result += "%04X %-*s %s\n" % (offset, length * 3, hexa, s_ascii) 168 | offset += length 169 | return result 170 | 171 | 172 | def closeStream(self, syscall, retcode, args): 173 | stream_nr = int(args[0]) 174 | if stream_nr in self._open_streams: 175 | stream = self._open_streams[stream_nr] 176 | closing_strs = ['closed(%d) - in:%d - out: %d\n' % 177 | (stream_nr, stream._metadata['in'], stream._metadata['out'])] 178 | 179 | if self.show_online: 180 | #just show the report and continue 181 | print '\n'.join(stream + closing_strs) 182 | else: 183 | #store the report for later 184 | self._closed_streams.append('\n'.join(stream + closing_strs)) 185 | 186 | del self._open_streams[stream_nr] 187 | else: 188 | logging.error("Missed openning %d", stream_nr) 189 | 190 | def statStreams(self, result): 191 | logging.debug(result) 192 | syscall, retcode, args = result["syscall"], int(result["return"]), result["args"] 193 | 194 | if syscall in StatStreams.SYSCALLS: 195 | dict(open=self.openStream, 196 | openat=self.openStream, 197 | socket=self.openStream, 198 | connect=self.socketConnect, 199 | read=self.readStream, 200 | write=self.writeStream, 201 | close=self.closeStream)[syscall](syscall, retcode, args) 202 | 203 | 204 | def printOutput(self): 205 | #close all open streams 206 | if self.show_online: 207 | print "====== Finalized Streams ======" 208 | for stream in self._open_streams.keys(): 209 | self.closeStream(None, None, [stream]) 210 | 211 | 212 | if not self.show_online: 213 | print "====== File Streams ======" 214 | print '\n'.join(self._closed_streams) 215 | 216 | 217 | -------------------------------------------------------------------------------- /strace_analyser: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | 17 | import sys 18 | import getopt 19 | import re 20 | import traceback 21 | import logging 22 | import os 23 | import io 24 | from optparse import OptionParser, OptionValueError 25 | from straceParserLib.StraceParser import StraceParser 26 | from collections import defaultdict 27 | 28 | def parsePluginOption(pluginOptionStr): 29 | """ Parse the plugin option str into dict 30 | e.g. -o StatFileIO.output=/tmp/IO.out,StatProcessTree.output=/tmp/process.out 31 | Return: {"StatFileIO": {"output": "/tmp/IO.out"}, 32 | "StatProcessTree: {"output": "/tmp/process.out"} 33 | } 34 | if there is no "." in the option key, we will put it in the "default". 35 | """ 36 | returnDict = defaultdict(dict) 37 | if not pluginOptionStr: 38 | return returnDict 39 | for optionStr in pluginOptionStr.split(","): 40 | try: 41 | key, value = optionStr.split("=") 42 | if "." in key: 43 | pluginName, keyName = key.split('.') 44 | else: 45 | pluginName, keyName = "default", key 46 | returnDict[pluginName][keyName] = value 47 | except ValueError as e: 48 | logging.warning("Cannot parse plugin option '%s', ignore." % optionStr) 49 | return returnDict 50 | 51 | 52 | def importPlugin(pluginname, name): 53 | """ Import a plugin 54 | similar to "from pluginname import name" 55 | """ 56 | try: 57 | plugin = __import__(pluginname, globals(), locals(), [name]) 58 | except ImportError: 59 | return None 60 | return getattr(plugin, name) 61 | 62 | def main(): 63 | # parse command line options 64 | usage = "\n".join(["Usage: %prog [options] -e [plugin1,plugin2,...] [| - ]", 65 | "", 66 | "Example: %prog -e StatFileIO strace.out", 67 | " %prog -e StatFileIO -o output=/tmp/StatFileIO.txt strace.out", 68 | " %prog -e StatFileIO,StatFutex -o StatFileIO.output=/tmp/FileIO.txt,StatFutex.output=/tmp/Futex.txt strace.out", 69 | " strace -o >(%prog -e StatFileIO -) ls > /dev/null" 70 | ]) 71 | 72 | optionParser = OptionParser(usage=usage) 73 | optionParser.add_option("-t", action="count", dest="withtime", 74 | help="have time in strace (disable autodetect, use -T, -f, -t, -tt or -ttt to match with your strace output)") 75 | optionParser.add_option("-f", action="store_true", dest="withpid", help="have pid in strace (disable autodetect)") 76 | optionParser.add_option("-T", action="store_true", dest="withtimespent", help="have time spent in strace (disable autodetect)") 77 | optionParser.add_option("-l", "--list-plugins", action="store_true", dest="listplugins", help="list all plugins") 78 | optionParser.add_option("-e", "--enable-plugins", action="store", type="string", dest="enableplugins", 79 | help="enable these plugins only (e.g. plugin1,plugin2,plugin3)") 80 | optionParser.add_option("-o", "--plugin-options", action="store", type="string", dest="plugin_options", 81 | help=" ".join(["Specify plugin options by plugin_name.key=value,", 82 | "multiple options can be separate by comma (see example above).", 83 | "plugin_name can be omitted if only 1 plugin is enabled."])) 84 | optionParser.add_option("--list-plugin-options", action="store_true", dest="list_plugin_options", help="Show all plugin options") 85 | 86 | (options, args) = optionParser.parse_args() 87 | 88 | # List plugins 89 | if options.listplugins or options.list_plugin_options: 90 | print "=== Stat plugin list ===" 91 | pluginPath = os.path.join(sys.path[0], "statPlugins") 92 | plugins = os.listdir(pluginPath) 93 | plugins.sort() 94 | 95 | for plug in plugins: 96 | plugbase = plug[:-3] 97 | if not plug[-3:] == '.py' or plugbase == "__init__" or plugbase == "StatBase": 98 | continue 99 | 100 | try: 101 | pluginClass = importPlugin("statPlugins." + plugbase, plugbase) 102 | except: 103 | print "Warning: plugin %s does not install, skipping" % plug 104 | print plugbase, ":", pluginClass.__doc__ 105 | 106 | # show plugin options 107 | if options.list_plugin_options: 108 | optionHelp = pluginClass().optionHelp() 109 | if len(optionHelp) == 0: 110 | print " "*8 + "(No option for this plugin)" 111 | else: 112 | for name, desc in optionHelp.iteritems(): 113 | print " "*8 + "%s.%s: %s" % (pluginClass.__name__, name, desc) 114 | print "" 115 | 116 | # just listed all plugin and then exit 117 | exit(0) 118 | 119 | # Not list plugin then we will need the strace file 120 | if len(args) < 1: 121 | print "Error: Filename is missing, exit." 122 | optionParser.print_help() 123 | exit(1) 124 | straceFile = args[0] 125 | if straceFile == '-': 126 | reader = io.open(sys.stdin.fileno()) 127 | else: 128 | try: 129 | reader = io.open(straceFile) 130 | except IOError as e: 131 | print e 132 | exit(1) 133 | 134 | # init StraceParser 135 | straceParser = StraceParser() 136 | straceOptions = {} 137 | if options.withpid or options.withtime or options.withtimespent: 138 | straceOptions["havePid"] = options.withpid 139 | # options.withtime contain the number of -t (e.g. -t = 1, -tt = 2. -ttt = 3) 140 | # convert it back to t, tt, or ttt 141 | if options.withtime: 142 | straceOptions["haveTime"] = "t" * options.withtime 143 | else: 144 | straceOptions["haveTime"] = "" 145 | 146 | straceOptions["haveTimeSpent"] = options.withtimespent 147 | else: 148 | straceOptions = straceParser.autoDetectFormat(reader) 149 | if not straceOptions: 150 | logging.warning("Auto detect line format failed. Suggest using -t,-f,-T to specify.") 151 | exit(1) 152 | 153 | enablePluginList = [] 154 | if options.enableplugins: 155 | enablePluginList = options.enableplugins.split(",") 156 | 157 | if len(enablePluginList) == 0: 158 | print "No plugin is specified. Exit." 159 | exit(0) 160 | 161 | # parse plugin options 162 | pluginOptions = parsePluginOption(options.plugin_options) 163 | if "default" in pluginOptions: 164 | if len(enablePluginList) != 1: 165 | print "Have more than 1 plugin but plugin name doesn't specified on some plugin options." 166 | exit(1) 167 | pluginOptions[enablePluginList[0]] = pluginOptions["default"] 168 | # A sensible check: all the plugin named in plugin options should be enabled, avoid typo 169 | for key in pluginOptions: 170 | if key is not "default" and key not in enablePluginList: 171 | print "Plugin option is specified for plugin %s, but the plugin is not enabled. (typo?)" % key 172 | exit(1) 173 | 174 | # Load enabled plugins 175 | statObjList = [] 176 | for plug in enablePluginList: 177 | pluginClass = importPlugin("statPlugins." + plug, plug) 178 | if not pluginClass: 179 | print "Cannot install plugin %s, skipping" % plug 180 | continue 181 | 182 | statObj = pluginClass() 183 | if not statObj.isOperational(straceOptions): # if it is operational under current strace option 184 | print "plugin %s is not operational under this strace options, skipping" % plug 185 | continue 186 | 187 | # A sensible check: the plugin option should be in the dict of optionHelp 188 | option = pluginOptions.get(plug, {}) 189 | optionHelpDict = statObj.optionHelp() 190 | for optionName in option: 191 | if optionName not in optionHelpDict: 192 | print "option '%s' doesn't exist for plugin %s" % (optionName, plug) 193 | exit(1) 194 | 195 | # setOption for this plugin 196 | if not statObj.setOption(option): 197 | print "plugin %s add option failure" % plug 198 | exit(1) 199 | 200 | statObjList.append(statObj) # new an object from plugin class and put into list 201 | 202 | if len(statObjList) == 0: 203 | print "No plugin is loaded. Exit." 204 | exit(1) 205 | 206 | # register plugins to parser 207 | for obj in statObjList: 208 | hooks = obj.getSyscallHooks() 209 | if hooks: 210 | for syscall, func in hooks.iteritems(): 211 | straceParser.registerSyscallHook(syscall, func) 212 | hooks = obj.getRawSyscallHooks() 213 | if hooks: 214 | for syscall, func in hooks.iteritems(): 215 | straceParser.registerRawSyscallHook(syscall, func) 216 | 217 | ## Go ahead and parse the file 218 | straceParser.startParse(reader, straceOptions) 219 | 220 | ## print the result of the stat plugins 221 | for obj in statObjList: 222 | obj.printOutput() 223 | 224 | reader.close() 225 | 226 | if __name__ == "__main__": 227 | main() 228 | -------------------------------------------------------------------------------- /test/thread-ex.out: -------------------------------------------------------------------------------- 1 | 3667 23:21:22.835792 execve("./thread-ex", ["./thread-ex"], [/* 50 vars */]) = 0 2 | 3667 23:21:22.837058 brk(0) = 0x2505000 3 | 3667 23:21:22.837277 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7d6470b000 4 | 3667 23:21:22.837459 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) 5 | 3667 23:21:22.837670 open("/etc/ld.so.cache", O_RDONLY) = 3 6 | 3667 23:21:22.837890 fstat(3, {st_mode=S_IFREG|0644, st_size=139916, ...}) = 0 7 | 3667 23:21:22.838165 mmap(NULL, 139916, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7d646e8000 8 | 3667 23:21:22.838360 close(3) = 0 9 | 3667 23:21:22.838565 open("/lib64/libpthread.so.0", O_RDONLY) = 3 10 | 3667 23:21:22.838758 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\\`\3729\0\0\0"..., 832) = 832 11 | 3667 23:21:22.838959 fstat(3, {st_mode=S_IFREG|0755, st_size=141592, ...}) = 0 12 | 3667 23:21:22.839161 mmap(0x39fa600000, 2208672, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39fa600000 13 | 3667 23:21:22.839310 mprotect(0x39fa617000, 2093056, PROT_NONE) = 0 14 | 3667 23:21:22.839456 mmap(0x39fa816000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16000) = 0x39fa816000 15 | 3667 23:21:22.839621 mmap(0x39fa818000, 13216, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x39fa818000 16 | 3667 23:21:22.839811 close(3) = 0 17 | 3667 23:21:22.839961 open("/lib64/libc.so.6", O_RDONLY) = 3 18 | 3667 23:21:22.840105 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\355\341\3719\0\0\0"..., 832) = 832 19 | 3667 23:21:22.840268 fstat(3, {st_mode=S_IFREG|0755, st_size=1838360, ...}) = 0 20 | 3667 23:21:22.840479 mmap(0x39f9e00000, 3664040, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39f9e00000 21 | 3667 23:21:22.840624 mprotect(0x39f9f75000, 2097152, PROT_NONE) = 0 22 | 3667 23:21:22.840802 mmap(0x39fa175000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x175000) = 0x39fa175000 23 | 3667 23:21:22.841035 mmap(0x39fa17a000, 18600, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x39fa17a000 24 | 3667 23:21:22.841243 close(3) = 0 25 | 3667 23:21:22.841439 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7d646e7000 26 | 3667 23:21:22.841665 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7d646e6000 27 | 3667 23:21:22.841869 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7d646e5000 28 | 3667 23:21:22.844337 arch_prctl(ARCH_SET_FS, 0x7f7d646e6700) = 0 29 | 3667 23:21:22.844622 mprotect(0x39fa175000, 16384, PROT_READ) = 0 30 | 3667 23:21:22.844792 mprotect(0x39fa816000, 4096, PROT_READ) = 0 31 | 3667 23:21:22.844945 mprotect(0x39f981e000, 4096, PROT_READ) = 0 32 | 3667 23:21:22.845063 munmap(0x7f7d646e8000, 139916) = 0 33 | 3667 23:21:22.845205 set_tid_address(0x7f7d646e69d0) = 3667 34 | 3667 23:21:22.845314 set_robust_list(0x7f7d646e69e0, 0x18) = 0 35 | 3667 23:21:22.845427 futex(0x7fffcae8820c, FUTEX_WAKE_PRIVATE, 1) = 0 36 | 3667 23:21:22.845546 futex(0x7fffcae8820c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, NULL, 7f7d646e6700) = -1 EAGAIN (Resource temporarily unavailable) 37 | 3667 23:21:22.845689 rt_sigaction(SIGRTMIN, {0x39fa605a90, [], SA_RESTORER|SA_SIGINFO, 0x39fa60f440}, NULL, 8) = 0 38 | 3667 23:21:22.845873 rt_sigaction(SIGRT_1, {0x39fa605b20, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x39fa60f440}, NULL, 8) = 0 39 | 3667 23:21:22.846029 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 40 | 3667 23:21:22.846160 getrlimit(RLIMIT_STACK, {rlim_cur=10240*1024, rlim_max=RLIM_INFINITY}) = 0 41 | 3667 23:21:22.846404 mmap(NULL, 10489856, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f7d63ce4000 42 | 3667 23:21:22.846655 brk(0) = 0x2505000 43 | 3667 23:21:22.846763 brk(0x2526000) = 0x2526000 44 | 3667 23:21:22.846925 mprotect(0x7f7d63ce4000, 4096, PROT_NONE) = 0 45 | 3667 23:21:22.847062 clone(child_stack=0x7f7d646e3ff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f7d646e49e0, tls=0x7f7d646e4710, child_tidptr=0x7f7d646e49e0) = 3668 46 | 3667 23:21:22.847256 mmap(NULL, 10489856, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f7d632e3000 47 | 3667 23:21:22.847400 mprotect(0x7f7d632e3000, 4096, PROT_NONE) = 0 48 | 3667 23:21:22.847529 clone(child_stack=0x7f7d63ce2ff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f7d63ce39e0, tls=0x7f7d63ce3710, child_tidptr=0x7f7d63ce39e0) = 3669 49 | 3667 23:21:22.847693 mmap(NULL, 10489856, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f7d628e2000 50 | 3667 23:21:22.847851 mprotect(0x7f7d628e2000, 4096, PROT_NONE) = 0 51 | 3667 23:21:22.847988 clone(child_stack=0x7f7d632e1ff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f7d632e29e0, tls=0x7f7d632e2710, child_tidptr=0x7f7d632e29e0) = 3670 52 | 3667 23:21:22.848157 futex(0x7f7d646e49e0, FUTEX_WAIT, 3668, NULL 53 | 3669 23:21:22.848267 set_robust_list(0x7f7d63ce39f0, 0x18) = 0 54 | 3669 23:21:22.848416 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0 55 | 3669 23:21:22.848594 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7d6470a000 56 | 3669 23:21:22.848753 write(1, "Thread 2 says Hi! \n", 19) = 19 57 | 3669 23:21:22.848949 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 58 | 3669 23:21:22.849084 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 59 | 3669 23:21:22.849235 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 60 | 3669 23:21:22.849353 nanosleep({1, 0}, 61 | 3668 23:21:22.849471 set_robust_list(0x7f7d646e49f0, 0x18) = 0 62 | 3668 23:21:22.849590 futex(0x600d80, FUTEX_WAIT_PRIVATE, 2, NULL 63 | 3670 23:21:22.850095 set_robust_list(0x7f7d632e29f0, 0x18) = 0 64 | 3670 23:21:22.850358 futex(0x600d80, FUTEX_WAIT_PRIVATE, 2, NULL 65 | 3669 23:21:23.849628 <... nanosleep resumed> 0x7f7d63ce2e50) = 0 66 | 3669 23:21:23.849804 write(1, "Thread 2 says Hi! \n", 19) = 19 67 | 3669 23:21:23.850038 futex(0x600d80, FUTEX_WAKE_PRIVATE, 1) = 1 68 | 3668 23:21:23.850173 <... futex resumed> ) = 0 69 | 3669 23:21:23.850252 open("/etc/ld.so.cache", O_RDONLY 70 | 3668 23:21:23.850341 write(1, "Thread 1 says Hello! \n", 22 71 | 3669 23:21:23.850416 <... open resumed> ) = 3 72 | 3668 23:21:23.850468 <... write resumed> ) = 22 73 | 3669 23:21:23.850524 fstat(3, 74 | 3668 23:21:23.850584 rt_sigprocmask(SIG_BLOCK, [CHLD], 75 | 3669 23:21:23.850645 <... fstat resumed> {st_mode=S_IFREG|0644, st_size=139916, ...}) = 0 76 | 3668 23:21:23.850758 <... rt_sigprocmask resumed> [], 8) = 0 77 | 3669 23:21:23.850850 mmap(NULL, 139916, PROT_READ, MAP_PRIVATE, 3, 0 78 | 3668 23:21:23.850914 rt_sigaction(SIGCHLD, NULL, 79 | 3669 23:21:23.850965 <... mmap resumed> ) = 0x7f7d628bf000 80 | 3668 23:21:23.851015 <... rt_sigaction resumed> {SIG_DFL, [], 0}, 8) = 0 81 | 3669 23:21:23.851104 close(3 82 | 3668 23:21:23.851161 rt_sigprocmask(SIG_SETMASK, [], 83 | 3669 23:21:23.851215 <... close resumed> ) = 0 84 | 3668 23:21:23.851263 <... rt_sigprocmask resumed> NULL, 8) = 0 85 | 3669 23:21:23.851321 open("/lib64/libgcc_s.so.1", O_RDONLY 86 | 3668 23:21:23.851386 nanosleep({1, 0}, 87 | 3669 23:21:23.851442 <... open resumed> ) = 3 88 | 3669 23:21:23.851521 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20)\340\0:\0\0\0"..., 832) = 832 89 | 3669 23:21:23.851745 mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f7d5a8bf000 90 | 3669 23:21:23.851951 munmap(0x7f7d5a8bf000, 24383488) = 0 91 | 3669 23:21:23.852346 munmap(0x7f7d60000000, 42725376) = 0 92 | 3669 23:21:23.852475 mprotect(0x7f7d5c000000, 135168, PROT_READ|PROT_WRITE) = 0 93 | 3669 23:21:23.852752 fstat(3, {st_mode=S_IFREG|0755, st_size=93320, ...}) = 0 94 | 3669 23:21:23.853045 mmap(0x3a00e00000, 2186584, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3a00e00000 95 | 3669 23:21:23.853276 mprotect(0x3a00e16000, 2093056, PROT_NONE) = 0 96 | 3669 23:21:23.853531 mmap(0x3a01015000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x3a01015000 97 | 3669 23:21:23.853727 close(3) = 0 98 | 3669 23:21:23.853932 munmap(0x7f7d628bf000, 139916) = 0 99 | 3669 23:21:23.854174 futex(0x3a01015af0, FUTEX_WAKE_PRIVATE, 2147483647) = 0 100 | 3669 23:21:23.854352 madvise(0x7f7d632e3000, 10465280, MADV_DONTNEED) = 0 101 | 3669 23:21:23.854493 _exit(0) = ? 102 | 3668 23:21:24.851681 <... nanosleep resumed> 0x7f7d646e3e50) = 0 103 | 3668 23:21:24.851873 write(1, "Thread 1 says Hello! \n", 22) = 22 104 | 3668 23:21:24.852132 futex(0x600d80, FUTEX_WAKE_PRIVATE, 1 105 | 3670 23:21:24.852248 <... futex resumed> ) = 0 106 | 3668 23:21:24.852299 <... futex resumed> ) = 1 107 | 3670 23:21:24.852355 write(1, "Thread 3 says Fun! \n", 20 108 | 3668 23:21:24.852422 madvise(0x7f7d63ce4000, 10465280, MADV_DONTNEED 109 | 3670 23:21:24.852470 <... write resumed> ) = 20 110 | 3668 23:21:24.852518 <... madvise resumed> ) = 0 111 | 3670 23:21:24.852574 rt_sigprocmask(SIG_BLOCK, [CHLD], 112 | 3668 23:21:24.852638 _exit(0) = ? 113 | 3670 23:21:24.852691 <... rt_sigprocmask resumed> [], 8) = 0 114 | 3670 23:21:24.852791 rt_sigaction(SIGCHLD, NULL, 115 | 3667 23:21:24.852862 <... futex resumed> ) = 0 116 | 3670 23:21:24.852911 <... rt_sigaction resumed> {SIG_DFL, [], 0}, 8) = 0 117 | 3667 23:21:24.853009 futex(0x7f7d632e29e0, FUTEX_WAIT, 3670, NULL 118 | 3670 23:21:24.853069 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 119 | 3670 23:21:24.853212 nanosleep({1, 0}, 0x7f7d632e1e50) = 0 120 | 3670 23:21:25.853605 write(1, "Thread 3 says Fun! \n", 20) = 20 121 | 3670 23:21:25.853883 futex(0x600d80, FUTEX_WAKE_PRIVATE, 1) = 0 122 | 3670 23:21:25.854128 madvise(0x7f7d628e2000, 10465280, MADV_DONTNEED) = 0 123 | 3670 23:21:25.854296 _exit(0) = ? 124 | 3667 23:21:25.854410 <... futex resumed> ) = 0 125 | 3667 23:21:25.854548 exit_group(0) = ? 126 | -------------------------------------------------------------------------------- /straceParserLib/StraceParser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This program is free software; you can redistribute it and/or modify 3 | # it under the terms of the GNU General Public License as published by 4 | # the Free Software Foundation; either version 2 of the License, or 5 | # (at your option) any later version. 6 | 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 | 16 | 17 | import sys 18 | import getopt 19 | import re 20 | import traceback 21 | import logging 22 | from optparse import OptionParser 23 | from datetime import timedelta, time, datetime 24 | from collections import defaultdict 25 | 26 | 27 | class StraceParser: 28 | """ 29 | StraceParser 30 | 31 | This is the strace parser. It parses each system call lines into a dict, and 32 | then call the registered stat modules to process. 33 | 34 | The defination of dict: please refer to _parseLine 35 | """ 36 | 37 | 38 | def __init__(self): 39 | # _completeSyscallCallbackHook 40 | # the dict contains a list for each syscall that registered by someone who is 41 | # increased in the syscall is parsed. 42 | # E.g. 43 | # 44 | # _completeSyscallCallbackHook["open"] = [func1, func2] 45 | # _completeSyscallCallbackHook["close"] = [func1] 46 | # _completeSyscallCallbackHook["ALL"] = [func1] 'ALL' means it will be involved for all kind of syscalls 47 | # 48 | # 49 | self._completeSyscallCallbackHook = defaultdict(list) 50 | self._rawSyscallCallbackHook = defaultdict(list) 51 | 52 | # regex compiled for _parseLine 53 | self._reCompleteSyscall = re.compile(r"([^(]+)\((.*)\)[ ]+=[ ]+([a-fx\d\-?]+)(.*)") 54 | self._reUnfinishedSyscall = re.compile(r"([^(]+)\((.*) ") 55 | self._reResumedSyscall = re.compile(r"\<\.\.\. ([^ ]+) resumed\> (.*)\)[ ]+=[ ]+([a-fx\d\-?]+)(.*)") 56 | return 57 | 58 | def registerSyscallHook(self, fullSyscallName, func): 59 | self._registerHookInTable(fullSyscallName, self._completeSyscallCallbackHook, func) 60 | 61 | def registerRawSyscallHook(self, fullSyscallName, func): 62 | self._registerHookInTable(fullSyscallName, self._rawSyscallCallbackHook, func) 63 | 64 | def _registerHookInTable(self, name, table, func): 65 | table[name].append(func) 66 | 67 | 68 | def startParse(self, reader, straceOptions): 69 | self._parse(reader, straceOptions) 70 | 71 | def autoDetectFormat(self, reader): 72 | """ autoDetectFormat - Detect the strace output line format, return a 73 | dict with following: 74 | 75 | straceOptions["havePid"] = True/False 76 | straceOptions["haveTime"] = ""/"t"/"tt"/"ttt" 77 | straceOptions["haveTimeSpent"] True/False 78 | 79 | It use peek() on the reader so it will not abvance the position of 80 | the stream. 81 | """ 82 | buf = reader.buffer.peek(4096); 83 | 84 | failCount = 0 85 | for line in buf.split('\n'): 86 | if failCount == 3: 87 | return None 88 | if "unfinish" in line or "resume" in line: 89 | continue 90 | straceOptions = self._detectLineFormat(line) 91 | if straceOptions: 92 | return straceOptions 93 | else: 94 | failCount += 1 95 | return None 96 | 97 | def _detectTimeFormat(self, timeStr): 98 | if ":" not in timeStr and "." in timeStr: 99 | return "ttt" 100 | if ":" in timeStr: 101 | if "." in timeStr: 102 | return "tt" 103 | else: 104 | return "t" 105 | logging.debug("_detectTimeFormat: Failed: unable to detect time format.") 106 | return None 107 | 108 | def _detectLineFormat(self, line): 109 | havePid = False 110 | haveTime = "" 111 | haveTimeSpent = False 112 | 113 | remainLine = line 114 | 115 | m = re.match(r"([0-9:. ]*)([a-z]+\(.*[ ]+=[ ]+[-0-9]+)(.*)", line) 116 | if m: 117 | pre = m.group(1) 118 | mid = m.group(2) 119 | post = m.group(3) 120 | else: 121 | logging.debug("_detectLineFormat: Failed: unable to match the line, give up detection.") 122 | return 123 | 124 | if pre != '': 125 | preList = pre.strip().split() 126 | if len(preList) > 2: 127 | logging.debug("_detectLineFormat: Failed: more the 2 parts in pre.") 128 | return 129 | if len(preList) == 2: 130 | haveTime = self._detectTimeFormat(preList[1]) 131 | havePid = True 132 | else: 133 | if ':' in pre or '.' in pre: 134 | havePid = False 135 | haveTime = self._detectTimeFormat(preList[0]) 136 | else: 137 | havePid = True 138 | haveTime = "" 139 | 140 | if post != '': 141 | if re.search(r"(<[0-9.]+>)", line): 142 | haveTimeSpent = True 143 | else: 144 | haveTimeSpent = False 145 | 146 | straceOptions = {} 147 | straceOptions["havePid"] = havePid 148 | straceOptions["haveTime"] = haveTime 149 | straceOptions["haveTimeSpent"] = haveTimeSpent 150 | 151 | return straceOptions 152 | 153 | 154 | 155 | 156 | def _parse(self, reader, straceOptions): 157 | syscallListByPid = {} 158 | 159 | unfinishedSyscallStack = {} 160 | if not reader: 161 | logging.error("Cannot read file") 162 | return 163 | 164 | for line in reader: 165 | 166 | if "restart_syscall" in line: # TODO: ignore this first 167 | continue 168 | 169 | if "+++ exited with" in line: 170 | continue 171 | 172 | unfinishedSyscall = False 173 | reconstructSyscall = False 174 | if "" in line: # store the unfinished line for reconstruct 175 | unfinishedSyscall = True 176 | if straceOptions["havePid"]: 177 | pid = (line.partition(" "))[0] 178 | unfinishedSyscallStack[pid] = line 179 | else: 180 | unfinishedSyscallStack[0] = line 181 | elif "resumed>" in line: # get back the unfinished line and reconstruct 182 | if straceOptions["havePid"]: 183 | pid = (line.partition(" "))[0] 184 | if pid not in unfinishedSyscallStack: 185 | continue # no line before, ignore 186 | existLine = unfinishedSyscallStack[pid] 187 | else: 188 | if 0 not in unfinishedSyscallStack: 189 | continue # no line before, ignore 190 | existLine = unfinishedSyscallStack[0] 191 | lineIndex = line.find("resumed>") + len("resumed>") 192 | reconstructLine = existLine.replace("", line[lineIndex:]) 193 | reconstructSyscall = True 194 | #print "debug reconstructed line:", line 195 | 196 | 197 | # Parse the line 198 | #print line 199 | result = self._parseLine(line, straceOptions) 200 | 201 | # hook here for every (raw) syscalls 202 | if result: 203 | if result["syscall"] in self._rawSyscallCallbackHook: 204 | for func in self._rawSyscallCallbackHook[result["syscall"]]: 205 | func(result) 206 | if "ALL" in self._rawSyscallCallbackHook: 207 | for func in self._rawSyscallCallbackHook["ALL"]: 208 | func(result) 209 | 210 | # determine if there is a completeSyscallResult 211 | if unfinishedSyscall: 212 | completeSyscallResult = None 213 | elif reconstructSyscall: 214 | completeSyscallResult = self._parseLine(reconstructLine, straceOptions) 215 | else: # normal completed syscall 216 | completeSyscallResult = result 217 | 218 | # hook here for every completed syscalls: 219 | if completeSyscallResult: 220 | if completeSyscallResult["syscall"] in self._completeSyscallCallbackHook: 221 | for func in self._completeSyscallCallbackHook[completeSyscallResult["syscall"]]: 222 | func(completeSyscallResult) 223 | if "ALL" in self._completeSyscallCallbackHook: 224 | for func in self._completeSyscallCallbackHook["ALL"]: 225 | func(completeSyscallResult) 226 | 227 | return 228 | 229 | 230 | def _timeStrToTime(self, timeStr, timeFormat): 231 | """ _timeStrToTime 232 | 233 | timeFormat: "t" = "%H:%M:%S" 234 | "tt" = "%H:%M:%S.%f" 235 | "ttt" = "timestamp.%f" 236 | """ 237 | if timeFormat == "ttt": 238 | return datetime.utcfromtimestamp(float(timeStr)) 239 | else: 240 | timeList = timeStr.split(":") 241 | # in order to use datetime object for calculation, pad the time with 1970-1-1 242 | # TODO: should handle the day boundary case in _parse function 243 | if timeFormat == "tt": 244 | secondList = timeList[2].split(".") 245 | return datetime(1970, 1, 1, int(timeList[0]), int(timeList[1]), int(secondList[0]), int(secondList[1])) 246 | else: 247 | return datetime(1970, 1, 1, int(timeList[0]), int(timeList[1]), int(timeList[2])) 248 | 249 | def _timeStrToDelta(self, timeStr): 250 | return timedelta(seconds=float(timeStr)) 251 | 252 | # 253 | # _parseLine 254 | # 255 | # It parse a complete line and return a dict with the following: 256 | # pid : pid (if havePid enabled) 257 | # startTime : start time of the call (if haveTime enabled) 258 | # syscall : system call function 259 | # args : a list of arguments ([] if no options) 260 | # return : return value (+/- int string or hex number string or '?' (e.g. exit syscall)), not exist if it is an unfinished syscall 261 | # timeSpent : time spent in syscall (if haveTimeSpent enable. But even so, it may not exist in some case (e.g. exit syscall) and None will be stored in this field) 262 | # type : Type of syscall ("completed", "unfinished", "resumed") 263 | # 264 | # Return null if hit some error 265 | # 266 | # (Not implemented) signalEvent : signal event (no syscall, args, return) 267 | # 268 | def _parseLine(self, line, straceOptions): 269 | result = {} 270 | remainLine = line 271 | 272 | try: 273 | if straceOptions["havePid"]: 274 | result["pid"], remainLine = remainLine.split(None, 1) 275 | 276 | if straceOptions["haveTime"] != "": 277 | timeStr, remainLine = remainLine.split(None, 1) 278 | result["startTime"] = self._timeStrToTime(timeStr, straceOptions["haveTime"]) 279 | 280 | if "--- SIG" in remainLine: # a signal line 281 | #result["signalEvent"] = remainLine 282 | #return result 283 | ### Ignore signal line now 284 | return 285 | 286 | # If it is unfinished/resumed syscall, still parse it but let the 287 | # caller (_parse) determine what to do 288 | if "" in remainLine: 289 | result["type"] = "unfinished" 290 | m = self._reUnfinishedSyscall.match(remainLine) 291 | result["syscall"] = m.group(1) 292 | result["args"] = self._parseArgs(m.group(2).strip()) # probably only partal arguments 293 | elif "resumed>" in remainLine: 294 | result["type"] = "resumed" 295 | m = self._reResumedSyscall.match(remainLine) 296 | result["syscall"] = m.group(1) 297 | result["args"] = self._parseArgs(m.group(2).strip()) # probably only partal arguments 298 | result["return"] = m.group(3) 299 | remainLine = m.group(4) 300 | else: 301 | # normal system call 302 | result["type"] = "completed" 303 | m = self._reCompleteSyscall.match(remainLine) 304 | result["syscall"] = m.group(1) 305 | result["args"] = self._parseArgs(m.group(2).strip()) 306 | result["return"] = m.group(3) 307 | remainLine = m.group(4) 308 | 309 | if result["type"] != "unfinished" and straceOptions["haveTimeSpent"]: 310 | m = re.search(r"<([\d.]*)>", remainLine) 311 | if m: 312 | result["timeSpent"] = self._timeStrToDelta(m.group(1)) 313 | else: 314 | result["timeSpent"] = None 315 | 316 | except AttributeError: 317 | logging.warning("_parseLine: Error parsing this line: " + line) 318 | print sys.exc_info() 319 | #exctype, value, t = sys.exc_info() 320 | #print traceback.print_exc() 321 | #print sys.exc_info() 322 | return 323 | 324 | return result 325 | 326 | def _countPrecedingBackslashes(self, s, pos): 327 | initialPos = pos 328 | while pos > 0 and s[pos-1] == '\\': 329 | pos-=1 330 | return (initialPos-pos) 331 | 332 | def _parseStringArg(self, argString): 333 | """ 334 | Parses to the end of a string parameter. 335 | 336 | argString must begin with a quote character. _parseStringArg() parses 337 | to the corresponding terminating quote character. 338 | Returns the parsed string (including quotes) and the unparsed 339 | remainder of argString. 340 | 341 | >>> parser = StraceParser() 342 | >>> parser._parseStringArg('"abc"') 343 | ('"abc"', '') 344 | >>> parser._parseStringArg('"abc", 42') # the part behind the initial string will be returned as "remainder": 345 | ('"abc"', ', 42') 346 | >>> parser._parseStringArg('"", "42"') 347 | ('""', ', "42"') 348 | >>> parser._parseStringArg('"abc\"hello\"xyz", 42') 349 | ('"abc"', 'hello"xyz", 42') 350 | >>> parser._parseStringArg(r'"abc\x5c\x5c\x5c"xyz", 42') # multiple backslashes before terminating quote 351 | ('"abc\x5c\x5c\x5c\x5c\x5c\x5c"xyz"', ', 42') 352 | >>> print parser._parseStringArg(r'"\x5c\x5c\x5c"", 42') 353 | ('"\x5c\x5c\x5c\x5c\x5c\x5c""', ', 42') 354 | >>> print parser._parseStringArg(r'"\x5c\x5c", 42') 355 | ('"\x5c\x5c\x5c\x5c"', ', 42') 356 | >>> parser._parseStringArg('"abc') # bad parameter 357 | ('"', 'abc') 358 | """ 359 | searchEndSymbolStartAt = 1 360 | while True: 361 | endSymbolIndex = argString.find('"', searchEndSymbolStartAt) 362 | 363 | if endSymbolIndex == -1: 364 | logging.warning("_parseStringArg: strange, can't find end symbol in this arg:" + argString) 365 | endSymbolIndex = 0 366 | break 367 | 368 | numPrecedingBackslashes = self._countPrecedingBackslashes(argString, endSymbolIndex) 369 | if numPrecedingBackslashes % 2 == 1: 370 | # if preceded by an odd number of backslashes, the quote character is escaped 371 | searchEndSymbolStartAt = endSymbolIndex + 1 372 | else: 373 | break 374 | return ( argString[0:endSymbolIndex+1], argString[endSymbolIndex+1:] ) 375 | 376 | def _parseBlockArg(self, argString, parseBlock=False): 377 | """ 378 | Parses a list of arguments, recursing into blocks. 379 | 380 | argString must be a string of comma-separated arguments. 381 | If parseBlock is True, argString must start with [ or {, 382 | and _parseBlockArg() will only parse to the end of the matching 383 | bracket. 384 | Returns the parsed arguments and the unparsed remainder of argString. 385 | 386 | >>> parser = StraceParser() 387 | >>> parser._parseBlockArg('[42]', True) 388 | (['42'], '') 389 | >>> parser._parseBlockArg('[]', True) 390 | ([''], '') 391 | >>> parser._parseBlockArg('[], []', True) 392 | ([''], ', []') 393 | >>> parser._parseBlockArg('[42, 5, "abc"]', True) 394 | (['42', '5', '"abc"'], '') 395 | >>> parser._parseBlockArg('[42, {5, 6}, "abc"], "xyz"', True) 396 | (['42', ['5', '6'], '"abc"'], ', "xyz"') 397 | >>> parser._parseBlockArg('{42, [5, "abc"}', True) # error case 398 | ('{42, [5, "abc"}', '') 399 | 400 | >>> parser._parseBlockArg('42') 401 | (['42'], '') 402 | >>> parser._parseBlockArg('5, 42') 403 | (['5', '42'], '') 404 | >>> parser._parseBlockArg('[[["[[]]"]]]') 405 | ([[[['"[[]]"']]]], '') 406 | """ 407 | endSymbols = {'{':'}', '[':']', '"':'"'} 408 | resultArgs = [] 409 | 410 | currIndex = 0 411 | if parseBlock: 412 | endChar = endSymbols[argString[0]] 413 | currIndex+=1 414 | 415 | lengthArgString = len(argString) 416 | remainderString = argString 417 | while currIndex < lengthArgString: 418 | if argString[currIndex] == ' ': # ignore space 419 | currIndex += 1 420 | continue 421 | 422 | content = None 423 | if argString[currIndex] == '"': 424 | # inner string; parse recursively till end of string 425 | (content, remainderString) = self._parseStringArg(argString[currIndex:]) 426 | elif argString[currIndex] in ['{', '[']: 427 | # inner block; parse recursively till end of this block 428 | (content, remainderString) = self._parseBlockArg(argString[currIndex:], True) 429 | else: 430 | # normal parameter; find next comma 431 | remainderString = argString[currIndex:] 432 | 433 | nextCommaPos = remainderString.find(', ') 434 | if parseBlock: 435 | nextTerminatorPos = remainderString.find(endChar) 436 | if nextTerminatorPos == -1: 437 | logging.warning("_parseBlockArg: strange, can't find end symbol '%s' in this arg: '%s'" % (endChar, argString)) 438 | return (argString, "") 439 | else: 440 | nextTerminatorPos = lengthArgString 441 | 442 | finished = False 443 | if nextCommaPos == -1 or nextTerminatorPos < nextCommaPos: 444 | # we've parsed last parameter in block 445 | contentString = remainderString[:nextTerminatorPos] 446 | remainderString = remainderString[nextTerminatorPos+1:] 447 | finished = True 448 | elif nextTerminatorPos > nextCommaPos: 449 | # there is another parameter in this block: 450 | contentString = remainderString[:nextCommaPos] 451 | remainderString = remainderString[nextCommaPos+1:] 452 | else: 453 | assert False, "internal error (this case shouldn't be hit)" 454 | 455 | if content is None: 456 | # block parser didn't return any value, or current parameter is a non-block value; 457 | # so use entire raw string as "content" 458 | content = contentString 459 | 460 | resultArgs.append(content) 461 | 462 | if finished: 463 | break 464 | 465 | assert(remainderString) 466 | currIndex = len(argString) - len(remainderString) 467 | currIndex+=1 468 | 469 | return (resultArgs, remainderString) 470 | 471 | def _parseArgs(self, argString): 472 | """ 473 | Parses an argument string and returns a (possibly nested) list of arguments. 474 | 475 | >>> parser = StraceParser() 476 | >>> parser._parseArgs('42') 477 | ['42'] 478 | >>> parser._parseArgs('5, 42') 479 | ['5', '42'] 480 | 481 | >>> parser._parseArgs('5, FIONREAD, [0]') 482 | ['5', 'FIONREAD', ['0']] 483 | >>> parser._parseArgs('4, [{"ab, c]def", 9}, {"", 0}], 2') 484 | ['4', [['"ab, c]def"', '9'], ['""', '0']], '2'] 485 | """ 486 | endSymbol = {'{':'}', '[':']', '"':'"'} 487 | # short-cut: if there is no {, [, " in the whole argString, use split 488 | if all([sym not in argString for sym in endSymbol.keys()]): 489 | # remove the comma and space at the end of argString, then split 490 | # it by ', ' 491 | resultArgs = argString.rstrip(' ,').split(', ') 492 | # remove all empty split 493 | return filter(len, resultArgs) 494 | 495 | # otherwise, use a complex method to break the argument list, in order 496 | # to ensure the comma inside {}, [], "" would not break things. 497 | (content, remainderString) = self._parseBlockArg(argString, False) 498 | assert not(remainderString), "remainder left after parsing: '%s'" % remainderString 499 | return content 500 | 501 | 502 | if __name__ == '__main__': 503 | print "running some tests..." 504 | import doctest 505 | doctest.testmod() 506 | 507 | -------------------------------------------------------------------------------- /test/ls.out: -------------------------------------------------------------------------------- 1 | 12679 14:30:11.731864 execve("/bin/ls", ["ls"], [/* 61 vars */]) = 0 2 | 12679 14:30:11.732634 brk(0) = 0x1690000 3 | 12679 14:30:11.732790 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7ea5488000 4 | 12679 14:30:11.732945 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) 5 | 12679 14:30:11.733110 open("/etc/ld.so.cache", O_RDONLY) = 3 6 | 12679 14:30:11.733234 fstat(3, {st_mode=S_IFREG|0644, st_size=133467, ...}) = 0 7 | 12679 14:30:11.733381 mmap(NULL, 133467, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7ea5467000 8 | 12679 14:30:11.733486 close(3) = 0 9 | 12679 14:30:11.733614 open("/lib64/libselinux.so.1", O_RDONLY) = 3 10 | 12679 14:30:11.733729 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20V`Q;\0\0\0"..., 832) = 832 11 | 12679 14:30:11.733871 fstat(3, {st_mode=S_IFREG|0755, st_size=124592, ...}) = 0 12 | 12679 14:30:11.734020 mmap(0x3b51600000, 2221872, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3b51600000 13 | 12679 14:30:11.734131 mprotect(0x3b5161d000, 2093056, PROT_NONE) = 0 14 | 12679 14:30:11.734242 mmap(0x3b5181c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x3b5181c000 15 | 12679 14:30:11.734370 mmap(0x3b5181e000, 1840, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3b5181e000 16 | 12679 14:30:11.734482 close(3) = 0 17 | 12679 14:30:11.734598 open("/lib64/librt.so.1", O_RDONLY) = 3 18 | 12679 14:30:11.734718 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@! Q;\0\0\0"..., 832) = 832 19 | 12679 14:30:11.734852 fstat(3, {st_mode=S_IFREG|0755, st_size=47072, ...}) = 0 20 | 12679 14:30:11.735006 mmap(0x3b51200000, 2128816, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3b51200000 21 | 12679 14:30:11.735114 mprotect(0x3b51207000, 2093056, PROT_NONE) = 0 22 | 12679 14:30:11.735225 mmap(0x3b51406000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x3b51406000 23 | 12679 14:30:11.735347 close(3) = 0 24 | 12679 14:30:11.735473 open("/lib64/libcap.so.2", O_RDONLY) = 3 25 | 12679 14:30:11.735593 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\23 ^;\0\0\0"..., 832) = 832 26 | 12679 14:30:11.735715 fstat(3, {st_mode=S_IFREG|0755, st_size=18920, ...}) = 0 27 | 12679 14:30:11.735871 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7ea5466000 28 | 12679 14:30:11.735990 mmap(0x3b5e200000, 2111680, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3b5e200000 29 | 12679 14:30:11.736097 mprotect(0x3b5e204000, 2093056, PROT_NONE) = 0 30 | 12679 14:30:11.736206 mmap(0x3b5e403000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x3b5e403000 31 | 12679 14:30:11.736326 close(3) = 0 32 | 12679 14:30:11.736441 open("/lib64/libacl.so.1", O_RDONLY) = 3 33 | 12679 14:30:11.736559 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\35\340\f5\0\0\0"..., 832) = 832 34 | 12679 14:30:11.736681 fstat(3, {st_mode=S_IFREG|0755, st_size=34336, ...}) = 0 35 | 12679 14:30:11.736824 mmap(0x350ce00000, 2126992, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x350ce00000 36 | 12679 14:30:11.736944 mprotect(0x350ce07000, 2097152, PROT_NONE) = 0 37 | 12679 14:30:11.737053 mmap(0x350d007000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x350d007000 38 | 12679 14:30:11.737172 close(3) = 0 39 | 12679 14:30:11.737287 open("/lib64/libc.so.6", O_RDONLY) = 3 40 | 12679 14:30:11.737405 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\355\341O;\0\0\0"..., 832) = 832 41 | 12679 14:30:11.737526 fstat(3, {st_mode=S_IFREG|0755, st_size=1838296, ...}) = 0 42 | 12679 14:30:11.737669 mmap(0x3b4fe00000, 3664040, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3b4fe00000 43 | 12679 14:30:11.737776 mprotect(0x3b4ff75000, 2097152, PROT_NONE) = 0 44 | 12679 14:30:11.737900 mmap(0x3b50175000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x175000) = 0x3b50175000 45 | 12679 14:30:11.738027 mmap(0x3b5017a000, 18600, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3b5017a000 46 | 12679 14:30:11.738140 close(3) = 0 47 | 12679 14:30:11.738268 open("/lib64/libdl.so.2", O_RDONLY) = 3 48 | 12679 14:30:11.738402 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\r P;\0\0\0"..., 832) = 832 49 | 12679 14:30:11.738524 fstat(3, {st_mode=S_IFREG|0755, st_size=22536, ...}) = 0 50 | 12679 14:30:11.738667 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7ea5465000 51 | 12679 14:30:11.738785 mmap(0x3b50200000, 2109696, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3b50200000 52 | 12679 14:30:11.738914 mprotect(0x3b50202000, 2097152, PROT_NONE) = 0 53 | 12679 14:30:11.739024 mmap(0x3b50402000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x3b50402000 54 | 12679 14:30:11.739229 close(3) = 0 55 | 12679 14:30:11.739347 open("/lib64/libpthread.so.0", O_RDONLY) = 3 56 | 12679 14:30:11.739470 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\\`P;\0\0\0"..., 832) = 832 57 | 12679 14:30:11.739592 fstat(3, {st_mode=S_IFREG|0755, st_size=145672, ...}) = 0 58 | 12679 14:30:11.739735 mmap(0x3b50600000, 2212768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3b50600000 59 | 12679 14:30:11.739852 mprotect(0x3b50617000, 2097152, PROT_NONE) = 0 60 | 12679 14:30:11.739968 mmap(0x3b50817000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x3b50817000 61 | 12679 14:30:11.740097 mmap(0x3b50819000, 13216, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3b50819000 62 | 12679 14:30:11.740212 close(3) = 0 63 | 12679 14:30:11.740332 open("/lib64/libattr.so.1", O_RDONLY) = 3 64 | 12679 14:30:11.740654 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\23\340`;\0\0\0"..., 832) = 832 65 | 12679 14:30:11.740878 fstat(3, {st_mode=S_IFREG|0755, st_size=20280, ...}) = 0 66 | 12679 14:30:11.741028 mmap(0x3b60e00000, 2113072, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3b60e00000 67 | 12679 14:30:11.741137 mprotect(0x3b60e04000, 2093056, PROT_NONE) = 0 68 | 12679 14:30:11.741247 mmap(0x3b61003000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x3b61003000 69 | 12679 14:30:11.741366 close(3) = 0 70 | 12679 14:30:11.741490 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7ea5464000 71 | 12679 14:30:11.741647 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7ea5462000 72 | 12679 14:30:11.741763 arch_prctl(ARCH_SET_FS, 0x7f7ea54627a0) = 0 73 | 12679 14:30:11.741942 mprotect(0x3b5181c000, 4096, PROT_READ) = 0 74 | 12679 14:30:11.742058 mprotect(0x3b51406000, 4096, PROT_READ) = 0 75 | 12679 14:30:11.742165 mprotect(0x3b50175000, 16384, PROT_READ) = 0 76 | 12679 14:30:11.742273 mprotect(0x3b50402000, 4096, PROT_READ) = 0 77 | 12679 14:30:11.742381 mprotect(0x3b4f81e000, 4096, PROT_READ) = 0 78 | 12679 14:30:11.742489 mprotect(0x3b50817000, 4096, PROT_READ) = 0 79 | 12679 14:30:11.742599 munmap(0x7f7ea5467000, 133467) = 0 80 | 12679 14:30:11.742735 set_tid_address(0x7f7ea5462a70) = 12679 81 | 12679 14:30:11.742846 set_robust_list(0x7f7ea5462a80, 0x18) = 0 82 | 12679 14:30:11.742951 futex(0x7fffbd4fa94c, FUTEX_WAKE_PRIVATE, 1) = 0 83 | 12679 14:30:11.743063 futex(0x7fffbd4fa94c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, NULL, 7f7ea54627a0) = -1 EAGAIN (Resource temporarily unavailable) 84 | 12679 14:30:11.743190 rt_sigaction(SIGRTMIN, {0x3b50605a90, [], SA_RESTORER|SA_SIGINFO, 0x3b5060f4c0}, NULL, 8) = 0 85 | 12679 14:30:11.743332 rt_sigaction(SIGRT_1, {0x3b50605b20, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x3b5060f4c0}, NULL, 8) = 0 86 | 12679 14:30:11.743464 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 87 | 12679 14:30:11.743576 getrlimit(RLIMIT_STACK, {rlim_cur=10240*1024, rlim_max=RLIM_INFINITY}) = 0 88 | 12679 14:30:11.743776 statfs("/selinux", {f_type=0xf97cff8c, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0 89 | 12679 14:30:11.744272 brk(0) = 0x1690000 90 | 12679 14:30:11.744375 brk(0x16b1000) = 0x16b1000 91 | 12679 14:30:11.744540 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3 92 | 12679 14:30:11.744670 fstat(3, {st_mode=S_IFREG|0644, st_size=99158752, ...}) = 0 93 | 12679 14:30:11.744815 mmap(NULL, 99158752, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7e9f5d1000 94 | 12679 14:30:11.744984 close(3) = 0 95 | 12679 14:30:11.745116 ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 96 | 12679 14:30:11.745223 ioctl(1, TIOCGWINSZ, {ws_row=30, ws_col=100, ws_xpixel=0, ws_ypixel=0}) = 0 97 | 12679 14:30:11.745324 open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 98 | 12679 14:30:11.745407 fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC) 99 | 12679 14:30:11.745490 getdents(3, /* 353 entries */, 32768) = 16560 100 | 12679 14:30:11.748749 brk(0x16db000) = 0x16db000 101 | 12679 14:30:11.748831 brk(0x16d2000) = 0x16d2000 102 | 12679 14:30:11.748970 getdents(3, /* 0 entries */, 32768) = 0 103 | 12679 14:30:11.749040 close(3) = 0 104 | 12679 14:30:11.749661 open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3 105 | 12679 14:30:11.749748 fstat(3, {st_mode=S_IFREG|0644, st_size=26050, ...}) = 0 106 | 12679 14:30:11.750054 mmap(NULL, 26050, PROT_READ, MAP_SHARED, 3, 0) = 0x7f7ea5481000 107 | 12679 14:30:11.750131 close(3) = 0 108 | 12679 14:30:11.750206 futex(0x3b50179f60, FUTEX_WAKE_PRIVATE, 2147483647) = 0 109 | 12679 14:30:11.750518 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 125), ...}) = 0 110 | 12679 14:30:11.750618 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7ea5480000 111 | 12679 14:30:11.750701 write(1, "00001.avi\n", 10) = 10 112 | 12679 14:30:11.750786 write(1, "00001.mpeg\n", 11) = 11 113 | 12679 14:30:11.750891 write(1, "007-4273-003.pdf\n", 17) = 17 114 | 12679 14:30:11.750973 write(1, "05.MapReduce.pdf\n", 17) = 17 115 | 12679 14:30:11.751053 write(1, "086.pdf\n", 8) = 8 116 | 12679 14:30:11.751133 write(1, "10gRAConRHEL4.sxw\n", 18) = 18 117 | 12679 14:30:11.751214 write(1, "1150170835-NEC_RedHat_SIP-3.1.pd"..., 34) = 34 118 | 12679 14:30:11.751295 write(1, "115588.pdf\n", 11) = 11 119 | 12679 14:30:11.751373 write(1, "12248_div.pdf\n", 14) = 14 120 | 12679 14:30:11.751451 write(1, "128(2).py\n", 10) = 10 121 | 12679 14:30:11.751529 write(1, "128.py\n", 7) = 7 122 | 12679 14:30:11.751606 write(1, "18thJUl(2).tar.gz\n", 18) = 18 123 | 12679 14:30:11.751686 write(1, "18thJUl(2).tar.gz.part\n", 23) = 23 124 | 12679 14:30:11.751766 write(1, "18thJUl(3).tar.gz.part\n", 23) = 23 125 | 12679 14:30:11.751869 write(1, "18thJUl.tar.gz\n", 15) = 15 126 | 12679 14:30:11.751952 write(1, "2006sep_edition10_ima_user_guide"..., 40) = 40 127 | 12679 14:30:11.752036 write(1, "2006sep_edition10_ima_user_guide"..., 37) = 37 128 | 12679 14:30:11.752121 write(1, "2008-04-30_SPICE.pdf\n", 21) = 21 129 | 12679 14:30:11.752201 write(1, "2008-04-30_SPICE_perf.pdf\n", 26) = 26 130 | 12679 14:30:11.752282 write(1, "200810101050.pdf\n", 17) = 17 131 | 12679 14:30:11.752364 write(1, "20090312 Red Hat Enterprise Virt"..., 51) = 51 132 | 12679 14:30:11.752446 write(1, "2009-09-09-josef-StoragePerforma"..., 48) = 48 133 | 12679 14:30:11.752528 write(1, "220101.pdf\n", 11) = 11 134 | 12679 14:30:11.752606 write(1, "321211.pdf\n", 11) = 11 135 | 12679 14:30:11.753420 write(1, "438861-AA3.pdf\n", 15) = 15 136 | 12679 14:30:11.753546 write(1, "8.7\345\210\230\345\277\227\350\276\211\345\235\235\344\270\212\345\207\272\345\233\242.doc.pdf"..., 33) = 33 137 | 12679 14:30:11.753638 write(1, "Account_signup_and_login_v1.0.1."..., 36) = 36 138 | 12679 14:30:11.753722 write(1, "acl-2.2.29-CITI_NFS4_ALL-3.dif\n", 31) = 31 139 | 12679 14:30:11.753905 write(1, "acpi_cpufreq_add_acpi_perf_data_"..., 64) = 64 140 | 12679 14:30:11.753989 write(1, "ACPI_Overview.pdf\n", 18) = 18 141 | 12679 14:30:11.754069 write(1, "adobe-release-i386-1.0-1.noarch."..., 36) = 36 142 | 12679 14:30:11.754150 write(1, "allmydata-tahoe-1.6.1\n", 22) = 22 143 | 12679 14:30:11.754231 write(1, "allow_html_temp-2.0.1-tb.xpi\n", 29) = 29 144 | 12679 14:30:11.754313 write(1, "Anatomy_of_Oops.pdf\n", 20) = 20 145 | 12679 14:30:11.754393 write(1, "angkor-wat.kml\n", 15) = 15 146 | 12679 14:30:11.754472 write(1, "AppCompat(2).pdf\n", 17) = 17 147 | 12679 14:30:11.754551 write(1, "AppCompat.pdf\n", 14) = 14 148 | 12679 14:30:11.754629 write(1, "AtosOrigin(HK)Ltd.csv\n", 22) = 22 149 | 12679 14:30:11.754708 write(1, "audit-ids.pdf\n", 14) = 14 150 | 12679 14:30:11.755328 write(1, "autofs-5.0.1-0.rc2.143.el5.src.r"..., 35) = 35 151 | 12679 14:30:11.755418 write(1, "autofs-5.0.5-23.el6.src.rpm\n", 28) = 28 152 | 12679 14:30:11.755500 write(1, "autofs-debuginfo-5.0.1-0.rc2.143"..., 48) = 48 153 | 12679 14:30:11.755604 write(1, "autofs-debuginfo-5.0.5-23.el6.x8"..., 41) = 41 154 | 12679 14:30:11.755687 write(1, "b-GA7E8TMKNY.pdf\n", 17) = 17 155 | 12679 14:30:11.755767 write(1, "bind-utils-9.3.6-4.P1.el5_4.2.i3"..., 39) = 39 156 | 12679 14:30:11.755876 write(1, "??Bing\n", 7) = 7 157 | 12679 14:30:11.755954 write(1, "blktrace.pdf\n", 13) = 13 158 | 12679 14:30:11.756038 write(1, "boci_20090811.cert\n", 19) = 19 159 | 12679 14:30:11.756117 write(1, "booksample.pdf\n", 15) = 15 160 | 12679 14:30:11.756195 write(1, "bouml-4.23-p3-RHEL5.x86_64.rpm\n", 31) = 31 161 | 12679 14:30:11.756278 write(1, "b-whitepaper_implementing_highly"..., 90) = 90 162 | 12679 14:30:11.756362 write(1, "b-whitepaper_implementing_highly"..., 88) = 88 163 | 12679 14:30:11.756444 write(1, "b-whitepaper_nbu_architecture_ov"..., 57) = 57 164 | 12679 14:30:11.756526 write(1, "b-whitepaper_using_virtual_tape_"..., 75) = 75 165 | 12679 14:30:11.756607 write(1, "c00797875.pdf\n", 14) = 14 166 | 12679 14:30:11.756684 write(1, "c01633264.pdf\n", 14) = 14 167 | 12679 14:30:11.756762 write(1, "cacert.crt\n", 11) = 11 168 | 12679 14:30:11.756863 write(1, "Cache White Paper Xeon V1.pdf\n", 30) = 30 169 | 12679 14:30:11.756947 write(1, "catalina.out\n", 13) = 13 170 | 12679 14:30:11.757031 write(1, "cdrom.c\n", 8) = 8 171 | 12679 14:30:11.757106 write(1, "cegy00.xls\n", 11) = 11 172 | 12679 14:30:11.757185 write(1, "celgene-corp.cert\n", 18) = 18 173 | 12679 14:30:11.757265 write(1, "certificate_discovery_scenarios_"..., 40) = 40 174 | 12679 14:30:11.757345 write(1, "charts.tgz\n", 11) = 11 175 | 12679 14:30:11.757424 write(1, "cheungto.pdf\n", 13) = 13 176 | 12679 14:30:11.757501 write(1, "chrome\n", 7) = 7 177 | 12679 14:30:11.757577 write(1, "chrome.manifest\n", 16) = 16 178 | 12679 14:30:11.757655 write(1, "Cigna%20International%20Claim%20"..., 49) = 49 179 | 12679 14:30:11.757736 write(1, "Claim Form.pdf\n", 15) = 15 180 | 12679 14:30:11.757829 write(1, "Clicker_hi.apk\n", 15) = 15 181 | 12679 14:30:11.758086 write(1, "clsa_2.cert\n", 12) = 12 182 | 12679 14:30:11.758169 write(1, "clsa.cert\n", 10) = 10 183 | 12679 14:30:11.758247 write(1, "ClusterPitfalls(2).ppt\n", 23) = 23 184 | 12679 14:30:11.758328 write(1, "ClusterPitfalls.ppt\n", 20) = 20 185 | 12679 14:30:11.758409 write(1, "cman-1.0.27-1.el4.src.rpm\n", 26) = 26 186 | 12679 14:30:11.758489 write(1, "compactheader-0.6.2-tb.xpi\n", 27) = 27 187 | 12679 14:30:11.758570 write(1, "CompanyMeetingSlides3Q10PDF.pdf\n", 32) = 32 188 | 12679 14:30:11.758652 write(1, "console-messages-rac\n", 21) = 21 189 | 12679 14:30:11.758731 write(1, "core.27354\n", 11) = 11 190 | 12679 14:30:11.758828 write(1, "create-channel-update\n", 22) = 22 191 | 12679 14:30:11.758910 write(1, "CSatChina-FY10(2).sxc\n", 22) = 22 192 | 12679 14:30:11.758991 write(1, "CSatChina-FY10(3).sxc\n", 22) = 22 193 | 12679 14:30:11.759086 write(1, "CSatChina-FY10.sxc\n", 19) = 19 194 | 12679 14:30:11.759172 write(1, "CSAT_Graph.sxc\n", 15) = 15 195 | 12679 14:30:11.759260 write(1, "CSAT_Survey--May09.sxc\n", 23) = 23 196 | 12679 14:30:11.759349 write(1, "csbrief.pdf\n", 12) = 12 197 | 12679 14:30:11.759430 write(1, "cs-training-project2.doc\n", 25) = 25 198 | 12679 14:30:11.759524 write(1, "cs-training-project.doc\n", 24) = 24 199 | 12679 14:30:11.759614 write(1, "cs-training-project.sxw\n", 24) = 24 200 | 12679 14:30:11.759706 write(1, "customer.csv\n", 13) = 13 201 | 12679 14:30:11.759802 write(1, "data_sheet.pdf\n", 15) = 15 202 | 12679 14:30:11.759887 write(1, "defaults\n", 9) = 9 203 | 12679 14:30:11.759973 write(1, "device-mapper-1.02.39-1.el5_5.2."..., 41) = 41 204 | 12679 14:30:11.760061 write(1, "device-mapper-1.02.39-1.el5_5.2."..., 43) = 43 205 | 12679 14:30:11.760151 write(1, "device-mapper-event-1.02.39-1.el"..., 49) = 49 206 | 12679 14:30:11.760240 write(1, "DOC-22168.pdf\n", 14) = 14 207 | 12679 14:30:11.760329 write(1, "DOC-46950.pdf\n", 14) = 14 208 | 12679 14:30:11.760415 write(1, "document(2).svc\n", 16) = 16 209 | 12679 14:30:11.760509 write(1, "document(3).svc\n", 16) = 16 210 | 12679 14:30:11.760598 write(1, "document.pdf\n", 13) = 13 211 | 12679 14:30:11.760677 write(1, "document.svc\n", 13) = 13 212 | 12679 14:30:11.760761 write(1, "dotguide.pdf\n", 13) = 13 213 | 12679 14:30:11.760858 write(1, "download.csv\n", 13) = 13 214 | 12679 14:30:11.760938 write(1, "dsi.cert\n", 9) = 9 215 | 12679 14:30:11.761020 write(1, "E18429_01.pdf\n", 14) = 14 216 | 12679 14:30:11.761110 write(1, "e20_001_Storage_Technology_Found"..., 48) = 48 217 | 12679 14:30:11.761210 write(1, "eAdviceFile(2).pdf\n", 19) = 19 218 | 12679 14:30:11.761298 write(1, "eAdviceFile(3).pdf\n", 19) = 19 219 | 12679 14:30:11.761384 write(1, "eAdviceFile(4).pdf\n", 19) = 19 220 | 12679 14:30:11.761474 write(1, "eAdviceFile.pdf\n", 16) = 16 221 | 12679 14:30:11.761703 write(1, "email_source.log\n", 17) = 17 222 | 12679 14:30:11.761797 write(1, "emc-ap-training-schedule.pdf\n", 29) = 29 223 | 12679 14:30:11.761881 write(1, "ENG110.Bugzilla-v1.2.0.pdf\n", 27) = 27 224 | 12679 14:30:11.761963 write(1, "ENG111_Errata_Tool_and_Workflow_"..., 41) = 41 225 | 12679 14:30:11.762046 write(1, "ENG112-ContentDefinitionWorkflow"..., 40) = 40 226 | 12679 14:30:11.762128 write(1, "ENG114.Brew(2).pdf\n", 19) = 19 227 | 12679 14:30:11.762207 write(1, "ENG114.Brew.pdf\n", 16) = 16 228 | 12679 14:30:11.762286 write(1, "ENG119.RHTS.pdf\n", 16) = 16 229 | 12679 14:30:11.762364 write(1, "Enterprise_Agr_HongKong.pdf\n", 28) = 28 230 | 12679 14:30:11.762446 write(1, "EntitlementsWhitePaper.pdf\n", 27) = 27 231 | 12679 14:30:11.762527 write(1, "eStatementFile.pdf\n", 19) = 19 232 | 12679 14:30:11.762608 write(1, "FactSheet_Q3_2009_FINAL.pdf\n", 28) = 28 233 | 12679 14:30:11.762690 write(1, "family-status-change-form.doc\n", 30) = 30 234 | 12679 14:30:11.762784 write(1, "FAQ_20090429_Chn.pdf\n", 21) = 21 235 | 12679 14:30:11.762866 write(1, "fence_ilo\n", 10) = 10 236 | 12679 14:30:11.762943 write(1, "fence_vmware\n", 13) = 13 237 | 12679 14:30:11.763021 write(1, "firefox\n", 8) = 8 238 | 12679 14:30:11.763098 write(1, "FujitsuLimitedL3SIP_20080929.odt"..., 33) = 33 239 | 12679 14:30:11.763179 write(1, "gan.rar\n", 8) = 8 240 | 12679 14:30:11.763262 write(1, "gan's_f2l_oll_pll(08.08.25\346\233\264\346\226\260"..., 46) = 46 241 | 12679 14:30:11.763347 write(1, "glasses.pdf\n", 12) = 12 242 | 12679 14:30:11.763425 write(1, "GoalSettingResourceExample1.pdf\n", 32) = 32 243 | 12679 14:30:11.763506 write(1, "GoalSettingResourceExample2.pdf\n", 32) = 32 244 | 12679 14:30:11.763587 write(1, "GSS_All_Hands_31_Mar_2010.pdf\n", 30) = 30 245 | 12679 14:30:11.763670 write(1, "GSS_All_Hands_Q1FY10-v2-FINAL(2)"..., 37) = 37 246 | 12679 14:30:11.763751 write(1, "GSS_All_Hands_Q1FY10-v2-FINAL.pd"..., 34) = 34 247 | 12679 14:30:11.763849 write(1, "GSSAPSatCertHowTo.odt\n", 22) = 22 248 | 12679 14:30:11.763931 write(1, "GSS-Enterprise-Support-Services-"..., 59) = 59 249 | 12679 14:30:11.764015 write(1, "GSS-Enterprise-Support-Services-"..., 56) = 56 250 | 12679 14:30:11.764098 write(1, "GSS-Global-Services.sxi\n", 24) = 24 251 | 12679 14:30:11.764181 write(1, "GSS_QuickGuide.pdf\n", 19) = 19 252 | 12679 14:30:11.764262 write(1, "GSS-RedHat-Service-Offering(2).s"..., 35) = 35 253 | 12679 14:30:11.764343 write(1, "GSS-RedHat-Service-Offering.sxi\n", 32) = 32 254 | 12679 14:30:11.764424 write(1, "gss-report\n", 11) = 11 255 | 12679 14:30:11.764501 write(1, "guacamole-0.2.6\n", 16) = 16 256 | 12679 14:30:11.764579 write(1, "guacamole-0.2.6.tar.gz\n", 23) = 23 257 | 12679 14:30:11.764659 write(1, "GuitarTuner.zip\n", 16) = 16 258 | 12679 14:30:11.764737 write(1, "Handbook.doc\n", 13) = 13 259 | 12679 14:30:11.764833 write(1, "Hardware_Certification_Policy.pd"..., 34) = 34 260 | 12679 14:30:11.764916 write(1, "harper-Reprint.pdf\n", 19) = 19 261 | 12679 14:30:11.765328 write(1, "hi3g-access-ab.cert\n", 20) = 20 262 | 12679 14:30:11.765413 write(1, "HK-Cust-List\n", 13) = 13 263 | 12679 14:30:11.765493 write(1, "hong-kong-air-cargo-terminals-li"..., 46) = 46 264 | 12679 14:30:11.765575 write(1, "hong-kong-air-cargo-terminals-li"..., 43) = 43 265 | 12679 14:30:11.765656 write(1, "hospital-authority.cert\n", 24) = 24 266 | 12679 14:30:11.765737 write(1, "HP-Device-Mapper-Configuration-G"..., 67) = 67 267 | 12679 14:30:11.765834 write(1, "HP_NetTop_Whitepaper2.pdf\n", 26) = 26 268 | 12679 14:30:11.765918 write(1, "hs_err_pid14699.log\n", 20) = 20 269 | 12679 14:30:11.765997 write(1, "hwcert\n", 7) = 7 270 | 12679 14:30:11.766074 write(1, "HWCert_Presentation.wyn.pdf\n", 28) = 28 271 | 12679 14:30:11.766156 write(1, "Image001.jpg\n", 13) = 13 272 | 12679 14:30:11.766234 write(1, "index.html\n", 11) = 11 273 | 12679 14:30:11.766313 write(1, "inode.pdf\n", 10) = 10 274 | 12679 14:30:11.766391 write(1, "in_out_fund_template.pdf\n", 25) = 25 275 | 12679 14:30:11.766473 write(1, "Installation Variants.pdf\n", 26) = 26 276 | 12679 14:30:11.766554 write(1, "install.js\n", 11) = 11 277 | 12679 14:30:11.766642 write(1, "install.rdf\n", 12) = 12 278 | 12679 14:30:11.766720 write(1, "iotop-0.4.1\n", 12) = 12 279 | 12679 14:30:11.766816 write(1, "iotop-0.4.1.tar.bz2\n", 20) = 20 280 | 12679 14:30:11.766900 write(1, "IO_Tuning_Guide.pdf\n", 20) = 20 281 | 12679 14:30:11.766980 write(1, "IOzone_msword_98(2).pdf\n", 24) = 24 282 | 12679 14:30:11.767061 write(1, "IOzone_msword_98.pdf\n", 21) = 21 283 | 12679 14:30:11.767141 write(1, "irc2.9.5.tgz\n", 13) = 13 284 | 12679 14:30:11.767221 write(1, "ISM_Brochure.pdf\n", 17) = 17 285 | 12679 14:30:11.767301 write(1, "issue.csv\n", 10) = 10 286 | 12679 14:30:11.767380 write(1, "issue.ods\n", 10) = 10 287 | 12679 14:30:11.767459 write(1, "ITILTrainingPresentation.pdf\n", 29) = 29 288 | 12679 14:30:11.767540 write(1, "izxj9ssv\n", 9) = 9 289 | 12679 14:30:11.767619 write(1, "javafixcisco.xpi\n", 17) = 17 290 | 12679 14:30:11.767701 write(1, "jesus_life_gb.txt\n", 18) = 18 291 | 12679 14:30:11.767793 write(1, "jesus_life.txt\n", 15) = 15 292 | 12679 14:30:11.767876 write(1, "jumbomem-manual.pdf\n", 20) = 20 293 | 12679 14:30:11.767956 write(1, "kSar-5.1.0.jar\n", 15) = 15 294 | 12679 14:30:11.768201 write(1, "ksm-aa-ie-cw.pdf\n", 17) = 17 295 | 12679 14:30:11.768292 write(1, "KvmForum2007$kvm_pv_drv(2).pdf\n", 31) = 31 296 | 12679 14:30:11.768375 write(1, "KvmForum2007$kvm_pv_drv.pdf\n", 28) = 28 297 | 12679 14:30:11.768459 write(1, "lecture3.pdf\n", 13) = 13 298 | 12679 14:30:11.768537 write(1, "leftyguide.pdf\n", 15) = 15 299 | 12679 14:30:11.768616 write(1, "leroy_build_mod_condor.ppt\n", 27) = 27 300 | 12679 14:30:11.768704 write(1, "licence.txt\n", 12) = 12 301 | 12679 14:30:11.768799 write(1, "Linux Block Device Architecture("..., 35) = 35 302 | 12679 14:30:11.768884 write(1, "LinuxJournal_pNFS_article_ljones"..., 37) = 37 303 | 12679 14:30:11.768969 write(1, "LinuxRDAC v9.15 for Kernel2.6 on"..., 57) = 57 304 | 12679 14:30:11.769051 write(1, "lloyd_nature_406_1047_00.pdf\n", 29) = 29 305 | 12679 14:30:11.769132 write(1, "lmbench-2.0.4-2.EL4.i386.rpm\n", 29) = 29 306 | 12679 14:30:11.769212 write(1, "load.pdf\n", 9) = 9 307 | 12679 14:30:11.769291 write(1, "LTN20090302465_C.pdf\n", 21) = 21 308 | 12679 14:30:11.769372 write(1, "LTN20090312079_C.pdf\n", 21) = 21 309 | 12679 14:30:11.769452 write(1, "lvm2-2.02.27-2.el4.src.rpm\n", 27) = 27 310 | 12679 14:30:11.769533 write(1, "lvm2-2.02.56-8.el5_5.6.x86_64.rp"..., 34) = 34 311 | 12679 14:30:11.769615 write(1, "lvm2-cluster-2.02.56-7.el5_5.4.x"..., 42) = 42 312 | 12679 14:30:11.769696 write(1, "LVM Beyond the Basics.pdf\n", 26) = 26 313 | 12679 14:30:11.769794 write(1, "Manhood 10 - Three Cheers for Me"..., 48) = 48 314 | 12679 14:30:11.769879 write(1, "Manhood 15 - Genesis and Manhood"..., 43) = 43 315 | 12679 14:30:11.769964 write(1, "Manhood_15_-_Genesis_and_Manhood"..., 45) = 45 316 | 12679 14:30:11.770046 write(1, "Manhood 20 - A Man and His Wife-"..., 44) = 44 317 | 12679 14:30:11.770127 write(1, "Manhood 2 - Four Faces of Manhoo"..., 38) = 38 318 | 12679 14:30:11.770208 write(1, "Marco_Bill-Peter_Team_Results.pd"..., 34) = 34 319 | 12679 14:30:11.770290 write(1, "mastering-super-timeline-log2tim"..., 44) = 44 320 | 12679 14:30:11.770372 write(1, "Mastering_the_super_timeline_log"..., 52) = 52 321 | 12679 14:30:11.770453 write(1, "mdadm-2.5.tgz\n", 14) = 14 322 | 12679 14:30:11.770533 write(1, "Migrating SGLX cluster to RHCS C"..., 60) = 60 323 | 12679 14:30:11.770616 write(1, "mrta_PI_tch_1106.pdf\n", 21) = 21 324 | 12679 14:30:11.770695 write(1, "msg00937.pdf\n", 13) = 13 325 | 12679 14:30:11.770793 write(1, "MSP(D)2981 Personal details upda"..., 51) = 51 326 | 12679 14:30:11.770878 write(1, "nagar-Reprint.pdf\n", 18) = 18 327 | 12679 14:30:11.770960 write(1, "neatoguide.pdf\n", 15) = 15 328 | 12679 14:30:11.771041 write(1, "nomura_cert\n", 12) = 12 329 | 12679 14:30:11.771119 write(1, "nomura.cert\n", 12) = 12 330 | 12679 14:30:11.771197 write(1, "NonStop_LanConfigAndMgtManual.pd"..., 34) = 34 331 | 12679 14:30:11.771278 write(1, "notify.py\n", 10) = 10 332 | 12679 14:30:11.771355 write(1, "nptl-design.pdf\n", 16) = 16 333 | 12679 14:30:11.771434 write(1, "nss_ldap-253-25.el5.src.rpm\n", 28) = 28 334 | 12679 14:30:11.771517 write(1, "ntpd.strace.6447\n", 17) = 17 335 | 12679 14:30:11.771598 write(1, "OEML3SIP_v15-5.pdf\n", 19) = 19 336 | 12679 14:30:11.771677 write(1, "ogcio1.cert\n", 12) = 12 337 | 12679 14:30:11.771755 write(1, "ogcio2.cert\n", 12) = 12 338 | 12679 14:30:11.771857 write(1, "ogcio3.cert\n", 12) = 12 339 | 12679 14:30:11.771935 write(1, "ogcio-eval_cert\n", 16) = 16 340 | 12679 14:30:11.772015 write(1, "ogcio-real_cert\n", 16) = 16 341 | 12679 14:30:11.772095 write(1, "oldfield-cv-2008.pdf\n", 21) = 21 342 | 12679 14:30:11.772175 write(1, "One_Page_Resume_RichardKeech.pdf"..., 33) = 33 343 | 12679 14:30:11.772256 write(1, "oocl.cert\n", 10) = 10 344 | 12679 14:30:11.772334 write(1, "oocl_sat_cert\n", 14) = 14 345 | 12679 14:30:11.772412 write(1, "openais-0.80.6-16.el5.src.rpm\n", 30) = 30 346 | 12679 14:30:11.772493 write(1, "openssh-blacklist-1.0.sh\n", 25) = 25 347 | 12679 14:30:11.772576 write(1, "openstacktutorialieeecloudcom-10"..., 56) = 56 348 | 12679 14:30:11.772657 write(1, "OracleRedHatRelationship.pdf\n", 29) = 29 349 | 12679 14:30:11.772744 write(1, "Oracle\345\216\237\345\216\202\345\237\271\350\256\255\346\212\245\345\220\215\350\241\250.-.Re"..., 53) = 53 350 | 12679 14:30:11.772849 write(1, "or-pro.pdf\n", 11) = 11 351 | 12679 14:30:11.772927 write(1, "overview.pdf\n", 13) = 13 352 | 12679 14:30:11.773005 write(1, "pa.cert\n", 8) = 8 353 | 12679 14:30:11.773083 write(1, "paic.cert\n", 10) = 10 354 | 12679 14:30:11.773161 write(1, "paic.cert.bk\n", 13) = 13 355 | 12679 14:30:11.773240 write(1, "paic-paic-eval.cert\n", 20) = 20 356 | 12679 14:30:11.773319 write(1, "paig.cert\n", 10) = 10 357 | 12679 14:30:11.773397 write(1, "patching-r2-131911.pdf\n", 23) = 23 358 | 12679 14:30:11.773477 write(1, "pathvalidation_wp.pdf\n", 22) = 22 359 | 12679 14:30:11.773558 write(1, "perf troubleshooting trans cs.pd"..., 34) = 34 360 | 12679 14:30:11.773639 write(1, "PhoneList.xls\n", 14) = 14 361 | 12679 14:30:11.773718 write(1, "phone_number.ods\n", 17) = 17 362 | 12679 14:30:11.773813 write(1, "phptagengine-1.0.zip\n", 21) = 21 363 | 12679 14:30:11.773895 write(1, "php.vim\n", 8) = 8 364 | 12679 14:30:11.773972 write(1, "PL-G2010-0601.pdf\n", 18) = 18 365 | 12679 14:30:11.774051 write(1, "qhli_eng.pdf\n", 13) = 13 366 | 12679 14:30:11.774131 write(1, "Quest PPT Session 10-Mentors-Cn-"..., 39) = 39 367 | 12679 14:30:11.774214 write(1, "Red_Hat_Enterprise_Linux-6-GDB_a"..., 68) = 68 368 | 12679 14:30:11.774297 write(1, "Red Hat Product Portfolio Improv"..., 87) = 87 369 | 12679 14:30:11.774378 write(1, "remote_access_agreement_statemen"..., 38) = 38 370 | 12679 14:30:11.774460 write(1, "restorevm(2).sql\n", 17) = 17 371 | 12679 14:30:11.774539 write(1, "restorevm.sql\n", 14) = 14 372 | 12679 14:30:11.774619 write(1, "resume_JohnLau.pdf\n", 19) = 19 373 | 12679 14:30:11.774701 write(1, "ResumeMikeFabian.pdf\n", 21) = 21 374 | 12679 14:30:11.774801 write(1, "resume.odt\n", 11) = 11 375 | 12679 14:30:11.774883 write(1, "rfbproto.pdf\n", 13) = 13 376 | 12679 14:30:11.774963 write(1, "rfc1305(2).pdf\n", 15) = 15 377 | 12679 14:30:11.775044 write(1, "rfc1305(3).pdf\n", 15) = 15 378 | 12679 14:30:11.775424 write(1, "rfc1305.pdf\n", 12) = 12 379 | 12679 14:30:11.775510 write(1, "rgmanager-2.0.52-1.el5_4.3.src.r"..., 35) = 35 380 | 12679 14:30:11.775592 write(1, "rgmanager-debuginfo-2.0.52-6.el5"..., 44) = 44 381 | 12679 14:30:11.775674 write(1, "rhce-exam-question-1.pdf\n", 25) = 25 382 | 12679 14:30:11.775755 write(1, "rhcf-the_movie-iPhone.mp4\n", 26) = 26 383 | 12679 14:30:11.775853 write(1, "RHCLogoHRE.eps\n", 15) = 15 384 | 12679 14:30:11.775932 write(1, "RHEL-4_en_US_netdump_crash.pdf\n", 31) = 31 385 | 12679 14:30:11.776013 write(1, "RHEL4-IO-Schedulers.pdf\n", 24) = 24 386 | 12679 14:30:11.776092 write(1, "rhel4_vm(2).pdf\n", 16) = 16 387 | 12679 14:30:11.776171 write(1, "rhel4_vm.pdf\n", 13) = 13 388 | 12679 14:30:11.776249 write(1, "RHEL6EnergySavings.odp\n", 23) = 23 389 | 12679 14:30:11.776329 write(1, "rhel6 info cards final.pdf\n", 27) = 27 390 | 12679 14:30:11.776410 write(1, "RHEL6-KVM.zip\n", 14) = 14 391 | 12679 14:30:11.776489 write(1, "RHELTuningandOptimizationforOrac"..., 45) = 45 392 | 12679 14:30:11.776571 write(1, "RHELTuningandOptimizationforOrac"..., 42) = 42 393 | 12679 14:30:11.776651 write(1, "RHEV\n", 5) = 5 394 | 12679 14:30:11.776729 write(1, "RH-MRG-Introduction-for-Customer"..., 37) = 37 395 | 12679 14:30:11.776827 write(1, "rhn_taskomatic_daemon.log.gz\n", 29) = 29 396 | 12679 14:30:11.776908 write(1, "Robert.sxw\n", 11) = 11 397 | 12679 14:30:11.776985 write(1, "rskndam.zip\n", 12) = 12 398 | 12679 14:30:11.777063 write(1, "sat_ent2.JPG\n", 13) = 13 399 | 12679 14:30:11.777140 write(1, "save_life.doc\n", 14) = 14 400 | 12679 14:30:11.777228 write(1, "scale-out-file-services-white-pa"..., 49) = 49 401 | 12679 14:30:11.777309 write(1, "ScorecarD.sxc\n", 14) = 14 402 | 12679 14:30:11.777387 write(1, "scponly-4.8.tgz\n", 16) = 16 403 | 12679 14:30:11.777464 write(1, "Screenshot-gnome-session.png\n", 29) = 29 404 | 12679 14:30:11.777546 write(1, "search_results.csv\n", 19) = 19 405 | 12679 14:30:11.777627 write(1, "SEC-W-0019-Linux.doc\n", 21) = 21 406 | 12679 14:30:11.777707 write(1, "SEG-ALL-HANDS-Q1FY12-v0.4.odp\n", 30) = 30 407 | 12679 14:30:11.777799 write(1, "share_ca-certs_Microsoft_Interne"..., 53) = 53 408 | 12679 14:30:11.777883 write(1, "share_ca-certs_Microsoft_Secure_"..., 58) = 58 409 | 12679 14:30:11.777964 write(1, "sosreport-bcawebp1-709288-0bcbaf"..., 41) = 41 410 | 12679 14:30:11.778045 write(1, "sosreport-pgsqlha2.tar.bz2\n", 27) = 27 411 | 12679 14:30:11.778125 write(1, "SpaceDebrisAstrolunch.pdf\n", 26) = 26 412 | 12679 14:30:11.778373 write(1, "SpaceDebrisAstrolunch.pdf.part\n", 31) = 31 413 | 12679 14:30:11.778459 write(1, "stardict-3.0.1-20.fc12.x86_64.rp"..., 34) = 34 414 | 12679 14:30:11.778540 write(1, "stock032410.pdf\n", 16) = 16 415 | 12679 14:30:11.778618 write(1, "strace_analyzer_ng_0.09.pl\n", 27) = 27 416 | 12679 14:30:11.778699 write(1, "stress-0.18.8-1.3.EL4.i386.rpm\n", 31) = 31 417 | 12679 14:30:11.778794 write(1, "Summit08presentation_GFSBestPrac"..., 48) = 48 418 | 12679 14:30:11.778878 write(1, "sun-ray-software-ds-065317.pdf\n", 31) = 31 419 | 12679 14:30:11.778958 write(1, "syllabus_forSaba(2).pdf\n", 24) = 24 420 | 12679 14:30:11.779038 write(1, "syllabus_forSaba(3).pdf\n", 24) = 24 421 | 12679 14:30:11.779117 write(1, "syllabus_forSaba(4).pdf\n", 24) = 24 422 | 12679 14:30:11.779195 write(1, "syllabus_forSaba(5).pdf\n", 24) = 24 423 | 12679 14:30:11.779275 write(1, "syllabus_forSaba(6).pdf\n", 24) = 24 424 | 12679 14:30:11.779355 write(1, "syllabus_forSaba(7).pdf\n", 24) = 24 425 | 12679 14:30:11.779433 write(1, "syllabus_forSaba(8).pdf\n", 24) = 24 426 | 12679 14:30:11.779513 write(1, "syllabus_forSaba(9).pdf\n", 24) = 24 427 | 12679 14:30:11.779592 write(1, "syllabus_forSaba.pdf\n", 21) = 21 428 | 12679 14:30:11.779672 write(1, "sysklogd-1.4.1-28.el4.src.rpm\n", 30) = 30 429 | 12679 14:30:11.779754 write(1, "sysreport-root.bss-db1.tar.bz2-f"..., 68) = 68 430 | 12679 14:30:11.779850 write(1, "SystemTap_Beginners_Guide.pdf\n", 30) = 30 431 | 12679 14:30:11.779932 write(1, "System-Tuning-in-General.sxw\n", 29) = 29 432 | 12679 14:30:11.780013 write(1, "System_users.pdf\n", 17) = 17 433 | 12679 14:30:11.780093 write(1, "TAM-Webinar-Cluster-Best-Practic"..., 42) = 42 434 | 12679 14:30:11.780173 write(1, "tburke_rhel6_summit.pdf\n", 24) = 24 435 | 12679 14:30:11.780252 write(1, "TCP-Keepalive-HOWTO.pdf\n", 24) = 24 436 | 12679 14:30:11.780332 write(1, "TeamProcessTrackingSheet.sxc\n", 29) = 29 437 | 12679 14:30:11.780413 write(1, "thunderbird\n", 12) = 12 438 | 12679 14:30:11.780492 write(1, "thunderbird_message_filter_impor"..., 59) = 59 439 | 12679 14:30:11.780573 write(1, "thunderfilter\n", 14) = 14 440 | 12679 14:30:11.780650 write(1, "udev.pdf\n", 9) = 9 441 | 12679 14:30:11.780728 write(1, "util_tst.plg\n", 13) = 13 442 | 12679 14:30:11.780822 write(1, "virtio-drivers-1.0.0-45801.vfd\n", 31) = 31 443 | 12679 14:30:11.780903 write(1, "vmware_timekeeping.pdf\n", 23) = 23 444 | 12679 14:30:11.780984 write(1, "VPNRedHatPHX2RSA.vpn\n", 21) = 21 445 | 12679 14:30:11.781063 write(1, "WEB_McNaught_Path.pdf\n", 22) = 22 446 | 12679 14:30:11.781143 write(1, "wordpress-3.1.tar.gz\n", 21) = 21 447 | 12679 14:30:11.781222 write(1, "wp-2005_bfs.pdf\n", 16) = 16 448 | 12679 14:30:11.781300 write(1, "www.dedoimedo.com-crash-book.pdf"..., 33) = 33 449 | 12679 14:30:11.781381 write(1, "www.dedoimedo.com-crash-book.pdf"..., 38) = 38 450 | 12679 14:30:11.781466 write(1, "Xajax\344\270\255\346\226\207\346\211\213\345\206\214.zip\n", 22) = 22 451 | 12679 14:30:11.781549 write(1, "xchat-notify.py\n", 16) = 16 452 | 12679 14:30:11.781628 write(1, "XFS-0.1-XFS_Filesystem_Structure"..., 43) = 43 453 | 12679 14:30:11.781708 write(1, "XFS-0.1-XFS_Labs-en-US.pdf\n", 27) = 27 454 | 12679 14:30:11.781799 write(1, "XFS-0.1-XFS_User_Guide-en-US.pdf"..., 33) = 33 455 | 12679 14:30:11.781883 write(1, "xfs_filesystem_structure.pdf\n", 29) = 29 456 | 12679 14:30:11.781963 write(1, "xfs_slides_01_background.pdf\n", 29) = 29 457 | 12679 14:30:11.782052 write(1, "xfs_slides_02_overview.pdf\n", 27) = 27 458 | 12679 14:30:11.782133 write(1, "xfs_slides_09_internals.pdf\n", 28) = 28 459 | 12679 14:30:11.782214 write(1, "xfs_slides_15_dmapi.pdf\n", 24) = 24 460 | 12679 14:30:11.782296 write(1, "\345\271\263\345\256\211\350\257\201\345\210\270.cert\n", 18) = 18 461 | 12679 14:30:11.782383 write(1, "\351\230\277Bing.rar\n", 12) = 12 462 | 12679 14:30:11.782474 close(1) = 0 463 | 12679 14:30:11.782546 munmap(0x7f7ea5480000, 4096) = 0 464 | 12679 14:30:11.782629 close(2) = 0 465 | 12679 14:30:11.782723 exit_group(0) = ? 466 | --------------------------------------------------------------------------------