Skip to content

Commit

Permalink
demangle: Add demangle command
Browse files Browse the repository at this point in the history
Signed-off-by: iipeace <[email protected]>
  • Loading branch information
iipeace committed Jul 11, 2024
1 parent b7ffc48 commit b908331
Showing 1 changed file with 108 additions and 40 deletions.
148 changes: 108 additions & 40 deletions guider/guider.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
__credits__ = "Peace Lee"
__license__ = "GPLv2"
__version__ = "3.9.8"
__revision__ = "240710"
__revision__ = "240711"
__maintainer__ = "Peace Lee"
__email__ = "[email protected]"
__repository__ = "https://github.com/iipeace/guider"
Expand Down Expand Up @@ -36770,6 +36770,7 @@ def getCmdList():
"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"),
"exec": ("Command", "Linux/MacOS/Windows"),
Expand Down Expand Up @@ -38502,6 +38503,13 @@ def printHelp(force=False, isExit=True):
cmd, mode
)

defUsage6 = """
Usage:
# {0:1} {1:1} <VALUE> [OPTIONS] [--help]
""".format(
cmd, mode
)

# description formatter #
def _getDesc(s, t=0):
usages = [
Expand All @@ -38511,6 +38519,7 @@ def _getDesc(s, t=0):
defUsage3,
defUsage4,
defUsage5,
defUsage6,
]
return "%s\nDescription:\n %s\n" % (usages[t], s)

Expand Down Expand Up @@ -40300,6 +40309,9 @@ def _getDesc(s, t=0):
- {2:1} of specific processes having cmdline path including specific keywords
# {0:1} {1:1} a.out -q TARGETCMD
# {0:1} {1:1} "*chrome, *test*" -q TARGETCMD

- {2:1} from stdin
# echo a.out | {0:1} {1:1}
""".format(
cmd,
mode,
Expand Down Expand Up @@ -41282,13 +41294,13 @@ def _getDesc(s, t=0):
# {0:1} {1:1} -g a.out -q RMRECOPT:"--no-dump-kernel-symbols", RMREPOPT:"-f"

- {2:1} and report to the specific output file with task filter
# {0:1} {1:1} -g a.out -q TASKFILTER:"*task"
# {0:1} {1:1} -q TASKFILTER:"*task"

- {2:1} and report to per-task output files
# {0:1} {1:1} -g a.out -q EACHFILE
# {0:1} {1:1} -q EACHFILE

- {2:1} and report the flame graph to a specific file
# {0:1} {1:1} -g a.out -q DRAWFLAME
# {0:1} {1:1} -q DRAWFLAME

- Report from perf data
# {0:1} {1:1} -I perf.data
Expand Down Expand Up @@ -43520,6 +43532,33 @@ def _getDesc(s, t=0):
cmd, mode, "Print systemd files"
)

# demangle #
elif SysMgr.checkMode("demangle"):
helpStr = (
_getDesc("Demangle symbols", t=6)
+ """
Options:
-v verbose
-J print in JSON format
-q <NAME{:VALUE}> set environment variables
"""
)

helpStr += """
Examples:
- {2:1}
# {0:1} {1:1} {3:1}
# {0:1} {1:1} "{3:1}|_ZL15__pthread_startPv"

- {2:1} from stdin
# echo {3:1} | {0:1} {1:1}
""".format(
cmd,
mode,
"Demangle symbols",
"_ZN3art6Thread14CreateCallbackEPv",
)

# printinfo #
elif SysMgr.checkMode("printinfo"):
helpStr = (
Expand Down Expand Up @@ -54914,6 +54953,10 @@ def _printJson(path, obj):
elif SysMgr.checkMode("printinfo"):
SysMgr.doPrintInfo()

# DEMANGLE MODE #
elif SysMgr.checkMode("demangle"):
SysMgr.doDemangle()

# SETAFFINITY MODE #
elif SysMgr.checkMode("setafnt"):
SysMgr.doSetAffinity()
Expand Down Expand Up @@ -56428,6 +56471,7 @@ def doSimplePerfRec():
def convSimplePerfSample(path, scripts=[]):
# open file #
try:
realpath = os.path.realpath(path) if path else "INPUT"
compressed = False
if scripts:
fd = None
Expand All @@ -56437,10 +56481,24 @@ def convSimplePerfSample(path, scripts=[]):
compressed = True
else:
fd = open(path)

# get scripts #
try:
if compressed:
scripts = fd.read().decode().split("\n")
else:
scripts = fd.readlines()
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to read samples from '%s'" % realpath, True
)
return
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to '%s'", os.path.realpath(path), True)
SysMgr.printErr("failed to read '%s'" % realpath, True)
return

# init variables #
Expand All @@ -56462,19 +56520,6 @@ def _getSym(call):
symbol = "0x" + symbol.rsplit("[+", 1)[1].rstrip("]")
return symbol

# get scripts #
if not scripts:
try:
if compressed:
scripts = fd.read().decode().split("\n")
else:
scripts = fd.readlines()
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to read samples", True)
return

# get filter variables #
eachFile = "EACHFILE" in SysMgr.environList
onlyUser = "ONLYUSER" in SysMgr.environList
Expand Down Expand Up @@ -56675,7 +56720,14 @@ def _getSym(call):
# print task stats #
taskStatStr = ", ".join(
[
"%s(%s): %s" % (v["comm"], tid, convNum(v["nrSample"]))
"%s(%s): %s"
% (
v["comm"]
if v["comm"] != "unknown"
else SysMgr.getComm(tid),
tid,
convNum(v["nrSample"]),
)
for tid, v in sorted(
taskList.items(),
key=lambda x: x[1]["nrSample"],
Expand All @@ -56701,21 +56753,19 @@ def _getSym(call):

# draw flame graph #
if "DRAWFLAME" in SysMgr.environList:
try:
# sync report file #
SysMgr.printFd.flush()
except SystemExit:
sys.exit(0)
except:
pass
# remove task filter #
SysMgr.filterGroup = []

# sync report file #
SysMgr.closeAllForPrint()

# set output name #
outFile = UtilMgr.getDrawOutputPath(SysMgr.outPath, "flamegraph")

# draw flame graph #
Debugger.drawFlame(
inputFile=SysMgr.outPath,
outFile=UtilMgr.rstrip(outFile, ".gz"),
outFile=outFile,
forceOutFile=True,
)

Expand Down Expand Up @@ -62258,6 +62308,26 @@ def doPrintNs():

sys.exit(0)

@staticmethod
def doDemangle():
# get keyword #
if SysMgr.hasMainArg():
targetList = SysMgr.getMainArgs(False, "|")
elif SysMgr.filterGroup:
targetList = ",".join(SysMgr.filterGroup)
else:
targetList = []

if not targetList:
# check stdin pipe #
buf = sys.stdin.readline()
if buf:
targetList = UtilMgr.cleanItem(buf.split("|"), False)

for symbol in targetList:
symbol = ElfAnalyzer.demangleSymbol(symbol)
SysMgr.printPipe(symbol)

@staticmethod
def doPrintInfo():
SysMgr.printLogo(big=True, onlyFile=True)
Expand All @@ -62283,7 +62353,7 @@ def doPrintInfo():

@staticmethod
def isSilentCmd():
if SysMgr.checkMode("getpid"):
if SysMgr.checkMode(["getpid", "demangle"]):
return True
else:
return False
Expand Down Expand Up @@ -93098,7 +93168,7 @@ def _loadSamples(fname, nrSamples, nrFiles):
sysinfo = SysMgr.sysinfoBuffer.split("\n")
for s in sysinfo:
try:
if not s:
if not s or s in (twoLine):
continue

# add task info #
Expand Down Expand Up @@ -101210,10 +101280,7 @@ def _printSystemStat():
pass

# check mode #
if instance.isRealtime:
mtype = "Top"
else:
mtype = "Trace"
mtype = "Top" if instance.isRealtime else "Trace"
suffix = "\n"

# update suffix of output file name #
Expand All @@ -101230,13 +101297,16 @@ def _printSystemStat():
# print System Info #
_printSystemStat()

SysMgr.printInfo(
"start analyzing %ss of %s(%s)..."
% (ctype, instance.comm, instance.pid)
)

nrTotal = float(len(instance.callList))

convert = UtilMgr.convNum
if instance.pid == 0:
procInfo = "%s samples" % convert(nrTotal)
else:
procInfo = "%s(%s)" % (instance.comm, instance.pid)

SysMgr.printInfo("start analyzing %ss of %s..." % (ctype, procInfo))

# check incomplete break mode #
if not Debugger.envFlags["COMPLETECALL"] and instance.mode == "break":
isIncompleteBreakMode = True
Expand Down Expand Up @@ -101291,7 +101361,6 @@ def _printSystemStat():
UtilMgr.deleteProgress()

# print call table #
convert = UtilMgr.convNum
try:
elapsed = instance.callList[-1][1] - instance.start
except:
Expand All @@ -101315,7 +101384,6 @@ def _printSystemStat():
freqStr = ""

# set task info #
procInfo = "%s(%s)" % (instance.comm, instance.pid)
mprocInfo = "%s(%s)" % (
Debugger.tracerInstance.comm,
Debugger.tracerInstance.pid,
Expand Down

0 comments on commit b908331

Please sign in to comment.