-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
checkdup: Merge multiple reports for flamegraph
Signed-off-by: iipeace <[email protected]>
- Loading branch information
Showing
1 changed file
with
56 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
__credits__ = "Peace Lee" | ||
__license__ = "GPLv2" | ||
__version__ = "3.9.8" | ||
__revision__ = "240602" | ||
__revision__ = "240603" | ||
__maintainer__ = "Peace Lee" | ||
__email__ = "[email protected]" | ||
__repository__ = "https://github.com/iipeace/guider" | ||
|
@@ -47973,7 +47973,7 @@ def _readFile(fd): | |
return None | ||
|
||
@staticmethod | ||
def writeFile(path, val, errval=True, byte=False): | ||
def writeFile(path, val, errval=True, byte=False, verb=True): | ||
try: | ||
perm = "wb" if byte else "w" | ||
dirpath = os.path.dirname(path) | ||
|
@@ -47992,6 +47992,9 @@ def writeFile(path, val, errval=True, byte=False): | |
except SystemExit: | ||
sys.exit(0) | ||
except: | ||
if not verb: | ||
return False | ||
|
||
SysMgr.printErr( | ||
"failed to write '%s' to '%s'" | ||
% ( | ||
|
@@ -53709,7 +53712,12 @@ def checkCmdMode(): | |
|
||
# CHECKDUP MODE # | ||
elif SysMgr.checkMode("checkdup"): | ||
SysMgr.doCheckDup() | ||
try: | ||
SysMgr.doCheckDup() | ||
except SystemExit: | ||
sys.exit(0) | ||
except: | ||
SysMgr.printErr("failed to check duplication", True) | ||
|
||
# GETPID MODE # | ||
elif SysMgr.checkMode("getpid"): | ||
|
@@ -60878,6 +60886,9 @@ def _isValidPage(pagemap, idx): | |
|
||
# get chunk info from report files # | ||
if SysMgr.inputParam: | ||
gMemTable = {} | ||
titleList = {} | ||
dupCallTable = {} | ||
sizeMB = 1048576 | ||
flist = UtilMgr.cleanItem(SysMgr.inputParam.split(","), False) | ||
flist = UtilMgr.getFileList(flist, exceptDir=True) | ||
|
@@ -60919,6 +60930,7 @@ def _isValidPage(pagemap, idx): | |
# get process info # | ||
info = fd.readline() | ||
pid = info.split("(", 1)[1].split(")", 1)[0] | ||
tgid = SysMgr.getTgid(pid) | ||
|
||
# check process # | ||
procInfo = info[info.find(":") + 2 :].split("]", 1)[0] | ||
|
@@ -61006,6 +61018,9 @@ def _isValidPage(pagemap, idx): | |
":" + mstat if mstat else "", | ||
convNum(nrCallList), | ||
) | ||
if not tgid in titleList: | ||
titleList[tgid] = [] | ||
titleList[tgid].append(title + " @" + fname) | ||
SysMgr.printPipe(title) | ||
|
||
# print menu # | ||
|
@@ -61035,8 +61050,10 @@ def _isValidPage(pagemap, idx): | |
dbgObj.updateProcMap(onlyExec=False, saveAll=True) | ||
|
||
# make global chunk table for dup check # | ||
gMemTable = {} | ||
dupCallTable = {} | ||
if not tgid in gMemTable: | ||
gMemTable[tgid] = {} | ||
if not tgid in dupCallTable: | ||
dupCallTable[tgid] = {} | ||
dupCallList = callList if drawDupFlame else [] | ||
for ci, item in enumerate(dupCallList): | ||
UtilMgr.printProgress(ci, nrCallList) | ||
|
@@ -61079,11 +61096,13 @@ def _isValidPage(pagemap, idx): | |
nextPage = addr + PAGESIZE | ||
end = nextPage - pos if last > nextPage else None | ||
cdata = chunk[start:end] | ||
gMemTable[cdata] = gMemTable.get(cdata, 0) + 1 | ||
gMemTable[tgid][cdata] = ( | ||
gMemTable[tgid].get(cdata, 0) + 1 | ||
) | ||
if drawDupFlame: | ||
# remove uniq chunks # | ||
gMemTable = { | ||
k: v for k, v in gMemTable.items() if v != 1 | ||
gMemTable[tgid] = { | ||
k: v for k, v in gMemTable[tgid].items() if v != 1 | ||
} | ||
|
||
nrPrint = 0 | ||
|
@@ -61153,10 +61172,10 @@ def _isValidPage(pagemap, idx): | |
cdata = chunk[start:end] | ||
|
||
# check dup of call chunks # | ||
if drawDupFlame and cdata in gMemTable: | ||
dupCallTable[sym] = dupCallTable.get( | ||
sym, 0 | ||
) + len(cdata) | ||
if drawDupFlame and cdata in gMemTable[tgid]: | ||
dupCallTable[tgid][sym] = dupCallTable[ | ||
tgid | ||
].get(sym, 0) + len(cdata) | ||
|
||
# save data # | ||
if showHist or mergeCall: | ||
|
@@ -61231,8 +61250,8 @@ def _isValidPage(pagemap, idx): | |
|
||
# destroy debugger object # | ||
dbgObj.detach() | ||
gMemTable.pop(tgid) | ||
del dbgObj | ||
del gMemTable | ||
|
||
if mergedMemTable and SysMgr.outPath: | ||
SysMgr.printInfo( | ||
|
@@ -61282,21 +61301,6 @@ def _isValidPage(pagemap, idx): | |
if mergedMemTable: | ||
UtilMgr.deleteProgress() | ||
|
||
# draw flame graph for dup size # | ||
if drawDupFlame and dupCallTable: | ||
outputPath = UtilMgr.getDrawOutputPath( | ||
UtilMgr.getInputNames(fname)[0], "flamegraph" | ||
) | ||
|
||
Debugger.drawFlame( | ||
callList=dupCallTable, | ||
title=UtilMgr.convHtmlChar( | ||
UtilMgr.removeColor(title).strip(), | ||
skip=["&"], | ||
), | ||
outFile=outputPath, | ||
) | ||
|
||
# sort calls by address # | ||
if not SysMgr.sort: | ||
callList.sort(key=lambda e: e[0]) | ||
|
@@ -61340,6 +61344,23 @@ def _isValidPage(pagemap, idx): | |
SysMgr.printErr("no target process alive") | ||
return | ||
|
||
# draw flame graph for dup size # | ||
for tgid in dupCallTable: | ||
fname = flist[0] if len(flist) == 1 else "merged" | ||
outputPath = UtilMgr.getDrawOutputPath(fname, "flamegraph") | ||
titles = [ | ||
'<tspan x="0" dy="1.2em">%s</tspan>' | ||
% UtilMgr.convHtmlChar( | ||
UtilMgr.removeColor(title).strip(), skip=["&"] | ||
) | ||
for title in titleList[tgid] | ||
] | ||
Debugger.drawFlame( | ||
callList=dupCallTable[tgid], | ||
title="".join(titles), | ||
outFile=outputPath, | ||
) | ||
|
||
elif SysMgr.hasMainArg(): | ||
targetList = SysMgr.getMainArgs(False) | ||
elif SysMgr.filterGroup: | ||
|
@@ -96258,7 +96279,10 @@ def handleUsercall(self, update=True): | |
fname = offset = "??" | ||
|
||
# get backtrace # | ||
backtrace = self.isRealtime and SysMgr.funcDepth | ||
if self.isRealtime and SysMgr.funcDepth > 0: | ||
backtrace = self.getBacktrace(SysMgr.funcDepth) | ||
else: | ||
backtrace = None | ||
|
||
# print unknown call address # | ||
if fname == "??": | ||
|
@@ -129300,9 +129324,7 @@ def getInitTime(fname, verb=True): | |
printer = SysMgr.printErr if verb else lambda *x: None | ||
exit = sys.exit if verb else lambda x: x | ||
|
||
if SysMgr.isRecordMode(): | ||
compressor = None | ||
else: | ||
if not SysMgr.isRecordMode(): | ||
try: | ||
fd = open(fname, "rb") | ||
except SystemExit: | ||
|
@@ -129332,10 +129354,7 @@ def getInitTime(fname, verb=True): | |
|
||
# update fd # | ||
try: | ||
if SysMgr.isRecordMode(): | ||
verb = False | ||
else: | ||
verb = True | ||
verb = not SysMgr.isRecordMode() | ||
|
||
if fd: | ||
if verb: | ||
|
@@ -135838,7 +135857,7 @@ def saveGpuData(self): | |
activeNode = os.path.join( | ||
devPath, "gpu_active_rate_enable" | ||
) | ||
SysMgr.writeFile(activeNode, "1") | ||
SysMgr.writeFile(activeNode, "1", verb=False) | ||
elif not os.path.isdir(devPath): | ||
continue | ||
|
||
|