-
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.
Signed-off-by: iipeace <[email protected]>
- Loading branch information
Showing
1 changed file
with
103 additions
and
21 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__ = "241029" | ||
__revision__ = "241030" | ||
__maintainer__ = "Peace Lee" | ||
__email__ = "[email protected]" | ||
__repository__ = "https://github.com/iipeace/guider" | ||
|
@@ -30497,6 +30497,16 @@ def execTopCmd(): | |
LogMgr.printTrace(False) | ||
sys.exit(0) | ||
|
||
# memory dump # | ||
elif SysMgr.checkMode("mdtop"): | ||
if not SysMgr.filterGroup: | ||
SysMgr.printErr("no input for target info") | ||
sys.exit(0) | ||
|
||
SysMgr.addEnvironVar("MEMTOP") | ||
SysMgr.doHeapProfRec() | ||
sys.exit(0) | ||
|
||
# binder # | ||
elif SysMgr.checkMode("bdtop"): | ||
SysMgr.addEnvironVar("FLUSH") | ||
|
@@ -38136,6 +38146,7 @@ def getCmdList(): | |
"irqtop": ("IRQ", "Linux"), | ||
"kftop": ("Function", "Linux"), | ||
"ktop": ("Function", "Linux"), | ||
"mdtop": ("MemDump", "Linux"), | ||
"mtop": ("Memory", "Linux"), | ||
"ntop": ("Network", "Linux/MacOS/Windows"), | ||
"ptop": ("PMU", "Linux"), | ||
|
@@ -41114,6 +41125,27 @@ def _getDesc(s, t=0): | |
|
||
helpStr += topCommonStr + examStr | ||
|
||
# memory dump top # | ||
elif SysMgr.checkMode("mdtop"): | ||
helpStr = _getDesc( | ||
"Monitor memory details for a process using dumpsys meminfo", | ||
) | ||
|
||
examStr = """ | ||
Examples: | ||
- {2:1} | ||
# {0:1} {1:1} -g system_server | ||
# {0:1} {1:1} -g com.android.car -q APP | ||
|
||
See the top COMMAND help for more examples. | ||
""".format( | ||
cmd, | ||
mode, | ||
"Monitor memory details for a process using dumpsys meminfo", | ||
) | ||
|
||
helpStr += topSubStr + topCommonStr + examStr | ||
|
||
# binder top # | ||
elif SysMgr.checkMode("bdtop"): | ||
helpStr = _getDesc( | ||
|
@@ -56602,6 +56634,7 @@ def isTopMode(): | |
"irqtop", | ||
"kftop", | ||
"ktop", | ||
"mdtop", | ||
"mtop", | ||
"ntop", | ||
"ptop", | ||
|
@@ -58848,6 +58881,7 @@ def parseMemDump(data): | |
"appSummary": {}, | ||
"objects": {}, | ||
"sql": {}, | ||
"databases": [], | ||
} | ||
|
||
# define regex patterns for each section and their items # | ||
|
@@ -58870,6 +58904,9 @@ def parseMemDump(data): | |
"sql": re.compile( | ||
r"(MEMORY_USED|PAGECACHE_OVERFLOW|MALLOC_SIZE):\s+(\d+)" | ||
), | ||
"databases": re.compile( | ||
r"\s*(\d+)\s+(\d+)\s*(\d*)\s*(\d+)/(\d+)/(\d+)\s+(.*)" | ||
), | ||
} | ||
|
||
# parse uptime # | ||
|
@@ -58908,6 +58945,25 @@ def parseMemDump(data): | |
for match in patterns["sql"].finditer(data): | ||
result["sql"][match.group(1)] = int(match.group(2)) | ||
|
||
# parse databases # | ||
for match in patterns["databases"].finditer(data): | ||
pgsz, dbsz, lookaside, cache_1, cache_2, cache_3, dbname = ( | ||
match.groups() | ||
) | ||
result["databases"].append( | ||
{ | ||
"pgsz": int(pgsz), | ||
"dbsz": int(dbsz), | ||
"lookaside": int(lookaside) if lookaside else None, | ||
"cache": { | ||
"cache_1": int(cache_1), | ||
"cache_2": int(cache_2), | ||
"cache_3": int(cache_3), | ||
}, | ||
"dbname": dbname.strip(), | ||
} | ||
) | ||
|
||
return result | ||
|
||
@staticmethod | ||
|
@@ -59968,7 +60024,7 @@ def convHeapProfSample(path, scripts=[], statusDict={}): | |
return scripts | ||
|
||
# define lists # | ||
buf = "" | ||
buf = [] | ||
maps = {} | ||
paths = {} | ||
stacks = {} | ||
|
@@ -59992,6 +60048,7 @@ def convHeapProfSample(path, scripts=[], statusDict={}): | |
totalCnt = 0 | ||
totalSize = 0 | ||
totalLength = len(scripts) if isinstance(scripts, list) else 0 | ||
printPkgList = "PRINTPKGLIST" in SysMgr.environList | ||
|
||
def _printErr(err, reason=False): | ||
SysMgr.printErr(err, reason=reason) | ||
|
@@ -60011,18 +60068,19 @@ def _getLine(scripts): | |
try: | ||
if isinstance(scripts, list): | ||
yield idx, scripts[idx] | ||
idx += 1 | ||
else: | ||
line = scripts.readline() | ||
if line == "": | ||
raise Exception() | ||
elif isinstance(line, bytes): | ||
line = line.decode() | ||
yield idx, line.rstrip("\n") | ||
idx += 1 | ||
except SystemExit: | ||
sys.exit(0) | ||
except: | ||
yield idx, None | ||
idx += 1 | ||
|
||
# parse lines # | ||
for idx, l in _getLine(scripts): | ||
|
@@ -60039,10 +60097,9 @@ def _getLine(scripts): | |
l = l.rstrip() | ||
|
||
if l.startswith("packet {"): | ||
buf = "{" | ||
buf = ["{"] | ||
elif l.startswith("}"): | ||
buf = buf.rstrip(",") + "}" | ||
encoded = buf.replace("\\", "\\\\") | ||
encoded = ("".join(buf).rstrip(",") + "}").replace("\\", "\\\\") | ||
json = UtilMgr.convStr2Dict(encoded, True, True) | ||
|
||
# save data # | ||
|
@@ -60071,12 +60128,13 @@ def _getLine(scripts): | |
packets[s] = v | ||
|
||
# reset buffer # | ||
buf = "" | ||
buf = [] | ||
elif l.endswith("{"): | ||
l = '"%s": {' % l.rsplit("{", 1)[0].strip() | ||
buf += l | ||
buf.append(l) | ||
elif l.endswith("}"): | ||
buf = buf.rstrip(",") + "}," | ||
buf[-1] = buf[-1].rstrip(",") | ||
buf.append("},") | ||
else: | ||
ll = l.split(":", 1) | ||
if len(ll) == 1: | ||
|
@@ -60086,7 +60144,7 @@ def _getLine(scripts): | |
ll[0].strip(), | ||
":".join(ll[1:]).strip('" ').replace('"', "'"), | ||
) | ||
buf += l | ||
buf.append(l) | ||
except SystemExit: | ||
sys.exit(0) | ||
except: | ||
|
@@ -60171,11 +60229,13 @@ def _saveSysInfo(pstr): | |
pkglist.append(pinfo) | ||
|
||
# print package info # | ||
if UtilMgr.isValidStr(pname, targetPkgs): | ||
if not printPkgList and targetPkgs and UtilMgr.isValidStr( | ||
pname, targetPkgs | ||
): | ||
SysMgr.printInfo(pkglist[-1], color=False) | ||
|
||
# print package list # | ||
if pkglist and "PRINTPKGLIST" in SysMgr.environList: | ||
if pkglist and printPkgList: | ||
# print package info # | ||
_printInfo("\n".join(pkglist).rstrip(), color=False) | ||
|
||
|
@@ -60242,7 +60302,7 @@ def _saveSysInfo(pstr): | |
_saveSysInfo(pstr) | ||
|
||
# save callstack info # | ||
for s in samples: | ||
for s in samples if isinstance(samples, list) else []: | ||
cid = s.pop("callstack_id") | ||
if not cid: | ||
continue | ||
|
@@ -60254,14 +60314,27 @@ def _saveSysInfo(pstr): | |
for n, v in s.items(): | ||
stacks[cid][n] = long(stacks[cid].get(n, 0)) + long(v) | ||
|
||
# process internedData for callstacks # | ||
# get internedData for callstacks # | ||
internedData = packets.get("interned_data") | ||
if not internedData: | ||
_printErr("no profiled intenred data") | ||
return -1 | ||
for x in ( | ||
[internedData] if isinstance(internedData, dict) else internedData | ||
): | ||
|
||
# convert internedData # | ||
internedList = [] | ||
if isinstance(internedData, dict): | ||
internedList.append(internedData) | ||
elif isinstance(internedData, list): | ||
for x in internedData: | ||
if isinstance(x, list): | ||
internedList += x | ||
else: | ||
internedList.append(x) | ||
else: | ||
SysMgr.printErr("failed to recognize interned data") | ||
|
||
# process internedData for callstacks # | ||
for x in internedList: | ||
# check type # | ||
if not isinstance(x, dict): | ||
continue | ||
|
@@ -60319,14 +60392,23 @@ def _saveSysInfo(pstr): | |
for cid, stats in stacks.items(): | ||
stack = [] | ||
for fid in reversed(callstacks[cid] if cid in callstacks else []): | ||
# check fid # | ||
if not fid in frames: | ||
SysMgr.printWarn("failed to get frame ID '%s'" % fid, always=True) | ||
stack.append([0, "??", "??"]) | ||
continue | ||
|
||
# make full path # | ||
fpath = mapCache.get(fid) | ||
if not fpath: | ||
mid = frames[fid]["mapping_id"] | ||
midxs = maps[mid]["path_string_ids"] | ||
if not isinstance(midxs, list): | ||
midxs = [midxs] | ||
fpath = "/" + "/".join([paths[m] for m in midxs]) | ||
midxs = maps[mid].get("path_string_ids", -1) | ||
if midxs == -1: | ||
fpath = "??" | ||
else: | ||
if not isinstance(midxs, list): | ||
midxs = [midxs] | ||
fpath = "/" + "/".join([paths[m] for m in midxs]) | ||
mapCache[fid] = fpath | ||
|
||
# make function # | ||
|