diff --git a/guider/guider.py b/guider/guider.py index 5138c66e..437c632c 100755 --- a/guider/guider.py +++ b/guider/guider.py @@ -7,7 +7,7 @@ __credits__ = "Peace Lee" __license__ = "GPLv2" __version__ = "3.9.8" -__revision__ = "241122" +__revision__ = "241123" __maintainer__ = "Peace Lee" __email__ = "iipeace5@gmail.com" __repository__ = "https://github.com/iipeace/guider" @@ -37988,6 +37988,7 @@ def _checkMode(): "printdir", "printdlt", "printext", + "ps", "pstree", "readelf", "report", @@ -38380,6 +38381,7 @@ def getCmdList(): "printsig": ("Signal", "Linux/Android"), "printslab": ("Slab", "Linux/Android"), "printvma": ("Vmalloc", "Linux/Android"), + "ps": ("Process", "Linux/Android/MacOS/Windows"), "pstree": ("Process", "Linux/Android/MacOS/Windows"), "readahead": ("File", "Linux/Android"), "readelf": ("File", "Linux/Android/MacOS/Windows"), @@ -45677,6 +45679,42 @@ def _getDesc(s, t=0): "Print system info", ) + # ps # + elif SysMgr.checkMode("ps"): + helpStr = ( + _getDesc("Show the task list") + + """ +Options: + -e enable options + [ t:thread ] + -g set filter + -o set output path + -S sort by key + [ c:cpu / m:mem / p:pid / N:name / b:block / w:wfc + n:new / r:runtime / P:prio ] + -J print in JSON format + -v verbose + """ + ) + + helpStr += """ +Examples: + - {2:1} all processes + # {0:1} {1:1} + + - {2:1} specific processes + # {0:1} {1:1} -g a.out + # {0:1} {1:1} -g "a.out, yes" + # {0:1} {1:1} -q CMDLINEFILTER:"*a.out*" + + - {2:1} all threads + # {0:1} {1:1} -e t + """.format( + cmd, + mode, + "Print the tree list of", + ) + # pstree # elif SysMgr.checkMode("pstree"): helpStr = ( @@ -57367,80 +57405,11 @@ def _printJson(path, obj): # LIMIT MODE # elif SysMgr.isLimitMode(): - # change the CPU scheduling priority for tasks # - if SysMgr.prio is None: - SysMgr.setPriority(SysMgr.pid, "C", -20) - - # get argument # - if SysMgr.hasMainArg(): - filterGroup = SysMgr.getMainArgs() - else: - filterGroup = SysMgr.filterGroup - - # check input # - if not filterGroup: - SysMgr.printErr("no input value for task limit info") - sys.exit(-1) - - # get resource name # - if SysMgr.checkMode("limitcpu"): - if "NOCG" in SysMgr.environList: - limitInfo = SysMgr.getLimitCpuInfo(filterGroup) - SysMgr.doLimitCpu(limitInfo, SysMgr.processEnable) - sys.exit(0) - name = "LIMITCPU" - elif SysMgr.checkMode("limitcpuset"): - name = "LIMITCPUSET" - elif SysMgr.checkMode("limitmem"): - name = "LIMITMEM" - elif SysMgr.checkMode("limitread"): - name = "LIMITREAD" - elif SysMgr.checkMode("limitwrite"): - name = "LIMITWRITE" - elif SysMgr.checkMode("limitpid"): - name = "LIMITPID" - else: - SysMgr.printErr("no support resource limitation") - sys.exit(-1) - - # parse limit info # - limitList = {name: []} - try: - for item in filterGroup: - target = item.split(":", 1) - if len(target) == 1: - raise Exception("no limit value") - - target, value = target - - # check targets # - targets = SysMgr.getTids( - target, - isThread=not SysMgr.processEnable, - sibling=SysMgr.groupProcEnable, - ) - if not targets: - SysMgr.printErr("no task for '%s'" % target) - sys.exit(-1) - - limitList[name].append(value + "@" + target) - except SystemExit: - sys.exit(0) - except: - SysMgr.printErr( - "failed to limit resource using %s" % name, True - ) - sys.exit(-1) + SysMgr.doLimit() - # limit resources # - pids = SysMgr.applyLimitVars(limitList) - - # start monitoring # - if "TASKMON" in SysMgr.environList: - SysMgr.runTaskMonitor(pids, wait=True) - else: - # wait for events # - SysMgr.waitEvent() + # PS MODE # + elif SysMgr.checkMode("ps"): + SysMgr.doPs() # PSTREE MODE # elif SysMgr.checkMode("pstree"): @@ -77420,6 +77389,225 @@ def mergeCommStat(statList, commIdx=None): return statList + @staticmethod + def doPs(): + SysMgr(onlyInstance=True) + + # save task info # + obj = TaskAnalyzer(onlyInstance=True) + obj.saveProcStat() + + # set sort value # + try: + sortedProcData = obj.getSortedProcData() + except SystemExit: + sys.exit(0) + except: + SysMgr.printWarn("failed to sort tasks", True, True) + sortedProcData = list(obj.procData) + + # get max pid len # + pd = max(4, max(list(map(len, sortedProcData)))) + + # comm length # + if "COMMLEN" in SysMgr.environList: + cl = UtilMgr.getEnvironNum("COMMLEN") + else: + cl = 26 - (pd * 2) + + # get types # + if SysMgr.processEnable: + mode = "Process" + pidType = "PID" + ppidType = "PPID" + else: + mode = "Thread" + pidType = "TID" + ppidType = "PID" + + if not SysMgr.jsonEnable: + SysMgr.printPipe( + ( + "{10:1}\n{0:>{cl}} {1:>{pd}} {2:>{pd}} {3:1} {4:>4} {5:>4} " + "{6:>4} {7:>8} {8:>9} {9:1}\n{10:1}" + ).format( + mode, + pidType, + ppidType, + "S", + "Nr", + "Pri", + "RSS", + "User", + "LifeTime", + "CMD", + twoLine, + cl=cl, + pd=pd, + ) + ) + + filterGroup = SysMgr.filterGroup + cmdFilter = SysMgr.environList.get("CMDLINEFILTER") + + nrPrint = 0 + for idx, value in sortedProcData: + # save status info # + obj.saveProcStatusData(value["taskPath"], idx) + try: + status = value["status"] + except SystemExit: + sys.exit(0) + except: + status = None + + comm = value["comm"] + + # check ID/COMM filter # + if filterGroup: + if ( + not idx in filterGroup + and not UtilMgr.isValidStr(comm, filterGroup) + ): + continue + + # save cmdline # + obj.saveCmdlineData(value["taskPath"], idx, force=True) + cmdline = obj.procData[idx]["cmdline"] + + # check cmdline filter # + if cmdFilter and not UtilMgr.isValidStr(cmdline, cmdFilter): + continue + + nrTask = value["stat"][obj.nrthreadIdx] + stat = value["stat"][obj.statIdx] + rss = long(value["stat"][obj.rssIdx]) >> 8 + + # save user # + obj.saveUserData(idx) + user = value["user"] + + # lifetime # + value["runtime"] = long( + SysMgr.uptime - (float(value["stat"][obj.starttimeIdx]) / 100) + ) + lifeTime = UtilMgr.convTime(value["runtime"]) + + # parent ID # + if SysMgr.processEnable: + pid = value["stat"][obj.ppidIdx] + else: + pid = value["mainID"] + + # sched priority # + schedPolicy, schedValue = obj.getSchedInfo(value["stat"]) + sched = schedPolicy + schedValue.strip() + + SysMgr.printPipe( + ( + "{0:>{cl}} {1:>{pd}} {2:>{pd}} {3:1} {4:>4} {5:>4} " + "{6:>4} {7:>8} {8:>9} {9:1}" + ).format( + comm, + idx, + pid, + stat, + nrTask, + sched, + rss, + user[:8], + lifeTime[:9], + cmdline, + cl=cl, + pd=pd, + ) + ) + nrPrint += 1 + + if SysMgr.jsonEnable: + pass + else: + if nrPrint == 0: + SysMgr.printPipe("\tNone") + SysMgr.printPipe(oneLine) + + @staticmethod + def doLimit(): + # change the CPU scheduling priority for tasks # + if SysMgr.prio is None: + SysMgr.setPriority(SysMgr.pid, "C", -20) + + # get argument # + if SysMgr.hasMainArg(): + filterGroup = SysMgr.getMainArgs() + else: + filterGroup = SysMgr.filterGroup + + # check input # + if not filterGroup: + SysMgr.printErr("no input value for task limit info") + sys.exit(-1) + + # get resource name # + if SysMgr.checkMode("limitcpu"): + if "NOCG" in SysMgr.environList: + limitInfo = SysMgr.getLimitCpuInfo(filterGroup) + SysMgr.doLimitCpu(limitInfo, SysMgr.processEnable) + sys.exit(0) + name = "LIMITCPU" + elif SysMgr.checkMode("limitcpuset"): + name = "LIMITCPUSET" + elif SysMgr.checkMode("limitmem"): + name = "LIMITMEM" + elif SysMgr.checkMode("limitread"): + name = "LIMITREAD" + elif SysMgr.checkMode("limitwrite"): + name = "LIMITWRITE" + elif SysMgr.checkMode("limitpid"): + name = "LIMITPID" + else: + SysMgr.printErr("no support resource limitation") + sys.exit(-1) + + # parse limit info # + limitList = {name: []} + try: + for item in filterGroup: + target = item.split(":", 1) + if len(target) == 1: + raise Exception("no limit value") + + target, value = target + + # check targets # + targets = SysMgr.getTids( + target, + isThread=not SysMgr.processEnable, + sibling=SysMgr.groupProcEnable, + ) + if not targets: + SysMgr.printErr("no task for '%s'" % target) + sys.exit(-1) + + limitList[name].append(value + "@" + target) + except SystemExit: + sys.exit(0) + except: + SysMgr.printErr( + "failed to limit resource using %s" % name, True + ) + sys.exit(-1) + + # limit resources # + pids = SysMgr.applyLimitVars(limitList) + + # start monitoring # + if "TASKMON" in SysMgr.environList: + SysMgr.runTaskMonitor(pids, wait=True) + else: + # wait for events # + SysMgr.waitEvent() + @staticmethod def doLimitCpu(limitInfo, isProcess=False, verb=True): CLK_PRECISION = 100000 @@ -150784,6 +150972,22 @@ def printTaskUsageGen(self, idIndex=False): SysMgr.addPrint(oneLine) + def saveUserData(self, pid): + try: + if pid in self.prevProcData and "user" in self.prevProcData[pid]: + self.procData[pid]["user"] = self.prevProcData[pid]["user"] + elif self.isKernelThread(pid): + raise Exception("kernel thread") + else: + SysMgr.sysInstance.saveUserInfo() + userData = SysMgr.sysInstance.userData + uid = self.procData[pid]["status"]["Uid"].split(None, 1)[0] + self.procData[pid]["user"] = userData[uid]["name"] + except SystemExit: + sys.exit(0) + except: + self.procData[pid]["user"] = "-" + def printTaskUsage(self, idIndex=False): isValidStr = UtilMgr.isValidStr @@ -151461,21 +151665,8 @@ def _memFactorPG(stat): except: status = None - # user # - try: - if idx in prevProcData and "user" in prevProcData[idx]: - value["user"] = prevProcData[idx]["user"] - elif self.isKernelThread(idx): - raise Exception("kernel thread") - else: - SysMgr.sysInstance.saveUserInfo() - userData = SysMgr.sysInstance.userData - uid = status["Uid"].split(None, 1)[0] - value["user"] = userData[uid]["name"] - except SystemExit: - sys.exit(0) - except: - value["user"] = "-" + # save user # + self.saveUserData(idx) # check user # if userFilter and not isValidStr(value["user"], userFilter):