summaryrefslogtreecommitdiffstats
path: root/tools/deep_memory_profiler
diff options
context:
space:
mode:
authordmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 04:44:25 +0000
committerdmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 04:44:25 +0000
commit3b3948bfe4aafb7f6982f2b725857eea0db33c06 (patch)
tree9ec2a5c12f505e42dfba0103918140a1650915b8 /tools/deep_memory_profiler
parenta25ead36e046d33282fc28b6b3fd2b324949d713 (diff)
downloadchromium_src-3b3948bfe4aafb7f6982f2b725857eea0db33c06.zip
chromium_src-3b3948bfe4aafb7f6982f2b725857eea0db33c06.tar.gz
chromium_src-3b3948bfe4aafb7f6982f2b725857eea0db33c06.tar.bz2
Improve parsing error handling in dmprof.
BUG=none TEST=none Review URL: http://codereview.chromium.org/10096009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132541 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/deep_memory_profiler')
-rwxr-xr-xtools/deep_memory_profiler/dmprof66
1 files changed, 44 insertions, 22 deletions
diff --git a/tools/deep_memory_profiler/dmprof b/tools/deep_memory_profiler/dmprof
index fdf5a7c..a2f6919 100755
--- a/tools/deep_memory_profiler/dmprof
+++ b/tools/deep_memory_profiler/dmprof
@@ -66,6 +66,13 @@ appeared_addresses = set()
components = []
+class ParsingException(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+
class Policy(object):
def __init__(self, name, mmap, pattern):
@@ -112,17 +119,16 @@ class Bucket(object):
class Log(object):
"""A class representing one dumped log data."""
- def __init__(self, log_path, buckets):
+ def __init__(self, log_path):
self.log_path = log_path
self.log_lines = [
l for l in open(self.log_path, 'r') if l and not l.startswith('#')]
self.log_version = ''
- sys.stderr.write('parsing a log file:%s\n' % log_path)
+ sys.stderr.write('Loading a dump: %s\n' % log_path)
self.mmap_stacktrace_lines = []
self.malloc_stacktrace_lines = []
self.counters = {}
self.log_time = os.stat(self.log_path).st_mtime
- self.parse_log(buckets)
@staticmethod
def dump_stacktrace_lines(stacktrace_lines, buckets):
@@ -279,13 +285,17 @@ class Log(object):
@staticmethod
def skip_lines_while(line_number, max_line_number, skipping_condition):
"""Increments line_number until skipping_condition(line_number) is false.
+
+ Returns:
+ A pair of an integer indicating a line number after skipped, and a
+ boolean value which is True if found a line which skipping_condition
+ is False for.
"""
while skipping_condition(line_number):
line_number += 1
if line_number >= max_line_number:
- sys.stderr.write('invalid heap profile dump.')
- return line_number
- return line_number
+ return line_number, False
+ return line_number, True
def parse_stacktraces_while_valid(self, buckets, log_lines, line_number):
"""Parses stacktrace lines while the lines are valid.
@@ -301,11 +311,11 @@ class Log(object):
A pair of a list of valid lines and an integer representing the last
line number in log_lines.
"""
- line_number = self.skip_lines_while(
+ (line_number, _) = self.skip_lines_while(
line_number, len(log_lines),
lambda n: not log_lines[n].split()[0].isdigit())
stacktrace_lines_start = line_number
- line_number = self.skip_lines_while(
+ (line_number, _) = self.skip_lines_while(
line_number, len(log_lines),
lambda n: self.check_stacktrace_line(log_lines[n], buckets))
return (log_lines[stacktrace_lines_start:line_number], line_number)
@@ -323,15 +333,15 @@ class Log(object):
log_lines.
Raises:
- RuntimeException for invalid dump versions.
+ ParsingException for invalid dump versions.
"""
- sys.stderr.write(' heap profile dump version: %s\n' % self.log_version)
+ sys.stderr.write(' Version: %s\n' % self.log_version)
if self.log_version in (DUMP_DEEP_3, DUMP_DEEP_4):
(self.mmap_stacktrace_lines, line_number) = (
self.parse_stacktraces_while_valid(
buckets, self.log_lines, line_number))
- line_number = self.skip_lines_while(
+ (line_number, _) = self.skip_lines_while(
line_number, len(self.log_lines),
lambda n: self.log_lines[n] != 'MALLOC_STACKTRACES:\n')
(self.malloc_stacktrace_lines, line_number) = (
@@ -342,7 +352,7 @@ class Log(object):
(self.mmap_stacktrace_lines, line_number) = (
self.parse_stacktraces_while_valid(
buckets, self.log_lines, line_number))
- line_number = self.skip_lines_while(
+ (line_number, _) = self.skip_lines_while(
line_number, len(self.log_lines),
lambda n: self.log_lines[n] != 'MALLOC_STACKTRACES:\n')
(self.malloc_stacktrace_lines, line_number) = (
@@ -357,12 +367,12 @@ class Log(object):
buckets, self.log_lines, line_number))
else:
- raise RuntimeError('invalid heap profile dump version: %s' % (
+ raise ParsingException('invalid heap profile dump version: %s' % (
self.log_version))
def parse_global_stats(self):
"""Parses lines in self.log_lines as global stats."""
- ln = self.skip_lines_while(
+ (ln, _) = self.skip_lines_while(
0, len(self.log_lines),
lambda n: self.log_lines[n] != 'GLOBAL_STATS:\n')
@@ -378,7 +388,7 @@ class Log(object):
'total', 'file', 'anonymous', 'other', 'mmap', 'tcmalloc']
for prefix in global_stat_names:
- ln = self.skip_lines_while(
+ (ln, _) = self.skip_lines_while(
ln, len(self.log_lines),
lambda n: self.log_lines[n].split()[0] != prefix)
words = self.log_lines[ln].split()
@@ -393,26 +403,31 @@ class Log(object):
and an integer indicating a line number next to the version string).
Raises:
- RuntimeException for invalid dump versions.
+ ParsingException for invalid dump versions.
"""
version = ''
# Skip until an identifiable line.
headers = ('STACKTRACES:\n', 'MMAP_STACKTRACES:\n', 'heap profile: ')
- ln = self.skip_lines_while(
+ if not self.log_lines:
+ raise ParsingException('Empty heap dump file.')
+ (ln, found) = self.skip_lines_while(
0, len(self.log_lines),
lambda n: not self.log_lines[n].startswith(headers))
+ if not found:
+ raise ParsingException('Invalid heap dump file (no version header).')
# Identify a version.
if self.log_lines[ln].startswith('heap profile: '):
version = self.log_lines[ln][13:].strip()
if (version == DUMP_DEEP_2 or version == DUMP_DEEP_3 or
version == DUMP_DEEP_4):
- ln = self.skip_lines_while(
+ (ln, _) = self.skip_lines_while(
ln, len(self.log_lines),
lambda n: self.log_lines[n] != 'MMAP_STACKTRACES:\n')
else:
- raise RuntimeError('invalid heap profile dump version: %s' % version)
+ raise ParsingException('invalid heap profile dump version: %s'
+ % version)
elif self.log_lines[ln] == 'STACKTRACES:\n':
version = DUMP_DEEP_1
elif self.log_lines[ln] == 'MMAP_STACKTRACES:\n':
@@ -746,8 +761,6 @@ Examples:
buckets[int(words[0])] = Bucket(words[1:])
n += 1
- sys.stderr.write('the number buckets: %d\n' % (bucket_count))
-
log_path_list = [log_path]
if action in ('--csv', '--json'):
@@ -762,7 +775,16 @@ Examples:
break
n += 1
- logs = [Log(path, buckets) for path in log_path_list]
+ logs = []
+ for path in log_path_list:
+ new_log = Log(path)
+ sys.stderr.write('Parsing a dump: %s\n' % path)
+ try:
+ new_log.parse_log(buckets)
+ except ParsingException:
+ sys.stderr.write(' Ignored an invalid dump: %s\n' % path)
+ else:
+ logs.append(new_log)
sys.stderr.write('getting symbols\n')
update_symbols(symbol_path, maps_lines, chrome_path)