diff --git a/guider/guider.py b/guider/guider.py index 67ca6012..41b6865c 100755 --- a/guider/guider.py +++ b/guider/guider.py @@ -7,7 +7,7 @@ __credits__ = "Peace Lee" __license__ = "GPLv2" __version__ = "3.9.8" -__revision__ = "241006" +__revision__ = "241008" __maintainer__ = "Peace Lee" __email__ = "iipeace5@gmail.com" __repository__ = "https://github.com/iipeace/guider" @@ -65,7 +65,7 @@ class ConfigMgr(object): """Manager for config""" # logo, made by http://www.figlet.org, consider also jp2a # - logo = """ + logo = r""" _____ _ _ / ____| (_) | | | | __ _ _ _ __| | ___ _ __ @@ -3201,7 +3201,7 @@ class ConfigMgr(object): ), } - """ + r""" update syscalls from https://github.com/strace/src/linux/ARCH/syscallent.h 1. %s/\[.*= //g 2. %s/{.*),\s*"/\'sys_/g @@ -6161,7 +6161,7 @@ def __del__(self): class UtilMgr(object): """Manager for utilities""" - """ + r""" [ TIPS ] - vim replacement - PROBLEM: replace all "type(???) is long" with "isinstance(???, (int, long))" @@ -6911,7 +6911,7 @@ def _check(fd): def sort(l, val=None, reverse=False): convert = lambda text: float(text) if text.isdigit() else text alphanum = lambda key: [ - convert(c) for c in re.split("([-+]?[0-9]+\.?[0-9]*)", key) + convert(c) for c in re.split(r"([-+]?[0-9]+\.?[0-9]*)", key) ] if isinstance(l, list): @@ -7373,7 +7373,7 @@ def _variance(data, ddof=0): @staticmethod def splitString(string): - string = string.replace("\,", "$%") + string = string.replace(r"\,", "$%") clist = string.split(",") @@ -8337,7 +8337,7 @@ def convNum(number, isFloat=False, floatDigit=1): except SystemExit: sys.exit(0) except: - return number + return str(number) @staticmethod def convCpuColor(value, string=None, size=1, align="right"): @@ -8985,7 +8985,7 @@ def writeFlamegraph(path, samples, title, depth=20, infodata=""): """.format( infodata ) - + """ + + r""" function init(evt) { details = document.getElementById("details").firstChild; searchbtn = document.getElementById("search"); @@ -11486,7 +11486,7 @@ class Config(object): def _conv_palette(self, palette): plist = [] for palette_entry in palette: - """ + r""" rgb = [ int(rgb_value) for rgb_value in re.findall("\d+", palette_entry) @@ -26086,7 +26086,7 @@ def printTrace(console=False, targets=None, cb=None, parser=None): if SysMgr.jsonEnable: # pick each key and value set # - addAttrs = re.findall("(\w+)=(.+?(?=\s\w+=|\Z))", d["etc"]) + addAttrs = re.findall(r"(\w+)=(.+?(?=\s\w+=|\Z))", d["etc"]) for name, val in addAttrs: d[name] = val.rstrip() @@ -38150,7 +38150,7 @@ def printHelp(force=False, isExit=True): else: target = "processes" - topExamStr = """ + topExamStr = r""" Examples: - {3:1} {2:1} used CPU resource more than 1% every interval # {0:1} {1:1} @@ -38357,6 +38357,9 @@ def printHelp(force=False, isExit=True): - {3:1} the fixed target {2:1} only to save CPU resource for monitoring # {0:1} {1:1} -g a.out -e x + - {3:1} {2:1} and {5:1} {4:1} with systemd info + # {0:1} {1:1} -o . -q PRINTSYSTEMD + - {3:1} {2:1} and {5:1} {4:1} # {0:1} {1:1} -o . # {0:1} {1:1} -o . -q NOBACKUP @@ -38657,6 +38660,10 @@ def printHelp(force=False, isExit=True): # {0:1} {1:1} {4:1} -q DPI:400 # {0:1} {1:1} {4:1} -q RESOLUTION:"16*8" + - {2:1} for specific files with specific font type + # {0:1} {1:1} {4:1} -q SYSFONT + # {0:1} {1:1} {4:1} -q SYSFONT:path + - {2:1} that haven't been summarized yet for specific files # {0:1} {1:1} {4:1} -q TOPSUM # {0:1} {1:1} {4:1} -q TOPSUM, CLEANCHAR @@ -38790,6 +38797,9 @@ def printHelp(force=False, isExit=True): # {0:1} {1:1} {4:1} -q TARGETFILTER:"*home*" # {0:1} {1:1} {4:1} -q TARGETEXFILTER:"*home*" + - {2:1} after updating xticks based on systemd events + # {0:1} {1:1} {4:1} -q SDXRANGE + - {2:1} with specific systemd events and line breaks grouped for text separated by a specific y-axis region # {0:1} {1:1} {4:1} -q NRVPART:10 @@ -39271,7 +39281,7 @@ def printHelp(force=False, isExit=True): ).rstrip() brkExamStr = ( - """{2:1} + r"""{2:1} Examples: - {3:1} {7:1} # {0:1} {1:1} -g 1234 @@ -39772,7 +39782,7 @@ def _getDesc(s, t=0): """ ) - helpStr += """ + helpStr += r""" Examples: - {2:1} for all threads to guider.dat # {0:1} {1:1} -s . @@ -40138,7 +40148,7 @@ def _getDesc(s, t=0): """ ) - helpStr += """ + helpStr += r""" * uprobe p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a uprobe r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe) @@ -40207,7 +40217,7 @@ def _getDesc(s, t=0): (\*4) "u" means user-space dereference. See :ref:`user_mem_access`. """ - helpStr += """ + helpStr += r""" Examples: - {2:1} of all threads to guider.dat # {0:1} {1:1} -s . @@ -40950,7 +40960,7 @@ def _getDesc(s, t=0): "Monitor resources with threshold on the system" ) - examStr = """ + examStr = r""" Examples: - {2:1} {3:1} # {0:1} {1:1} @@ -41181,7 +41191,7 @@ def _getDesc(s, t=0): t=2, ) - examStr = """ + examStr = r""" Examples: - {2:1} and reset WSS when SIGQUIT(Ctrl+\) arrives # {0:1} {1:1} chrome @@ -42945,6 +42955,12 @@ def _getDesc(s, t=0): # {0:1} {1:1} "./guider_*" -q DEPTHBT:5 # {0:1} {1:1} "./guider_*" -q DEPTHLT:100 + - {2:1} without path + # {0:1} {1:1} "./guider_*" -q ONLYSTACK + + - {2:1} with reversed stack + # {0:1} {1:1} "./guider_*" -q REVERSESTACK + - {2:1} for multiple android tombstones # {0:1} {1:1} "/data/tombstone/*" -q MERGETOMBSTONE -f @@ -43821,7 +43837,7 @@ def _getDesc(s, t=0): ) if ocmd == "printsdinfo": - helpStr += """ + helpStr += r""" - {2:1} only for boot time # {0:1} {1:1} -q ONLYBOOT # {0:1} {1:1} -q ONLYBOOT, SORTBYSTART @@ -44254,7 +44270,7 @@ def _getDesc(s, t=0): cmd, mode ) - helpStr += """ + helpStr += r""" Examples: - {2:1} from a file # {0:1} {1:1} -I {4:1} -g {3:1} @@ -50472,7 +50488,7 @@ def stopHandler(signum=None, frame=None): # update exit status # SysMgr.inExit = True - SysMgr.printStat("start reporting... [ STOP(Ctrl+\) ]") + SysMgr.printStat(r"start reporting... [ STOP(Ctrl+\) ]") # report log events # if any( @@ -71491,30 +71507,30 @@ def _checkSignals(tobj, path, pid, startSig, stopSig): remoteCmd = [] hookCmd = [] hookList = [ - "calloc", - "malloc", - "realloc", - "free", - "operator new(unsigned long)", - "operator new(unsigned long\, std::align_val_t)", - "operator new(unsigned long\, std::align_val_t\, std::nothrow_t const&)", - "operator new(unsigned long\, std::nothrow_t const&)", - "operator new[](unsigned long)", - "operator new[](unsigned long\, std::align_val_t)", - "operator new[](unsigned long\, std::align_val_t\, std::nothrow_t const&)", - "operator new[](unsigned long\, std::nothrow_t const&)", - "operator delete(void*)", - "operator delete(void*\, std::align_val_t)", - "operator delete(void*\, std::align_val_t\, std::nothrow_t const&)", - "operator delete(void*\, std::nothrow_t const&)", - "operator delete(void*\, unsigned long)", - "operator delete(void*\, unsigned long\, std::align_val_t)", - "operator delete[](void*)", - "operator delete[](void*\, std::align_val_t)", - "operator delete[](void*\, std::align_val_t\, std::nothrow_t const&)", - "operator delete[](void*\, std::nothrow_t const&)", - "operator delete[](void*\, unsigned long)", - "operator delete[](void*\, unsigned long\, std::align_val_t)", + r"calloc", + r"malloc", + r"realloc", + r"free", + r"operator new(unsigned long)", + r"operator new(unsigned long\, std::align_val_t)", + r"operator new(unsigned long\, std::align_val_t\, std::nothrow_t const&)", + r"operator new(unsigned long\, std::nothrow_t const&)", + r"operator new[](unsigned long)", + r"operator new[](unsigned long\, std::align_val_t)", + r"operator new[](unsigned long\, std::align_val_t\, std::nothrow_t const&)", + r"operator new[](unsigned long\, std::nothrow_t const&)", + r"operator delete(void*)", + r"operator delete(void*\, std::align_val_t)", + r"operator delete(void*\, std::align_val_t\, std::nothrow_t const&)", + r"operator delete(void*\, std::nothrow_t const&)", + r"operator delete(void*\, unsigned long)", + r"operator delete(void*\, unsigned long\, std::align_val_t)", + r"operator delete[](void*)", + r"operator delete[](void*\, std::align_val_t)", + r"operator delete[](void*\, std::align_val_t\, std::nothrow_t const&)", + r"operator delete[](void*\, std::nothrow_t const&)", + r"operator delete[](void*\, unsigned long)", + r"operator delete[](void*\, unsigned long\, std::align_val_t)", ] # check PRELOAD result # @@ -87869,7 +87885,8 @@ def _getDefaultTasks(comm, sibling=True): else: res = DbusMgr.printUnitInfo(tid, ret, bus, procStr, True) unitList.setdefault(procStr, {}) - unitList[procStr].update(res) + if res: + unitList[procStr].update(res) # pidlist # elif mode == "getpidlist": @@ -97155,8 +97172,9 @@ def _loadSamples(fname, nrSamples, nrFiles): SysMgr.printWarn( "failed to parse system info", reason=True ) - analInfo = "\nAnalysis > # " + " ".join(sys.argv) + " -" + # split a long line to multiple lines # + analInfo = "\nAnalysis > # " + " ".join(sys.argv) + " -" v = UtilMgr.convLineStr( analInfo, "", @@ -97337,13 +97355,15 @@ def _getObj(): depthLt = UtilMgr.getEnvironNum("DEPTHLT", False, 0, False, True) keepRedundantCnt = "KEEPREDCNT" in SysMgr.environList + reverseStack = "REVERSESTACK" in SysMgr.environList + onlyStack = "ONLYSTACK" in SysMgr.environList # iterate calls # for sample, count in callList.items(): level = 0 pos = tree callsList = sample.split(" <- ") - calls = reversed(callsList) + calls = callsList if reverseStack else reversed(callsList) # apply filter # if callFilter: @@ -97358,12 +97378,16 @@ def _getObj(): # iterate functions # for call in calls: + # remove multiple info # if not keepRedundantCnt: - # remove multiple info # items = call.rsplit("] * ", 1) if len(items) > 1: call = "%s]" % items[0] + # remove path info # + if onlyStack: + call = call.rsplit("[", 1)[0] + # check call filter # if hasCallFilter: func, path = call.rstrip("]").rsplit("[", 1) @@ -98974,7 +98998,7 @@ def printContext( if rvalue: try: rvalue = '"%s"' % rvalue.decode("utf-8") - rvalue = re.sub("\W+", "", rvalue) + rvalue = re.sub(r"\W+", "", rvalue) except SystemExit: sys.exit(0) except: @@ -117636,7 +117660,7 @@ def _getFileMenu(printBuf, menuBuf, menuStat, lenStat): diffStr2 = "%6.1f%s" else: newStatStr = "%7s(%2d)(%5s%s/%7.1f%s/%5s%s/%6s%s) |" - diffStr = "{0:>7}{1:0}" + diffStr = "{0:>7}" diffStr2 = "%7.1f%s" jsonData[res] = {} @@ -122066,6 +122090,12 @@ def initDrawEnv(dpi=0, size=None, fontsize=None): "LFONTSIZE", False, 3, False ) + # set system font # + fonttype = SysMgr.environList.get("SYSFONT", ["none"])[0] + if fonttype == "SET": + fonttype = "path" + matplotlib.rcParams["svg.fonttype"] = fonttype + # set variables for stacked plots # if SysMgr.checkMode("drawstack", True): SysMgr.addEnvironVar("STACKEDPLOT") @@ -123828,17 +123858,69 @@ def _drawTargetEvent(graphStats, timeline, ax): return # get values # - minPos = timeline[0] - maxPos = timeline[-1] nrVpart = UtilMgr.getEnvironNum("NRVPART", False, 5, False, True) nrPart = long(len(timeline) / nrVpart) if nrPart == 0: nrPart = 1 ntimeline = [timeline[n] for n in range(0, len(timeline), nrPart)] posList = [[] for _ in range(len(ntimeline))] - ymin, ymax = _getYrange(ax) eventFilter = SysMgr.environList.get("TARGETFILTER", []) eventExFilter = SysMgr.environList.get("TARGETEXFILTER", []) + fitXrange = "SDXRANGE" in SysMgr.environList + + # update timeline # + if fitXrange: + # check xrange # + newRange = {} + for n, v in graphStats.items(): + if not n.endswith("systemdInfo"): + continue + + for dn, dv in v.items(): + for bs in dv.get("systemd", {}).values(): + newRange.setdefault(long(bs) / 1000000.0, None) + + for unit, val in sorted( + dv.items(), + key=lambda k: ( + long(k[1]["Boot"]["activating"]) + if "Boot" in k[1] + else 0 + ), + reverse=True, + ): + try: + if not val["Boot"]["activating"]: + raise Exception() + except SystemExit: + sys.exit(0) + except: + break + + # check filter # + if not unit.endswith(".target"): + continue + elif eventFilter and not UtilMgr.isValidStr( + unit, eventFilter + ): + continue + elif eventExFilter and UtilMgr.isValidStr( + unit, eventExFilter + ): + continue + + # get x pos # + x = long(val["Boot"]["activating"]) / 1000000.0 + newRange.setdefault(x / 1000000.0, None) + + # update timeline and xrange # + timeline = sorted(list(map(float, newRange.keys()))) + xlim(timeline[0], timeline[-1]) + + # get range # + minPos = timeline[0] + maxPos = timeline[-1] + ymin, ymax = _getYrange(ax) # per file # for n, v in graphStats.items(): @@ -142775,9 +142857,9 @@ def readProcMemStats(path, tid, retPss=True, retShr=False): # set re string # if retPss: - restr = "\nPss:\s+" + restr = r"\nPss:\s+" elif retShr: - restr = "\nShared_Clean:\s+|\nShared_Dirty:\s+" + restr = r"\nShared_Clean:\s+|\nShared_Dirty:\s+" else: return 0, 0