OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """The deep heap profiler script for Chrome.""" | 6 """The deep heap profiler script for Chrome.""" |
7 | 7 |
8 from datetime import datetime | 8 from datetime import datetime |
9 import json | 9 import json |
10 import os | 10 import os |
(...skipping 27 matching lines...) Expand all Loading... |
38 # DUMP_DEEP_2 DOES distinct mmap regions and malloc chunks. | 38 # DUMP_DEEP_2 DOES distinct mmap regions and malloc chunks. |
39 # Their stacktraces still DO contain mmap* or tc-*. | 39 # Their stacktraces still DO contain mmap* or tc-*. |
40 # They should be processed by POLICY_DEEP_1. | 40 # They should be processed by POLICY_DEEP_1. |
41 DUMP_DEEP_2 = 'DUMP_DEEP_2' | 41 DUMP_DEEP_2 = 'DUMP_DEEP_2' |
42 | 42 |
43 # DUMP_DEEP_3 DOES distinct mmap regions and malloc chunks. | 43 # DUMP_DEEP_3 DOES distinct mmap regions and malloc chunks. |
44 # Their stacktraces DO NOT contain mmap* or tc-*. | 44 # Their stacktraces DO NOT contain mmap* or tc-*. |
45 # They should be processed by POLICY_DEEP_2. | 45 # They should be processed by POLICY_DEEP_2. |
46 DUMP_DEEP_3 = 'DUMP_DEEP_3' | 46 DUMP_DEEP_3 = 'DUMP_DEEP_3' |
47 | 47 |
| 48 # DUMP_DEEP_4 adds some features to DUMP_DEEP_3: |
| 49 # 1. Support comments starting with '#' |
| 50 # 2. Support additional global stats: e.g. nonprofiled-*. |
| 51 DUMP_DEEP_4 = 'DUMP_DEEP_4' |
| 52 |
48 # Heap Profile Policy versions | 53 # Heap Profile Policy versions |
49 | 54 |
50 # POLICY_DEEP_1 DOES NOT include allocation_type columns. | 55 # POLICY_DEEP_1 DOES NOT include allocation_type columns. |
51 # mmap regions are distincted w/ mmap frames in the pattern column. | 56 # mmap regions are distincted w/ mmap frames in the pattern column. |
52 POLICY_DEEP_1 = 'POLICY_DEEP_1' | 57 POLICY_DEEP_1 = 'POLICY_DEEP_1' |
53 | 58 |
54 # POLICY_DEEP_2 DOES include allocation_type columns. | 59 # POLICY_DEEP_2 DOES include allocation_type columns. |
55 # mmap regions are distincted w/ the allocation_type column. | 60 # mmap regions are distincted w/ the allocation_type column. |
56 POLICY_DEEP_2 = 'POLICY_DEEP_2' | 61 POLICY_DEEP_2 = 'POLICY_DEEP_2' |
57 | 62 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 def __init__(self, stacktrace): | 107 def __init__(self, stacktrace): |
103 self.stacktrace = stacktrace | 108 self.stacktrace = stacktrace |
104 self.component = '' | 109 self.component = '' |
105 | 110 |
106 | 111 |
107 class Log(object): | 112 class Log(object): |
108 | 113 |
109 """A class representing one dumped log data.""" | 114 """A class representing one dumped log data.""" |
110 def __init__(self, log_path, buckets): | 115 def __init__(self, log_path, buckets): |
111 self.log_path = log_path | 116 self.log_path = log_path |
112 with open(self.log_path, mode='r') as log_f: | 117 self.log_lines = [ |
113 self.log_lines = log_f.readlines() | 118 l for l in open(self.log_path, 'r') if l and not l.startswith('#')] |
114 self.log_version = '' | 119 self.log_version = '' |
115 sys.stderr.write('parsing a log file:%s\n' % log_path) | 120 sys.stderr.write('parsing a log file:%s\n' % log_path) |
116 self.mmap_stacktrace_lines = [] | 121 self.mmap_stacktrace_lines = [] |
117 self.malloc_stacktrace_lines = [] | 122 self.malloc_stacktrace_lines = [] |
118 self.counters = {} | 123 self.counters = {} |
119 self.log_time = os.stat(self.log_path).st_mtime | 124 self.log_time = os.stat(self.log_path).st_mtime |
120 self.parse_log(buckets) | 125 self.parse_log(buckets) |
121 | 126 |
122 @staticmethod | 127 @staticmethod |
123 def dump_stacktrace_lines(stacktrace_lines, buckets): | 128 def dump_stacktrace_lines(stacktrace_lines, buckets): |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 def skip_lines_while(line_number, max_line_number, skipping_condition): | 280 def skip_lines_while(line_number, max_line_number, skipping_condition): |
276 """Increments line_number until skipping_condition(line_number) is false. | 281 """Increments line_number until skipping_condition(line_number) is false. |
277 """ | 282 """ |
278 while skipping_condition(line_number): | 283 while skipping_condition(line_number): |
279 line_number += 1 | 284 line_number += 1 |
280 if line_number >= max_line_number: | 285 if line_number >= max_line_number: |
281 sys.stderr.write('invalid heap profile dump.') | 286 sys.stderr.write('invalid heap profile dump.') |
282 return line_number | 287 return line_number |
283 return line_number | 288 return line_number |
284 | 289 |
285 def parse_stacktraces_while_valid(self, buckets, log_lines, ln): | 290 def parse_stacktraces_while_valid(self, buckets, log_lines, line_number): |
286 """Parses stacktrace lines while the lines are valid. | 291 """Parses stacktrace lines while the lines are valid. |
287 | 292 |
288 Args: | 293 Args: |
289 buckets: A dict mapping bucket ids and their corresponding Bucket | 294 buckets: A dict mapping bucket ids and their corresponding Bucket |
290 objects. | 295 objects. |
291 log_lines: A list of lines to be parsed. | 296 log_lines: A list of lines to be parsed. |
292 ln: An integer representing the starting line number in log_lines. | 297 line_number: An integer representing the starting line number in |
| 298 log_lines. |
293 | 299 |
294 Returns: | 300 Returns: |
295 A pair of a list of valid lines and an integer representing the last | 301 A pair of a list of valid lines and an integer representing the last |
296 line number in log_lines. | 302 line number in log_lines. |
297 """ | 303 """ |
298 ln = self.skip_lines_while( | 304 line_number = self.skip_lines_while( |
299 ln, len(log_lines), lambda n: not log_lines[n].split()[0].isdigit()) | 305 line_number, len(log_lines), |
300 stacktrace_lines_start = ln | 306 lambda n: not log_lines[n].split()[0].isdigit()) |
301 ln = self.skip_lines_while( | 307 stacktrace_lines_start = line_number |
302 ln, len(log_lines), | 308 line_number = self.skip_lines_while( |
| 309 line_number, len(log_lines), |
303 lambda n: self.check_stacktrace_line(log_lines[n], buckets)) | 310 lambda n: self.check_stacktrace_line(log_lines[n], buckets)) |
304 return (log_lines[stacktrace_lines_start:ln], ln) | 311 return (log_lines[stacktrace_lines_start:line_number], line_number) |
305 | 312 |
306 def parse_stacktraces(self, buckets): | 313 def parse_stacktraces(self, buckets, line_number): |
307 """Parses lines in self.log_lines as stacktrace. | 314 """Parses lines in self.log_lines as stacktrace. |
308 | 315 |
309 Valid stacktrace lines are stored into self.mmap_stacktrace_lines and | 316 Valid stacktrace lines are stored into self.mmap_stacktrace_lines and |
310 self.malloc_stacktrace_lines. | 317 self.malloc_stacktrace_lines. |
311 | 318 |
312 Args: | 319 Args: |
313 buckets: A dict mapping bucket ids and their corresponding Bucket | 320 buckets: A dict mapping bucket ids and their corresponding Bucket |
314 objects. | 321 objects. |
| 322 line_number: An integer representing the starting line number in |
| 323 log_lines. |
| 324 |
| 325 Raises: |
| 326 RuntimeException for invalid dump versions. |
| 327 """ |
| 328 sys.stderr.write(' heap profile dump version: %s\n' % self.log_version) |
| 329 |
| 330 if self.log_version in (DUMP_DEEP_3, DUMP_DEEP_4): |
| 331 (self.mmap_stacktrace_lines, line_number) = ( |
| 332 self.parse_stacktraces_while_valid( |
| 333 buckets, self.log_lines, line_number)) |
| 334 line_number = self.skip_lines_while( |
| 335 line_number, len(self.log_lines), |
| 336 lambda n: self.log_lines[n] != 'MALLOC_STACKTRACES:\n') |
| 337 (self.malloc_stacktrace_lines, line_number) = ( |
| 338 self.parse_stacktraces_while_valid( |
| 339 buckets, self.log_lines, line_number)) |
| 340 |
| 341 elif self.log_version == DUMP_DEEP_2: |
| 342 (self.mmap_stacktrace_lines, line_number) = ( |
| 343 self.parse_stacktraces_while_valid( |
| 344 buckets, self.log_lines, line_number)) |
| 345 line_number = self.skip_lines_while( |
| 346 line_number, len(self.log_lines), |
| 347 lambda n: self.log_lines[n] != 'MALLOC_STACKTRACES:\n') |
| 348 (self.malloc_stacktrace_lines, line_number) = ( |
| 349 self.parse_stacktraces_while_valid( |
| 350 buckets, self.log_lines, line_number)) |
| 351 self.malloc_stacktrace_lines.extend(self.mmap_stacktrace_lines) |
| 352 self.mmap_stacktrace_lines = [] |
| 353 |
| 354 elif self.log_version == DUMP_DEEP_1: |
| 355 (self.malloc_stacktrace_lines, line_number) = ( |
| 356 self.parse_stacktraces_while_valid( |
| 357 buckets, self.log_lines, line_number)) |
| 358 |
| 359 else: |
| 360 raise RuntimeError('invalid heap profile dump version: %s' % ( |
| 361 self.log_version)) |
| 362 |
| 363 def parse_global_stats(self): |
| 364 """Parses lines in self.log_lines as global stats.""" |
| 365 ln = self.skip_lines_while( |
| 366 0, len(self.log_lines), |
| 367 lambda n: self.log_lines[n] != 'GLOBAL_STATS:\n') |
| 368 |
| 369 if self.log_version == DUMP_DEEP_4: |
| 370 global_stat_names = [ |
| 371 'total', 'file-exec', 'file-nonexec', 'anonymous', 'stack', 'other', |
| 372 'nonprofiled-absent', 'nonprofiled-anonymous', |
| 373 'nonprofiled-file-exec', 'nonprofiled-file-nonexec', |
| 374 'nonprofiled-stack', 'nonprofiled-other', |
| 375 'profiled-mmap', 'profiled-malloc'] |
| 376 else: |
| 377 global_stat_names = [ |
| 378 'total', 'file', 'anonymous', 'other', 'mmap', 'tcmalloc'] |
| 379 |
| 380 for prefix in global_stat_names: |
| 381 ln = self.skip_lines_while( |
| 382 ln, len(self.log_lines), |
| 383 lambda n: self.log_lines[n].split()[0] != prefix) |
| 384 words = self.log_lines[ln].split() |
| 385 self.counters[prefix + '_virtual'] = int(words[-2]) |
| 386 self.counters[prefix + '_committed'] = int(words[-1]) |
| 387 |
| 388 def parse_version(self): |
| 389 """Parses a version string in self.log_lines. |
315 | 390 |
316 Returns: | 391 Returns: |
317 A string representing a version of the stacktrace dump. '' for invalid | 392 A pair of (a string representing a version of the stacktrace dump, |
318 dump. | 393 and an integer indicating a line number next to the version string). |
| 394 |
| 395 Raises: |
| 396 RuntimeException for invalid dump versions. |
319 """ | 397 """ |
320 version = '' | 398 version = '' |
321 | 399 |
322 # Skip until an identifiable line. | 400 # Skip until an identifiable line. |
323 headers = ('STACKTRACES:\n', 'MMAP_STACKTRACES:\n', 'heap profile: ') | 401 headers = ('STACKTRACES:\n', 'MMAP_STACKTRACES:\n', 'heap profile: ') |
324 ln = self.skip_lines_while( | 402 ln = self.skip_lines_while( |
325 0, len(self.log_lines), | 403 0, len(self.log_lines), |
326 lambda n: not self.log_lines[n].startswith(headers)) | 404 lambda n: not self.log_lines[n].startswith(headers)) |
327 | 405 |
328 # Identify a version. | 406 # Identify a version. |
329 if self.log_lines[ln].startswith('heap profile: '): | 407 if self.log_lines[ln].startswith('heap profile: '): |
330 version = self.log_lines[ln][13:].strip() | 408 version = self.log_lines[ln][13:].strip() |
331 if version == DUMP_DEEP_2 or version == DUMP_DEEP_3: | 409 if (version == DUMP_DEEP_2 or version == DUMP_DEEP_3 or |
| 410 version == DUMP_DEEP_4): |
332 ln = self.skip_lines_while( | 411 ln = self.skip_lines_while( |
333 ln, len(self.log_lines), | 412 ln, len(self.log_lines), |
334 lambda n: self.log_lines[n] != 'MMAP_STACKTRACES:\n') | 413 lambda n: self.log_lines[n] != 'MMAP_STACKTRACES:\n') |
335 else: | 414 else: |
336 sys.stderr.write(' invalid heap profile dump version:%s\n' % version) | 415 raise RuntimeError('invalid heap profile dump version: %s' % version) |
337 return '' | |
338 elif self.log_lines[ln] == 'STACKTRACES:\n': | 416 elif self.log_lines[ln] == 'STACKTRACES:\n': |
339 version = DUMP_DEEP_1 | 417 version = DUMP_DEEP_1 |
340 elif self.log_lines[ln] == 'MMAP_STACKTRACES:\n': | 418 elif self.log_lines[ln] == 'MMAP_STACKTRACES:\n': |
341 version = DUMP_DEEP_2 | 419 version = DUMP_DEEP_2 |
342 | 420 |
343 if version == DUMP_DEEP_3: | 421 return (version, ln) |
344 sys.stderr.write(' heap profile dump version: %s\n' % version) | |
345 (self.mmap_stacktrace_lines, ln) = self.parse_stacktraces_while_valid( | |
346 buckets, self.log_lines, ln) | |
347 ln = self.skip_lines_while( | |
348 ln, len(self.log_lines), | |
349 lambda n: self.log_lines[n] != 'MALLOC_STACKTRACES:\n') | |
350 (self.malloc_stacktrace_lines, ln) = self.parse_stacktraces_while_valid( | |
351 buckets, self.log_lines, ln) | |
352 return version | |
353 | |
354 elif version == DUMP_DEEP_2: | |
355 sys.stderr.write(' heap profile dump version: %s\n' % version) | |
356 (self.mmap_stacktrace_lines, ln) = self.parse_stacktraces_while_valid( | |
357 buckets, self.log_lines, ln) | |
358 ln = self.skip_lines_while( | |
359 ln, len(self.log_lines), | |
360 lambda n: self.log_lines[n] != 'MALLOC_STACKTRACES:\n') | |
361 (self.malloc_stacktrace_lines, ln) = self.parse_stacktraces_while_valid( | |
362 buckets, self.log_lines, ln) | |
363 self.malloc_stacktrace_lines.extend(self.mmap_stacktrace_lines) | |
364 self.mmap_stacktrace_lines = [] | |
365 return version | |
366 | |
367 elif version == DUMP_DEEP_1: | |
368 sys.stderr.write(' heap profile dump version: %s\n' % version) | |
369 (self.malloc_stacktrace_lines, ln) = self.parse_stacktraces_while_valid( | |
370 buckets, self.log_lines, ln) | |
371 return version | |
372 | |
373 else: | |
374 sys.stderr.write(' invalid heap profile dump version:%s\n' % version) | |
375 return '' | |
376 | |
377 def parse_global_stats(self): | |
378 """Parses lines in self.log_lines as global stats.""" | |
379 ln = self.skip_lines_while( | |
380 0, len(self.log_lines), | |
381 lambda n: self.log_lines[n] != 'GLOBAL_STATS:\n') | |
382 | |
383 for prefix in ['total', 'file', 'anonymous', 'other', 'mmap', 'tcmalloc']: | |
384 ln = self.skip_lines_while( | |
385 ln, len(self.log_lines), | |
386 lambda n: self.log_lines[n].split()[0] != prefix) | |
387 words = self.log_lines[ln].split() | |
388 self.counters[prefix + '_virtual'] = int(words[-2]) | |
389 self.counters[prefix + '_committed'] = int(words[-1]) | |
390 | 422 |
391 def parse_log(self, buckets): | 423 def parse_log(self, buckets): |
| 424 self.log_version, ln = self.parse_version() |
392 self.parse_global_stats() | 425 self.parse_global_stats() |
393 self.log_version = self.parse_stacktraces(buckets) | 426 self.parse_stacktraces(buckets, ln) |
394 | 427 |
395 @staticmethod | 428 @staticmethod |
396 def accumulate_size_for_policy(stacktrace_lines, | 429 def accumulate_size_for_policy(stacktrace_lines, |
397 policy_list, buckets, sizes, mmap): | 430 policy_list, buckets, sizes, mmap): |
398 for l in stacktrace_lines: | 431 for l in stacktrace_lines: |
399 words = l.split() | 432 words = l.split() |
400 bucket = buckets.get(int(words[BUCKET_ID])) | 433 bucket = buckets.get(int(words[BUCKET_ID])) |
401 component_match = get_component(policy_list, bucket, mmap) | 434 component_match = get_component(policy_list, bucket, mmap) |
402 sizes[component_match] += int(words[COMMITTED]) | 435 sizes[component_match] += int(words[COMMITTED]) |
403 | 436 |
(...skipping 23 matching lines...) Expand all Loading... |
427 """ | 460 """ |
428 | 461 |
429 sys.stderr.write('apply policy:%s\n' % (self.log_path)) | 462 sys.stderr.write('apply policy:%s\n' % (self.log_path)) |
430 sizes = dict((c, 0) for c in components) | 463 sizes = dict((c, 0) for c in components) |
431 | 464 |
432 self.accumulate_size_for_policy(self.mmap_stacktrace_lines, | 465 self.accumulate_size_for_policy(self.mmap_stacktrace_lines, |
433 policy_list, buckets, sizes, True) | 466 policy_list, buckets, sizes, True) |
434 self.accumulate_size_for_policy(self.malloc_stacktrace_lines, | 467 self.accumulate_size_for_policy(self.malloc_stacktrace_lines, |
435 policy_list, buckets, sizes, False) | 468 policy_list, buckets, sizes, False) |
436 | 469 |
437 sizes['mmap-no-log'] = self.counters['mmap_committed'] - sizes[ | 470 if self.log_version == DUMP_DEEP_4: |
438 'mmap-total-log'] | 471 mmap_prefix = 'profiled-mmap' |
439 sizes['mmap-total-record'] = self.counters['mmap_committed'] | 472 malloc_prefix = 'profiled-malloc' |
440 sizes['mmap-total-record-vm'] = self.counters['mmap_virtual'] | 473 else: |
| 474 mmap_prefix = 'mmap' |
| 475 malloc_prefix = 'tcmalloc' |
441 | 476 |
442 sizes['tc-no-log'] = self.counters['tcmalloc_committed'] - sizes[ | 477 sizes['mmap-no-log'] = ( |
443 'tc-total-log'] | 478 self.counters['%s_committed' % mmap_prefix] - sizes['mmap-total-log']) |
444 sizes['tc-total-record'] = self.counters['tcmalloc_committed'] | 479 sizes['mmap-total-record'] = self.counters['%s_committed' % mmap_prefix] |
445 sizes['tc-unused'] = sizes['mmap-tcmalloc'] - self.counters[ | 480 sizes['mmap-total-record-vm'] = self.counters['%s_virtual' % mmap_prefix] |
446 'tcmalloc_committed'] | 481 |
| 482 sizes['tc-no-log'] = ( |
| 483 self.counters['%s_committed' % malloc_prefix] - sizes['tc-total-log']) |
| 484 sizes['tc-total-record'] = self.counters['%s_committed' % malloc_prefix] |
| 485 sizes['tc-unused'] = ( |
| 486 sizes['mmap-tcmalloc'] - self.counters['%s_committed' % malloc_prefix]) |
447 sizes['tc-total'] = sizes['mmap-tcmalloc'] | 487 sizes['tc-total'] = sizes['mmap-tcmalloc'] |
448 | 488 |
449 for key, value in { 'total': 'total_committed', | 489 for key, value in { |
450 'filemapped': 'file_committed', | 490 'total': 'total_committed', |
451 'anonymous': 'anonymous_committed', | 491 'filemapped': 'file_committed', |
452 'other': 'other_committed', | 492 'file-exec': 'file-exec_committed', |
453 'total-vm': 'total_virtual', | 493 'file-nonexec': 'file-nonexec_committed', |
454 'filemapped-vm': 'file_virtual', | 494 'anonymous': 'anonymous_committed', |
455 'anonymous-vm': 'anonymous_virtual', | 495 'stack': 'stack_committed', |
456 'other-vm': 'other_virtual' }.items(): | 496 'other': 'other_committed', |
| 497 'nonprofiled-absent': 'nonprofiled-absent_committed', |
| 498 'nonprofiled-anonymous': 'nonprofiled-anonymous_committed', |
| 499 'nonprofiled-file-exec': 'nonprofiled-file-exec_committed', |
| 500 'nonprofiled-file-nonexec': 'nonprofiled-file-nonexec_committed', |
| 501 'nonprofiled-stack': 'nonprofiled-stack_committed', |
| 502 'nonprofiled-other': 'nonprofiled-other_committed', |
| 503 'total-vm': 'total_virtual', |
| 504 'filemapped-vm': 'file_virtual', |
| 505 'anonymous-vm': 'anonymous_virtual', |
| 506 'other-vm': 'other_virtual' }.iteritems(): |
457 if key in sizes: | 507 if key in sizes: |
458 sizes[key] = self.counters[value] | 508 sizes[key] = self.counters[value] |
459 | 509 |
460 if 'unknown' in sizes: | 510 if 'mustbezero' in sizes: |
461 sizes['unknown'] = self.counters['total_committed'] - self.counters[ | 511 removed = ( |
462 'mmap_committed'] | 512 '%s_committed' % mmap_prefix, |
| 513 'nonprofiled-absent_committed', |
| 514 'nonprofiled-anonymous_committed', |
| 515 'nonprofiled-file-exec_committed', |
| 516 'nonprofiled-file-nonexec_committed', |
| 517 'nonprofiled-stack_committed', |
| 518 'nonprofiled-other_committed') |
| 519 sizes['mustbezero'] = ( |
| 520 self.counters['total_committed'] - |
| 521 sum(self.counters[i] for i in removed)) |
463 if 'total-exclude-profiler' in sizes: | 522 if 'total-exclude-profiler' in sizes: |
464 sizes['total-exclude-profiler'] = self.counters[ | 523 sizes['total-exclude-profiler'] = ( |
465 'total_committed'] - sizes['mmap-profiler'] | 524 self.counters['total_committed'] - sizes['mmap-profiler']) |
466 if 'hour' in sizes: | 525 if 'hour' in sizes: |
467 sizes['hour'] = (self.log_time - first_log_time) / 60.0 / 60.0 | 526 sizes['hour'] = (self.log_time - first_log_time) / 60.0 / 60.0 |
468 if 'minute' in sizes: | 527 if 'minute' in sizes: |
469 sizes['minute'] = (self.log_time - first_log_time) / 60.0 | 528 sizes['minute'] = (self.log_time - first_log_time) / 60.0 |
470 if 'second' in sizes: | 529 if 'second' in sizes: |
471 sizes['second'] = self.log_time - first_log_time | 530 sizes['second'] = self.log_time - first_log_time |
472 | 531 |
473 return sizes | 532 return sizes |
474 | 533 |
475 @staticmethod | 534 @staticmethod |
476 def accumulate_size_for_expand(stacktrace_lines, policy_list, buckets, | 535 def accumulate_size_for_expand(stacktrace_lines, policy_list, buckets, |
477 component_name, depth, sizes, mmap): | 536 component_name, depth, sizes, mmap): |
478 for line in stacktrace_lines: | 537 for line in stacktrace_lines: |
479 words = line.split() | 538 words = line.split() |
480 bucket = buckets.get(int(words[BUCKET_ID])) | 539 bucket = buckets.get(int(words[BUCKET_ID])) |
481 component_match = get_component(policy_list, bucket, mmap) | 540 component_match = get_component(policy_list, bucket, mmap) |
482 if component_match == component_name: | 541 if component_match == component_name: |
483 stacktrace_sequence = '' | 542 stacktrace_sequence = '' |
484 for address in bucket.stacktrace[1 : min(len(bucket.stacktrace), | 543 for address in bucket.stacktrace[0 : min(len(bucket.stacktrace), |
485 1 + depth)]: | 544 1 + depth)]: |
486 stacktrace_sequence += address_symbol_dict[address] + ' ' | 545 stacktrace_sequence += address_symbol_dict[address] + ' ' |
487 if not stacktrace_sequence in sizes: | 546 if not stacktrace_sequence in sizes: |
488 sizes[stacktrace_sequence] = 0 | 547 sizes[stacktrace_sequence] = 0 |
489 sizes[stacktrace_sequence] += int(words[COMMITTED]) | 548 sizes[stacktrace_sequence] += int(words[COMMITTED]) |
490 | 549 |
491 def expand(self, policy_list, buckets, component_name, depth): | 550 def expand(self, policy_list, buckets, component_name, depth): |
492 """Prints all stacktraces in a given component of given depth. | 551 """Prints all stacktraces in a given component of given depth. |
493 | 552 |
494 Args: | 553 Args: |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 | 817 |
759 elif action == '--pprof': | 818 elif action == '--pprof': |
760 if len(sys.argv) > 5: | 819 if len(sys.argv) > 5: |
761 logs[0].dump_for_pprof(policy_list, buckets, maps_lines, sys.argv[5]) | 820 logs[0].dump_for_pprof(policy_list, buckets, maps_lines, sys.argv[5]) |
762 else: | 821 else: |
763 logs[0].dump_for_pprof(policy_list, buckets, maps_lines, None) | 822 logs[0].dump_for_pprof(policy_list, buckets, maps_lines, None) |
764 | 823 |
765 | 824 |
766 if __name__ == '__main__': | 825 if __name__ == '__main__': |
767 sys.exit(main()) | 826 sys.exit(main()) |
OLD | NEW |