diff options
author | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-17 04:44:25 +0000 |
---|---|---|
committer | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-17 04:44:25 +0000 |
commit | 3b3948bfe4aafb7f6982f2b725857eea0db33c06 (patch) | |
tree | 9ec2a5c12f505e42dfba0103918140a1650915b8 /tools/deep_memory_profiler | |
parent | a25ead36e046d33282fc28b6b3fd2b324949d713 (diff) | |
download | chromium_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-x | tools/deep_memory_profiler/dmprof | 66 |
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) |