diff --git a/guider/guider.py b/guider/guider.py index 12c900ad..5138c66e 100755 --- a/guider/guider.py +++ b/guider/guider.py @@ -7,7 +7,7 @@ __credits__ = "Peace Lee" __license__ = "GPLv2" __version__ = "3.9.8" -__revision__ = "241121" +__revision__ = "241122" __maintainer__ = "Peace Lee" __email__ = "iipeace5@gmail.com" __repository__ = "https://github.com/iipeace/guider" @@ -10157,7 +10157,9 @@ def execReceiverTask(): tcp = sock if idx == 1 else None # start thread # - tobj = threadObj.Thread(target=SysMgr.runServerTask, args=[uds, tcp]) + tobj = threadObj.Thread( + target=SysMgr.runServerTask, args=[uds, tcp] + ) tobj.daemon = True tobj.start() @@ -23447,8 +23449,7 @@ def getProcMapList(pid): sys.exit(0) except: SysMgr.printWarn( - "failed to get map list of %s" - % SysMgr.getTaskStr(pid), + "failed to get map list of %s" % SysMgr.getTaskStr(pid), reason=True, ) return {} @@ -28648,9 +28649,9 @@ def getNrCrash(retDir=False): customNrCrash += len(UtilMgr.getFiles(path, recursive=False)) for path, name, exceptList in ( - ("/data/tombstones", ["*.pb"], []), # android # - ("/ccos/data/log/trace", [], ["*json"]), # ccos # - ("/var/crash", ["*.crash"], []), # ubuntu # + ("/data/tombstones", ["*.pb"], []), # android # + ("/ccos/data/log/trace", [], ["*json"]), # ccos # + ("/var/crash", ["*.crash"], []), # ubuntu # ): if not os.path.isdir(path): continue @@ -30814,32 +30815,45 @@ def execTopCmd(): @staticmethod def loadLibCache(): try: - # no ld cache file # - if not SysMgr.ldCachePath: - return + libDict = {} - if not os.path.exists(SysMgr.ldCachePath): - reason = SysMgr.ldCachePath - SysMgr.ldCachePath = None - raise Exception("no %s" % reason) + # using ld cache file # + if SysMgr.ldCachePath: + if not os.path.exists(SysMgr.ldCachePath): + reason = SysMgr.ldCachePath + SysMgr.ldCachePath = None + raise Exception("no %s" % reason) - libDict = {} + # load libs from cache # + libList = UtilMgr.convBin2Str(SysMgr.ldCachePath) + for idx, item in enumerate(libList): + try: + if libList[idx + 1].startswith("/"): + value = libList[idx + 1] + libDict.setdefault(item, []) + libDict[item].append(value) + except SystemExit: + sys.exit(0) + except: + pass - # load libs from cache # - libList = UtilMgr.convBin2Str(SysMgr.ldCachePath) - for idx, item in enumerate(libList): - try: - if libList[idx + 1].startswith("/"): - value = libList[idx + 1] - libDict.setdefault(item, []) - libDict[item].append(value) - except SystemExit: - sys.exit(0) - except: - pass + # save lib list # + SysMgr.libCache = libDict + + if not "SEARCHLIBDIR" in SysMgr.environList: + raise Exception() - # load libs form /usr/local/lib # - for path in ("/usr/local/lib", "/usr/local/lib64"): + # load libs from regular directories # + for path in ( + "/usr/local/lib", + "/usr/local/lib64", + "/system/lib", + "/system/lib64", + "/vendor/lib", + "/vendor/lib64", + "/product/lib", + "/product/lib64", + ): if not os.path.exists(path): continue @@ -30851,9 +30865,6 @@ def loadLibCache(): libDict.setdefault(item, []) libDict[item].append(value) - - # save lib list # - SysMgr.libCache = libDict except SystemExit: sys.exit(0) except: @@ -35685,8 +35696,7 @@ def getAffinity(pid): sys.exit(0) except: SysMgr.printWarn( - "failed to get CPU affinity for %s" - % SysMgr.getTaskStr(pid), + "failed to get CPU affinity for %s" % SysMgr.getTaskStr(pid), reason=True, ) @@ -36538,7 +36548,8 @@ def getUid(pid, itype="real"): sys.exit(0) except: SysMgr.printErr( - "failed to get UID for %s" % SysMgr.getTaskStr(pid), reason=True + "failed to get UID for %s" % SysMgr.getTaskStr(pid), + reason=True, ) return 0 @@ -37130,8 +37141,7 @@ def getMemStatList(pid): sys.exit(0) except: SysMgr.printWarn( - "failed to memory stats for %s" - % SysMgr.getTaskStr(pid), + "failed to memory stats for %s" % SysMgr.getTaskStr(pid), reason=True, ) return {} @@ -38068,13 +38078,19 @@ def _checkOS(): SysMgr.libdemanglePath = "libbacktrace" SysMgr.cacheDirPath = "/data/log/guider" # check commands only for Android # - elif len(sys.argv) > 1 and sys.argv[1] in ( - "logand", - "printand", - "andtop", - "attop", - "hprof", - "sperf", + elif ( + len(sys.argv) > 1 + and sys.argv[1] in ( + "andtop", + "attop", + "bdtop", + "hprof", + "logand", + "mdtop", + "printand", + "sperf", + ) + and not SysMgr.forceEnable ): SysMgr.printErr( "'%s' command is not supported on '%s' platform" @@ -38228,58 +38244,58 @@ def getCmdList(): return { "monitor": { "andtop": ("Log", "Android"), - "atop": ("All", "Linux"), + "atop": ("All", "Linux/Android"), "attop": ("Atrace", "Android"), - "bdtop": ("Binder", "Linux"), - "bgtop": ("Background", "Linux/MacOS/Windows"), - "btop": ("Function", "Linux"), - "cgtop": ("Cgroup", "Linux"), - "ctop": ("Threshold", "Linux/MacOS/Windows"), + "bdtop": ("Binder", "Android"), + "bgtop": ("Background", "Linux/Android/MacOS/Windows"), + "btop": ("Function", "Linux/Android"), + "cgtop": ("Cgroup", "Linux/Android"), + "ctop": ("Threshold", "Linux/Android/MacOS/Windows"), "dbustop": ("D-Bus", "Linux"), - "disktop": ("Storage", "Linux/MacOS/Windows"), + "disktop": ("Storage", "Linux/Android/MacOS/Windows"), "dlttop": ("DLT", "Linux/MacOS"), - "fetop": ("File", "Linux"), - "ftop": ("File", "Linux/MacOS"), - "irqtop": ("IRQ", "Linux"), - "kftop": ("Function", "Linux"), - "ktop": ("Function", "Linux"), - "mdtop": ("Memory", "Linux"), - "mtop": ("Memory", "Linux"), - "ntop": ("Network", "Linux/MacOS/Windows"), - "ptop": ("PMU", "Linux"), - "pytop": ("Python", "Linux"), - "rtop": ("JSON", "Linux/MacOS/Windows"), - "slabtop": ("Slab", "Linux"), - "stacktop": ("Stack", "Linux"), - "systop": ("Syscall", "Linux"), - "top": ("Process", "Linux/MacOS/Windows"), - "tptop": ("Ftrace", "Linux"), - "trtop": ("Tree", "Linux"), - "ttop": ("Thread", "Linux"), - "utop": ("Function", "Linux"), - "vtop": ("Memory", "Linux"), - "wtop": ("WSS", "Linux"), + "fetop": ("File", "Linux/Android"), + "ftop": ("File", "Linux/Android/MacOS"), + "irqtop": ("IRQ", "Linux/Android"), + "kftop": ("Function", "Linux/Android"), + "ktop": ("Function", "Linux/Android"), + "mdtop": ("Memory", "Android"), + "mtop": ("Memory", "Linux/Android"), + "ntop": ("Network", "Linux/Android/MacOS/Windows"), + "ptop": ("PMU", "Linux/Android"), + "pytop": ("Python", "Linux/Android"), + "rtop": ("JSON", "Linux/Android/MacOS/Windows"), + "slabtop": ("Slab", "Linux/Android"), + "stacktop": ("Stack", "Linux/Android"), + "systop": ("Syscall", "Linux/Android"), + "top": ("Process", "Linux/Android/MacOS/Windows"), + "tptop": ("Ftrace", "Linux/Android"), + "trtop": ("Tree", "Linux/Android"), + "ttop": ("Thread", "Linux/Android"), + "utop": ("Function", "Linux/Android"), + "vtop": ("Memory", "Linux/Android"), + "wtop": ("WSS", "Linux/Android"), }, "trace": { - "btrace": ("Function", "Linux"), - "leaktrace": ("Leak", "Linux"), - "mtrace": ("Memory", "Linux"), - "pytrace": ("Python", "Linux"), - "sigtrace": ("Signal", "Linux"), - "strace": ("Syscall", "Linux"), - "utrace": ("Function", "Linux"), + "btrace": ("Function", "Linux/Android"), + "leaktrace": ("Leak", "Linux/Android"), + "mtrace": ("Memory", "Linux/Android"), + "pytrace": ("Python", "Linux/Android"), + "sigtrace": ("Signal", "Linux/Android"), + "strace": ("Syscall", "Linux/Android"), + "utrace": ("Function", "Linux/Android"), }, "profile": { - "filerec": ("File", "Linux"), - "funcrec": ("Function", "Linux"), - "genrec": ("System", "Linux"), + "filerec": ("File", "Linux/Android"), + "funcrec": ("Function", "Linux/Android"), + "genrec": ("System", "Linux/Android"), "hprof": ("Memory", "Android"), - "iorec": ("I/O", "Linux"), - "mem": ("Page", "Linux"), - "rec": ("Thread", "Linux"), - "report": ("Report", "Linux"), + "iorec": ("I/O", "Linux/Android"), + "mem": ("Page", "Linux/Android"), + "rec": ("Thread", "Linux/Android"), + "report": ("Report", "Linux/Android/MacOS/Windows"), "sperf": ("Function", "Android"), - "sysrec": ("Syscall", "Linux"), + "sysrec": ("Syscall", "Linux/Android"), }, "visual": { "convert": ("Text", "Linux/MacOS/Windows"), @@ -38308,107 +38324,107 @@ def getCmdList(): "drawvssavg": ("VSS", "Linux/MacOS/Windows"), }, "control": { - "cgroup": ("Cgroup", "Linux"), - "freeze": ("Thread", "Linux"), - "hook": ("Function", "Linux"), - "kill/tkill": ("Signal", "Linux/MacOS"), - "limitcpu": ("CPU", "Linux"), - "limitcpuset": ("CPU", "Linux"), - "limitmem": ("Memory", "Linux"), - "limitpid": ("Task", "Linux"), - "limitread": ("I/O", "Linux"), - "limitwrite": ("I/O", "Linux"), - "pause": ("Thread", "Linux"), - "remote": ("Command", "Linux"), - "rlimit": ("Resource", "Linux"), - "setafnt": ("Affinity", "Linux"), - "setcpu": ("Clock", "Linux"), - "setsched": ("Priority", "Linux"), + "cgroup": ("Cgroup", "Linux/Android"), + "freeze": ("Thread", "Linux/Android"), + "hook": ("Function", "Linux/Android"), + "kill/tkill": ("Signal", "Linux/Android/MacOS"), + "limitcpu": ("CPU", "Linux/Android"), + "limitcpuset": ("CPU", "Linux/Android"), + "limitmem": ("Memory", "Linux/Android"), + "limitpid": ("Task", "Linux/Android"), + "limitread": ("I/O", "Linux/Android"), + "limitwrite": ("I/O", "Linux/Android"), + "pause": ("Thread", "Linux/Android"), + "remote": ("Command", "Linux/Android"), + "rlimit": ("Resource", "Linux/Android"), + "setafnt": ("Affinity", "Linux/Android"), + "setcpu": ("Clock", "Linux/Android"), + "setsched": ("Priority", "Linux/Android"), }, "util": { - "addr2sym": ("Symbol", "Linux/MacOS/Windows"), - "checkdup": ("Page", "Linux"), - "comp": ("Compress", "Linux/MacOS/Windows"), - "decomp": ("Decompress", "Linux/MacOS/Windows"), - "demangle": ("Demangling", "Linux/MacOS/Windows"), - "dirdiff": ("Dir", "Linux/MacOS/Windows"), - "dump": ("Memory", "Linux"), - "elftree": ("ELF", "Linux/MacOS/Windows"), - "exec": ("Command", "Linux/MacOS/Windows"), - "flush": ("Memory", "Linux"), - "fadvise": ("File", "Linux"), - "getafnt": ("Affinity", "Linux"), - "getpid": ("PID", "Linux"), - "less": ("Pager", "Linux/MacOS/Windows"), - "merge": ("File", "Linux/MacOS/Windows"), - "mkcache": ("Cache", "Linux/MacOS/Windows"), - "mnttree": ("Mount", "Linux"), - "mount": ("Mount", "Linux"), - "ping": ("ICMP", "Linux/MacOS/Windows"), - "print": ("File", "Linux/MacOS/Windows"), - "printbind": ("Function", "Linux"), - "printcg": ("Cgroup", "Linux"), + "addr2sym": ("Symbol", "Linux/Android/MacOS/Windows"), + "checkdup": ("Page", "Linux/Android"), + "comp": ("Compress", "Linux/Android/MacOS/Windows"), + "decomp": ("Decompress", "Linux/Android/MacOS/Windows"), + "demangle": ("Demangling", "Linux/Android/MacOS/Windows"), + "dirdiff": ("Dir", "Linux/Android/MacOS/Windows"), + "dump": ("Memory", "Linux/Android"), + "elftree": ("ELF", "Linux/Android/MacOS/Windows"), + "exec": ("Command", "Linux/Android/MacOS/Windows"), + "flush": ("Memory", "Linux/Android"), + "fadvise": ("File", "Linux/Android"), + "getafnt": ("Affinity", "Linux/Android"), + "getpid": ("PID", "Linux/Android"), + "less": ("Pager", "Linux/Android/MacOS/Windows"), + "merge": ("File", "Linux/Android/MacOS/Windows"), + "mkcache": ("Cache", "Linux/Android/MacOS/Windows"), + "mnttree": ("Mount", "Linux/Android"), + "mount": ("Mount", "Linux/Android"), + "ping": ("ICMP", "Linux/Android/MacOS/Windows"), + "print": ("File", "Linux/Android/MacOS/Windows"), + "printbind": ("Function", "Linux/Android"), + "printcg": ("Cgroup", "Linux/Android"), "printdbus": ("D-Bus", "Linux"), "printdbusintro": ("D-Bus", "Linux"), "printdbusstat": ("D-Bus", "Linux"), "printdbussub": ("D-Bus", "Linux"), - "printdir": ("Dir", "Linux/MacOS/Windows"), - "printenv": ("Env", "Linux"), - "printext": ("Ext4", "Linux/MacOS/Windows"), - "printinfo": ("System", "Linux"), - "printkconf": ("kernel", "Linux"), - "printns": ("Namespace", "Linux"), + "printdir": ("Dir", "Linux/Android/MacOS/Windows"), + "printenv": ("Env", "Linux/Android"), + "printext": ("Ext4", "Linux/Android/MacOS/Windows"), + "printinfo": ("System", "Linux/Android"), + "printkconf": ("kernel", "Linux/Android"), + "printns": ("Namespace", "Linux/Android"), "printsdfile": ("Systemd", "Linux"), "printsdinfo": ("Systemd", "Linux"), "printsdunit": ("Systemd", "Linux"), - "printsig": ("Signal", "Linux"), - "printslab": ("Slab", "Linux"), - "printvma": ("Vmalloc", "Linux"), - "pstree": ("Process", "Linux/MacOS/Windows"), - "readahead": ("File", "Linux"), - "readelf": ("File", "Linux/MacOS/Windows"), - "req": ("URL", "Linux/MacOS/Windows"), - "split": ("File", "Linux/MacOS/Windows"), - "strings": ("Text", "Linux/MacOS/Windows"), - "sym2addr": ("Address", "Linux/MacOS/Windows"), - "sync": ("File", "Linux"), - "sysrq": ("sysrq", "Linux"), - "systat": ("Status", "Linux"), - "topdiff": ("Diff", "Linux/MacOS/Windows"), - "topsum": ("Summary", "Linux/MacOS/Windows"), - "umount": ("Unmount", "Linux"), - "watch": ("File", "Linux"), + "printsig": ("Signal", "Linux/Android"), + "printslab": ("Slab", "Linux/Android"), + "printvma": ("Vmalloc", "Linux/Android"), + "pstree": ("Process", "Linux/Android/MacOS/Windows"), + "readahead": ("File", "Linux/Android"), + "readelf": ("File", "Linux/Android/MacOS/Windows"), + "req": ("URL", "Linux/Android/MacOS/Windows"), + "split": ("File", "Linux/Android/MacOS/Windows"), + "strings": ("Text", "Linux/Android/MacOS/Windows"), + "sym2addr": ("Address", "Linux/Android/MacOS/Windows"), + "sync": ("File", "Linux/Android"), + "sysrq": ("sysrq", "Linux/Android"), + "systat": ("Status", "Linux/Android"), + "topdiff": ("Diff", "Linux/Android/MacOS/Windows"), + "topsum": ("Summary", "Linux/Android/MacOS/Windows"), + "umount": ("Unmount", "Linux/Android"), + "watch": ("File", "Linux/Android"), }, "log": { "logand": ("Log", "Android"), "logdlt": ("DLT", "Linux"), "logjrl": ("Journal", "Linux"), - "logkmsg": ("Kernel", "Linux"), + "logkmsg": ("Kernel", "Linux/Android"), "logsys": ("Syslog", "Linux"), - "logtrace": ("Ftrace", "Linux"), + "logtrace": ("Ftrace", "Linux/Android"), "printdlt": ("DLT", "Linux/MacOS/Windows"), "printjrl": ("Journal", "Linux"), - "printkmsg": ("Kernel", "Linux"), + "printkmsg": ("Kernel", "Linux/Android"), "printand": ("Log", "Android"), "printsyslog": ("Syslog", "Linux"), - "printtrace": ("Ftrace", "Linux"), + "printtrace": ("Ftrace", "Linux/Android"), }, "network": { - "cli": ("Client", "Linux/MacOS/Windows"), - "event": ("Event", "Linux"), - "fserver": ("File", "Linux/MacOS/Windows"), - "hserver": ("Http", "Linux/MacOS/Windows"), - "list": ("List", "Linux/MacOS/Windows"), - "send": ("UDP", "Linux/MacOS/Windows"), - "server": ("Server", "Linux/MacOS"), - "start": ("Signal", "Linux"), + "cli": ("Client", "Linux/Android/MacOS/Windows"), + "event": ("Event", "Linux/Android"), + "fserver": ("File", "Linux/Android/MacOS/Windows"), + "hserver": ("Http", "Linux/Android/MacOS/Windows"), + "list": ("List", "Linux/Android/MacOS/Windows"), + "send": ("UDP", "Linux/Android/MacOS/Windows"), + "server": ("Server", "Linux/Android/MacOS"), + "start": ("Signal", "Linux/Android"), }, "test": { - "cputest": ("CPU", "Linux/MacOS/Windows"), + "cputest": ("CPU", "Linux/Android/MacOS/Windows"), "helptest": ("HELP", "ALL"), - "iotest": ("Storage", "Linux/MacOS/Windows"), - "memtest": ("Memory", "Linux/MacOS/Windows"), - "nettest": ("Network", "Linux"), + "iotest": ("Storage", "Linux/Android/MacOS/Windows"), + "memtest": ("Memory", "Linux/Android/MacOS/Windows"), + "nettest": ("Network", "Linux/Android"), }, } @@ -45748,6 +45764,12 @@ def _getDesc(s, t=0): - {2:1} with depth limitation # {0:1} {1:1} test.bin -H 2 + + - {2:1} for only summary + # {0:1} {1:1} test.bin -q ONLYSUMMARY + + - {2:1} without summary + # {0:1} {1:1} test.bin -q NOSUMMARY """.format( cmd, mode, desc ) @@ -49777,9 +49799,8 @@ def printSigError(tid, signal, warn=True): signal = signal.split(".", 2)[1] printFunc( - "failed to send %s to %s" - % (signal, SysMgr.getTaskStr(tid)), - reason=True + "failed to send %s to %s" % (signal, SysMgr.getTaskStr(tid)), + reason=True, ) @staticmethod @@ -51123,8 +51144,7 @@ def printDelayTime(pid=None, force=False): sys.exit(0) except: SysMgr.printWarn( - "failed to get delay time for %s" - % SysMgr.getTaskStr(pid), + "failed to get delay time for %s" % SysMgr.getTaskStr(pid), reason=True, ) @@ -54393,7 +54413,8 @@ def printErr(line, reason=False, code=False): @staticmethod def getTaskStr(pid, cache=False, commCache=True): return "%s(%s)" % ( - SysMgr.getComm(pid, cache=cache, commCache=commCache), pid + SysMgr.getComm(pid, cache=cache, commCache=commCache), + pid, ) @staticmethod @@ -58333,8 +58354,7 @@ def getStartTime(pid=None): sys.exit(0) except: SysMgr.printWarn( - "failed to get start time of %s" - % SysMgr.getTaskStr(pid), + "failed to get start time of %s" % SysMgr.getTaskStr(pid), True, True, ) @@ -59250,7 +59270,7 @@ def saveMemDump(memTarget, out=False): # print result # if not SysMgr.outPath: for s in meminfostr.split("\n"): - ret = SysMgr.addPrint(s+"\n") + ret = SysMgr.addPrint(s + "\n") if not ret: break @@ -59594,7 +59614,7 @@ def _waitThreshold(pids, cond, timing, target, sig=False): size_kb: 63488 } -duration_ms: 0 +duration_ms: 100 write_into_file: true flush_timeout_ms: 30000 flush_period_ms: 604800000 @@ -59771,11 +59791,8 @@ def _waitTask(pid): if javaTarget: # wait for task termination # _waitTask(recPid) - elif stopRss: + elif stopRss or term: pass - elif term: - # wait for perfetto # - time.sleep(0.5) else: signal.pause() except: @@ -59788,7 +59805,9 @@ def _waitTask(pid): SysMgr.sendSignalProcs(signal.SIGINT, [recPid], verb=False) # check heapprofd processes # - dlist = True if term else SysMgr.getTids("heapprofd", False, True) + dlist = ( + True if term else SysMgr.getTids("heapprofd", False, True) + ) if not dlist: _printWarn( "no running heapprofd, check below commands", True @@ -60418,9 +60437,7 @@ def _convPkgList(p, pkglist): profileable = p.get("profileable_from_shell") versioncode = p.get("version_code") pinfo = ( - "%s(%s): debuggable(%s), " - "profileable(%s), " - "vercode(%s)" + "%s(%s): debuggable(%s), " "profileable(%s), " "vercode(%s)" ) % ( pname, uid, @@ -60536,8 +60553,16 @@ def _saveSysInfo(pstr): # print package list # if "GETPKGLIST" in SysMgr.environList: - pkgList = packets.get("packages_list", {}).get("packages", []) + pkgList = sorted( + packets.get("packages_list", {}).get("packages", []), + key=lambda x: x.get("name", ""), + ) + + # remove default output path # + if not SysMgr.findOption("o"): + SysMgr.outPath = None + # print package info # if SysMgr.jsonEnable: pkgDict = {} @@ -61550,8 +61575,7 @@ def getTaskStats(pid): if len(statList) + 1 < len(ConfigMgr.PROCSTAT_ATTR): SysMgr.printWarn( - "failed to read stat for %s" - % SysMgr.getTaskStr(pid) + "failed to read stat for %s" % SysMgr.getTaskStr(pid) ) return statDict @@ -63723,7 +63747,9 @@ def _removeSock(sock, pid): try: # create a connection object # if uds: - connObj = NetworkMgr("server", path=uds, uds=True, bind=False) + connObj = NetworkMgr( + "server", path=uds, uds=True, bind=False + ) else: connObj = NetworkMgr("server", ip=ip, tcp=True, bind=False) connObj.socket = sock @@ -75285,7 +75311,9 @@ def preexec(): except SystemExit: sys.exit(0) except: - SysMgr.printWarn("skip applying group", reason=True) + SysMgr.printWarn( + "skip applying group", reason=True + ) # get uid and gid # stats = SysMgr.getProcAttr(pid) @@ -76212,9 +76240,7 @@ def _printUsage(obj, size, alloc=True): sys.exit(-1) # parent # elif pid > 0: - SysMgr.printWarn( - "created %s process" % SysMgr.getTaskStr(pid) - ) + SysMgr.printWarn("created %s process" % SysMgr.getTaskStr(pid)) pidList.append(pid) # print stats # @@ -76626,47 +76652,88 @@ def doElfTree(): if not targetList: SysMgr.printErr("no file for input path") sys.exit(-1) + targetList = list(map(SysMgr.convFullPath, targetList)) # add environment variables # SysMgr.addEnvironVar("TARGETSECT", ".dynamic") SysMgr.addEnvironVar("NODEBUGFILE") + SysMgr.addEnvironVar("SEARCHLIBDIR") + treeCache = {} + skipCache = {} dynListCache = {} # define elf dependency analysis function # - def _getElfTree(tree, path, depth=0): + def _getElfTree(tree, path, is32Bit, depth=0): UtilMgr.printProgress() + + if path in skipCache: + return tree + tree.setdefault(path, {}) + # check tree cache # + if path in treeCache: + tree[path] = dict(treeCache[path]) + return tree + else: + treeCache[path] = tree[path] + # get .dynamic section info # - SysMgr.printEnable = False if path in dynListCache: dynList = dynListCache[path] else: - dynList = ElfAnalyzer(path, debug=True).attr.get("dynFiles") + try: + SysMgr.printEnable = False + + eobj = ElfAnalyzer(path, debug=True) + if not SysMgr.showAll and is32Bit != eobj.is32Bit: + tree.pop(path) + treeCache.pop(path) + skipCache[path] = None + return tree + else: + dynList = eobj.attr.get("dynFiles") + except SystemExit: + sys.exit(0) + except: + SysMgr.printWarn( + "failed to get dependency info from '%s'" % path + ) + dynList = [] + finally: + SysMgr.printEnable = True + + # save info # dynListCache[path] = dynList - SysMgr.printEnable = True if not dynList or (SysMgr.funcDepth and depth >= SysMgr.funcDepth): return tree # traverse dependent files # for f in dynList: fpathList = SysMgr.findLib(f) - for fpath in fpathList: - _getElfTree(tree[path], fpath, depth + 1) + for fpath in fpathList if fpathList else [f]: + _getElfTree(tree[path], fpath, is32Bit, depth + 1) return tree - # define printer # - def _printTree(d, depth=0): - def __getFileStr(f): + def _getFileStr(f): + try: prefix, fname = f.rsplit("/", 1) - fname = UtilMgr.convColor(fname, "YELLOW") - return prefix + "/" + fname + UtilMgr.getFileSizeStr(f) + except SystemExit: + sys.exit(0) + except: + prefix = "?" + fname = f + + fname = UtilMgr.convColor(fname, "YELLOW") + return prefix + "/" + fname + UtilMgr.getFileSizeStr(f) + # define printer # + def _printTree(d, depth=0): indent = " " for key, value in d.items(): - finfo = __getFileStr(key) + finfo = _getFileStr(key) SysMgr.printPipe( indent * depth + ("L " if depth else "") + finfo ) @@ -76674,18 +76741,25 @@ def __getFileStr(f): if isinstance(value, dict): _printTree(value, depth + 1) else: - finfo = __getFileStr(value) + finfo = _getFileStr(value) SysMgr.printPipe(indent * (depth + 1) + "L " + finfo) for f in targetList: try: + treeCache = {} + skipCache = {} + fcache = ElfAnalyzer.getHeader(f) + is32Bit = fcache.is32Bit if fcache else False + # make tree # - ret = _getElfTree({}, f) + ret = _getElfTree({}, f, is32Bit) UtilMgr.deleteProgress() # print tree # - if SysMgr.jsonEnable: + if "ONLYSUMMARY" in SysMgr.environList: + pass + elif SysMgr.jsonEnable: SysMgr.printPipe( UtilMgr.convDict2Str( ret, pretty=not SysMgr.streamEnable @@ -76695,6 +76769,24 @@ def __getFileStr(f): SysMgr.printPipe("\n[ELF Tree Info]\n%s" % twoLine) _printTree(ret) SysMgr.printPipe(oneLine) + + # print summary # + if ( + not SysMgr.jsonEnable + and not "NOSUMMARY" in SysMgr.environList + ): + SysMgr.printPipe( + ( + "\n[ELF Tree Summary] (Target:%s) " + "(NrFile: %s)\n%s" + ) % (f, UtilMgr.convNum(len(treeCache)-1), twoLine) + ) + for l in sorted(treeCache.keys()): + if f != l: + SysMgr.printPipe(_getFileStr(l)) + if not ret: + SysMgr.printPipe("\tNone") + SysMgr.printPipe(oneLine + "\n\n") except SystemExit: sys.exit(0) except: @@ -78271,8 +78363,7 @@ def getIoPriority(pid=0, who=1, verb=True): sys.exit(0) else: SysMgr.printErr( - "failed to get I/O priority of %s" - % SysMgr.getTaskStr(pid) + "failed to get I/O priority of %s" % SysMgr.getTaskStr(pid) ) return None @@ -108087,8 +108178,7 @@ def dumpTaskMemory(pid, meminfo, output): sys.exit(0) except: SysMgr.printErr( - "failed to dump memory for %s" - % SysMgr.getTaskStr(pid), + "failed to dump memory for %s" % SysMgr.getTaskStr(pid), reason=True, ) @@ -113435,9 +113525,7 @@ def _mergeTables(tpath, fromOrig=True): and ei_mag2 != ord("L") and ei_mag3 != ord("F") ): - SysMgr.printWarn( - errStr % (path, "it is not an ELF file"), debug - ) + SysMgr.printWarn(errStr % (path, "it is not an ELF file"), debug) self.ret = None ElfAnalyzer.failedFiles[path] = True return None @@ -125425,7 +125513,9 @@ def drawBoundary(self, gtype, labelList): bl = boundary - axvline(x=bl,linewidth=1, linestyle="--", color="black") + axvline( + x=bl, linewidth=1, linestyle="--", color="black" + ) else: ltype = "Horizontal" @@ -125437,10 +125527,13 @@ def drawBoundary(self, gtype, labelList): else: bl = boundary - axhline(y=bl,linewidth=1, linestyle="--", color="black") + axhline( + y=bl, linewidth=1, linestyle="--", color="black" + ) labelList.append( - "[ %s Boundary ] - %s" % (ltype, UtilMgr.convSize2Unit(boundary)) + "[ %s Boundary ] - %s" + % (ltype, UtilMgr.convSize2Unit(boundary)) ) except SystemExit: sys.exit(0) @@ -151009,7 +151102,7 @@ def _splitLine(line, length): line, "", length, - SysMgr.lineLength - (length+2), + SysMgr.lineLength - (length + 2), startIndent=False, ).lstrip() @@ -151385,9 +151478,7 @@ def _memFactorPG(stat): value["user"] = "-" # check user # - if userFilter and not isValidStr( - value["user"], userFilter - ): + if userFilter and not isValidStr(value["user"], userFilter): continue # add task to fixed target list # @@ -152041,9 +152132,7 @@ def _memFactorPG(stat): if onlyVmflag and mprop != "FLAG": continue - elif memAttr and not isValidStr( - mval, memAttr, inc=True - ): + elif memAttr and not isValidStr(mval, memAttr, inc=True): continue ret = SysMgr.addPrint(mval) @@ -152190,7 +152279,7 @@ def _memFactorPG(stat): groupStr = _splitLine(groupStr, 41) ret = SysMgr.addPrint( "{0:>39} | {1:1}\n".format("GROUP", groupStr), - newline=groupStr.count("\n") + 1 + newline=groupStr.count("\n") + 1, ) if not ret: return @@ -153015,9 +153104,7 @@ def handleEventCmd(self, cmd, source, user): # RESTART # if cmd.startswith("RESTART"): # print message # - SysMgr.printInfo( - "restart %s..." % SysMgr.getTaskStr(SysMgr.pid) - ) + SysMgr.printInfo("restart %s..." % SysMgr.getTaskStr(SysMgr.pid)) # restart process # SysMgr.restart() @@ -155539,8 +155626,7 @@ def getMemStr( sys.exit(0) except: SysMgr.printWarn( - "failed to get memory stats for %s" - % SysMgr.getTaskStr(pid), + "failed to get memory stats for %s" % SysMgr.getTaskStr(pid), reason=True, ) return mstat @@ -155562,9 +155648,7 @@ def getMemStats(tobj, pid, verb=True): elif not SysMgr.isAlive(pid): SysMgr.printErr("%s is terminated" % taskStr) else: - SysMgr.printErr( - "failed to get memory usage of %s" % taskStr - ) + SysMgr.printErr("failed to get memory usage of %s" % taskStr) return None # get proc data #