Chromium Code Reviews| Index: tools/deep_memory_profiler/dmprof |
| diff --git a/tools/deep_memory_profiler/dmprof b/tools/deep_memory_profiler/dmprof |
| index fdf5a7c414ead3853c2f1ba29f649819603bcb06..e6bc93ecb5a03e562f49ec1fdd5e21ce3caad9a7 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, found) = self.skip_lines_while( |
|
M-A Ruel
2012/04/16 12:20:55
since found is not used, you can either:
line_numb
Dai Mikurube (NOT FULLTIME)
2012/04/17 03:26:32
Done.
|
| 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, found) = 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, found) = 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, found) = 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, found) = 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, found) = 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 len(self.log_lines) <= 0: |
|
M-A Ruel
2012/04/16 12:20:55
len() < 0?
Just use:
if not self.log_lines:
Dai Mikurube (NOT FULLTIME)
2012/04/17 03:26:32
Done.
|
| + 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, found) = 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) |
|
M-A Ruel
2012/04/16 12:20:55
The functional part of me dislike the fact that a
Dai Mikurube (NOT FULLTIME)
2012/04/17 03:26:32
I basically agree with you. I'll do that in anoth
|
| + 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) |