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
parent a25ead36
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment