2012-09-18 14:08:31 +00:00
|
|
|
#!/usr/bin/env python
|
2014-03-14 21:09:05 +00:00
|
|
|
# Copyright (C) 2012-2014 Bastian Kleineidam
|
2012-09-18 14:08:31 +00:00
|
|
|
#
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
# (at your option) any later version.
|
|
|
|
|
#
|
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
|
#
|
|
|
|
|
# You should have received a copy of the GNU General Public License along
|
|
|
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
|
"""
|
|
|
|
|
Analyze a memory dump by the meliae module.
|
|
|
|
|
"""
|
|
|
|
|
import sys
|
|
|
|
|
import os
|
|
|
|
|
import codecs
|
2020-05-14 19:15:28 +00:00
|
|
|
import html
|
2012-09-18 14:08:31 +00:00
|
|
|
from linkcheck import strformat
|
|
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2020-05-16 19:19:42 +00:00
|
|
|
def main(filename):
|
2012-09-18 14:08:31 +00:00
|
|
|
om = print_memorydump(filename)
|
|
|
|
|
dirname, basename = os.path.split(filename)
|
|
|
|
|
basename = os.path.splitext(basename)[0]
|
|
|
|
|
basedir = os.path.join(dirname, basename)
|
|
|
|
|
if not os.path.isdir(basedir):
|
|
|
|
|
os.mkdir(basedir)
|
|
|
|
|
write_htmlfiles(om, basedir)
|
|
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
def print_memorydump(filename):
|
|
|
|
|
from meliae import loader
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
om = loader.load(filename, collapse=True)
|
|
|
|
|
om.remove_expensive_references()
|
2020-05-26 19:20:57 +00:00
|
|
|
print(om.summarize())
|
2012-09-18 14:08:31 +00:00
|
|
|
return om
|
|
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
def write_htmlfiles(om, basedir):
|
|
|
|
|
om.compute_parents()
|
|
|
|
|
open_files = {}
|
|
|
|
|
for obj in om.objs.itervalues():
|
|
|
|
|
fp = get_file(obj.type_str, open_files, basedir)
|
|
|
|
|
write_html_obj(fp, obj, om.objs)
|
|
|
|
|
close_files(open_files)
|
|
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
def get_file(type_str, open_files, basedir):
|
|
|
|
|
"""Get already opened file, or open and initialize a new one."""
|
|
|
|
|
if type_str not in open_files:
|
2020-05-26 19:20:57 +00:00
|
|
|
filename = type_str + ".html"
|
|
|
|
|
encoding = "utf-8"
|
|
|
|
|
fd = codecs.open(os.path.join(basedir, filename), "w", encoding)
|
2012-09-18 14:08:31 +00:00
|
|
|
open_files[type_str] = fd
|
|
|
|
|
write_html_header(fd, type_str, encoding)
|
2012-10-10 10:26:19 +00:00
|
|
|
return open_files[type_str]
|
2012-09-18 14:08:31 +00:00
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
def close_files(open_files):
|
|
|
|
|
for fp in open_files.values():
|
|
|
|
|
write_html_footer(fp)
|
|
|
|
|
fp.close()
|
|
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2020-04-30 19:11:59 +00:00
|
|
|
HtmlHeader = """
|
2012-09-18 14:08:31 +00:00
|
|
|
<!doctype html>
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="%s">
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
"""
|
|
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
def write_html_header(fp, type_str, encoding):
|
|
|
|
|
fp.write(HtmlHeader % encoding)
|
2020-04-30 19:11:59 +00:00
|
|
|
fp.write("<h1>Type %s</h1>\n" % type_str)
|
2020-05-26 19:20:57 +00:00
|
|
|
fp.write(
|
2020-05-26 19:20:57 +00:00
|
|
|
"<table><tr><th>Address</th><th>Name</th><th>Size</th><th>Parents</th>"
|
|
|
|
|
"<th>References</th></tr>\n"
|
2020-05-26 19:20:57 +00:00
|
|
|
)
|
|
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
|
|
|
|
|
def get_children(obj, objs):
|
|
|
|
|
res = []
|
|
|
|
|
for address in obj.children:
|
|
|
|
|
if address in objs:
|
|
|
|
|
child = objs[address]
|
2020-04-30 19:11:59 +00:00
|
|
|
url = "#%d" % address
|
2012-09-18 14:08:31 +00:00
|
|
|
if child.type_str != obj.type_str:
|
2020-04-30 19:11:59 +00:00
|
|
|
url = child.type_str + ".html" + url
|
|
|
|
|
entry = '<a href="%s">%d</a>' % (url, address)
|
2012-09-18 14:08:31 +00:00
|
|
|
else:
|
2020-04-30 19:11:59 +00:00
|
|
|
entry = "%d" % address
|
2012-09-18 14:08:31 +00:00
|
|
|
res.append(entry)
|
|
|
|
|
return res
|
|
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
def get_parents(obj, objs):
|
|
|
|
|
res = []
|
|
|
|
|
for address in obj.parents:
|
|
|
|
|
if address in objs:
|
|
|
|
|
parent = objs[address]
|
2020-04-30 19:11:59 +00:00
|
|
|
url = "#%d" % address
|
2012-09-18 14:08:31 +00:00
|
|
|
if parent.type_str != obj.type_str:
|
2020-04-30 19:11:59 +00:00
|
|
|
url = parent.type_str + ".html" + url
|
|
|
|
|
entry = '<a href="%s">%d</a>' % (url, address)
|
2012-09-18 14:08:31 +00:00
|
|
|
else:
|
2020-04-30 19:11:59 +00:00
|
|
|
entry = "%d" % address
|
2012-09-18 14:08:31 +00:00
|
|
|
res.append(entry)
|
|
|
|
|
return res
|
|
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
def write_html_obj(fp, obj, objs):
|
|
|
|
|
if obj.value is None:
|
2020-04-30 19:11:59 +00:00
|
|
|
value = "None"
|
2012-09-18 14:08:31 +00:00
|
|
|
else:
|
2020-05-14 19:15:28 +00:00
|
|
|
value = html.escape(str(obj.value))
|
2012-09-18 14:08:31 +00:00
|
|
|
attrs = dict(
|
|
|
|
|
address=obj.address,
|
|
|
|
|
size=strformat.strsize(obj.size),
|
2020-04-30 19:11:59 +00:00
|
|
|
children=",".join(get_children(obj, objs)),
|
|
|
|
|
parents=",".join(get_parents(obj, objs)),
|
2012-09-18 14:08:31 +00:00
|
|
|
value=value,
|
|
|
|
|
)
|
2020-05-26 19:20:57 +00:00
|
|
|
fp.write(
|
2020-05-26 19:20:57 +00:00
|
|
|
"<tr><td>%(address)d</td><td>%(value)s</td><td>%(size)s</td>"
|
|
|
|
|
"<td>%(children)s</td></tr>\n" % attrs
|
2020-05-26 19:20:57 +00:00
|
|
|
)
|
|
|
|
|
|
2012-09-18 14:08:31 +00:00
|
|
|
|
|
|
|
|
def write_html_footer(fp):
|
2020-04-30 19:11:59 +00:00
|
|
|
fp.write("</table></body></html>")
|
2012-09-18 14:08:31 +00:00
|
|
|
|
2020-05-26 19:20:57 +00:00
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2012-09-18 14:08:31 +00:00
|
|
|
filename = sys.argv[1]
|
|
|
|
|
main(filename)
|