Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: tools/deep_memory_profiler/dmprof

Issue 10825075: Classify memory usage by allocated type in Deep Memory Profiler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 optparse 10 import optparse
11 import os 11 import os
12 import re 12 import re
13 import shutil 13 import shutil
14 import subprocess 14 import subprocess
15 import sys 15 import sys
16 import tempfile 16 import tempfile
17 17
18 FIND_RUNTIME_SYMBOLS_PATH = os.path.join( 18 FIND_RUNTIME_SYMBOLS_PATH = os.path.join(
19 os.path.dirname(os.path.abspath(__file__)), 19 os.path.dirname(os.path.abspath(__file__)),
20 os.pardir, 20 os.pardir,
21 'find_runtime_symbols') 21 'find_runtime_symbols')
22 sys.path.append(FIND_RUNTIME_SYMBOLS_PATH) 22 sys.path.append(FIND_RUNTIME_SYMBOLS_PATH)
23 23
24 from find_runtime_symbols import find_runtime_symbols_list 24 from find_runtime_symbols import find_runtime_symbols_list
25 from find_runtime_symbols import find_runtime_typeinfo_symbols_list
26 from find_runtime_symbols import RuntimeSymbolsInProcess
25 from prepare_symbol_info import prepare_symbol_info 27 from prepare_symbol_info import prepare_symbol_info
26 from static_symbols import StaticSymbols
27 28
28 BUCKET_ID = 5 29 BUCKET_ID = 5
29 VIRTUAL = 0 30 VIRTUAL = 0
30 COMMITTED = 1 31 COMMITTED = 1
31 ALLOC_COUNT = 2 32 ALLOC_COUNT = 2
32 FREE_COUNT = 3 33 FREE_COUNT = 3
33 NULL_REGEX = re.compile('') 34 NULL_REGEX = re.compile('')
34 35
35 POLICIES_JSON_PATH = os.path.join( 36 POLICIES_JSON_PATH = os.path.join(
36 os.path.dirname(os.path.abspath(__file__)), 37 os.path.dirname(os.path.abspath(__file__)),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 # mmap regions are distincted w/ mmap frames in the pattern column. 75 # mmap regions are distincted w/ mmap frames in the pattern column.
75 POLICY_DEEP_1 = 'POLICY_DEEP_1' 76 POLICY_DEEP_1 = 'POLICY_DEEP_1'
76 77
77 # POLICY_DEEP_2 DOES include allocation_type columns. 78 # POLICY_DEEP_2 DOES include allocation_type columns.
78 # mmap regions are distincted w/ the allocation_type column. 79 # mmap regions are distincted w/ the allocation_type column.
79 POLICY_DEEP_2 = 'POLICY_DEEP_2' 80 POLICY_DEEP_2 = 'POLICY_DEEP_2'
80 81
81 # POLICY_DEEP_3 is in JSON format. 82 # POLICY_DEEP_3 is in JSON format.
82 POLICY_DEEP_3 = 'POLICY_DEEP_3' 83 POLICY_DEEP_3 = 'POLICY_DEEP_3'
83 84
85 # POLICY_DEEP_3 contains typeinfo.
86 POLICY_DEEP_4 = 'POLICY_DEEP_4'
87
84 88
85 class EmptyDumpException(Exception): 89 class EmptyDumpException(Exception):
86 def __init__(self, value): 90 def __init__(self, value):
87 self.value = value 91 self.value = value
88 def __str__(self): 92 def __str__(self):
89 return repr(self.value) 93 return repr(self.value)
90 94
91 95
92 class ParsingException(Exception): 96 class ParsingException(Exception):
93 def __init__(self, value): 97 def __init__(self, value):
(...skipping 18 matching lines...) Expand all
112 116
113 class DelayedStaticSymbols(object): 117 class DelayedStaticSymbols(object):
114 """Represents static symbol information loaded lazily.""" 118 """Represents static symbol information loaded lazily."""
115 119
116 def __init__(self, prefix, keep=False): 120 def __init__(self, prefix, keep=False):
117 self.maps_path = prefix + '.maps' 121 self.maps_path = prefix + '.maps'
118 self.keep = keep 122 self.keep = keep
119 if keep: 123 if keep:
120 self.prepared_data_dir = prefix + '.pre' 124 self.prepared_data_dir = prefix + '.pre'
121 self.loaded_static_symbols = None 125 self.loaded_static_symbols = None
126 self.loaded_symbols_in_process = None
122 127
123 def get(self): 128 def get(self):
124 if not self.loaded_static_symbols: 129 if not self.loaded_symbols_in_process:
125 if not self.keep: 130 if not self.keep:
126 self.prepared_data_dir = tempfile.mkdtemp() 131 self.prepared_data_dir = tempfile.mkdtemp()
127 try: 132 try:
128 prepare_symbol_info(self.maps_path, self.prepared_data_dir) 133 prepare_symbol_info(self.maps_path, self.prepared_data_dir)
129 self.loaded_static_symbols = StaticSymbols.load(self.prepared_data_dir) 134 self.loaded_symbols_in_process = RuntimeSymbolsInProcess.load(
135 self.prepared_data_dir)
130 finally: 136 finally:
131 if not self.keep: 137 if not self.keep:
132 shutil.rmtree(self.prepared_data_dir) 138 shutil.rmtree(self.prepared_data_dir)
133 return self.loaded_static_symbols 139 return self.loaded_symbols_in_process
134 140
135 141
136 class Rule(object): 142 class Rule(object):
137 """Represents one matching rule in a policy file.""" 143 """Represents one matching rule in a policy file."""
138 144
139 def __init__(self, name, mmap, stacktrace_pattern): 145 def __init__(self, name, mmap, stacktrace_pattern, typeinfo_pattern=None):
140 self.name = name 146 self.name = name
141 self.mmap = mmap 147 self.mmap = mmap
142 self.stacktrace_pattern = re.compile(stacktrace_pattern + r'\Z') 148 self.stacktrace_pattern = re.compile(stacktrace_pattern + r'\Z')
149 if typeinfo_pattern:
150 self.typeinfo_pattern = re.compile(typeinfo_pattern + r'\Z')
151 else:
152 self.typeinfo_pattern = None
143 153
144 154
145 class Policy(object): 155 class Policy(object):
146 """Represents a policy, a content of a policy file.""" 156 """Represents a policy, a content of a policy file."""
147 157
148 def __init__(self, rules, version, components): 158 def __init__(self, rules, version, components):
149 self.rules = rules 159 self.rules = rules
150 self.version = version 160 self.version = version
151 self.components = components 161 self.components = components
152 162
(...skipping 11 matching lines...) Expand all
164 174
165 Returns: 175 Returns:
166 A string representing a component name. 176 A string representing a component name.
167 """ 177 """
168 if not bucket: 178 if not bucket:
169 return 'no-bucket' 179 return 'no-bucket'
170 if bucket.component_cache: 180 if bucket.component_cache:
171 return bucket.component_cache 181 return bucket.component_cache
172 182
173 stacktrace = ''.join(symbols[a] + ' ' for a in bucket.stacktrace).strip() 183 stacktrace = ''.join(symbols[a] + ' ' for a in bucket.stacktrace).strip()
184 typeinfo = bucket.typeinfo_symbol
185 if typeinfo.startswith('0x'):
186 typeinfo = bucket.typename
174 187
175 for rule in rule_list: 188 for rule in rule_list:
176 if bucket.mmap == rule.mmap and rule.stacktrace_pattern.match(stacktrace): 189 if (bucket.mmap == rule.mmap and
190 rule.stacktrace_pattern.match(stacktrace) and
191 (not rule.typeinfo_pattern or rule.typeinfo_pattern.match(typeinfo))):
177 bucket.component_cache = rule.name 192 bucket.component_cache = rule.name
178 return rule.name 193 return rule.name
179 194
180 assert False 195 assert False
181 196
182 197
183 class Bucket(object): 198 class Bucket(object):
184 """Represents a bucket, which is a unit of memory classification.""" 199 """Represents a bucket, which is a unit of memory classification."""
185 200
186 def __init__(self, stacktrace, mmap): 201 def __init__(self, stacktrace, mmap, typeinfo, typename):
187 self.stacktrace = stacktrace 202 self.stacktrace = stacktrace
188 self.mmap = mmap 203 self.mmap = mmap
204 self.typeinfo = typeinfo
205 self.typeinfo_symbol = typename
206 self.typename = typename
189 self.component_cache = '' 207 self.component_cache = ''
190 208
191 def clear_component_cache(self): 209 def clear_component_cache(self):
192 self.component_cache = '' 210 self.component_cache = ''
193 211
194 212
195 class Dump(object): 213 class Dump(object):
196 """Represents one heap profile dump.""" 214 """Represents one heap profile dump."""
197 215
198 def __init__(self, dump_path): 216 def __init__(self, dump_path):
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 sizes['hour'] = (self.dump_time - first_dump_time) / 60.0 / 60.0 574 sizes['hour'] = (self.dump_time - first_dump_time) / 60.0 / 60.0
557 if 'minute' in sizes: 575 if 'minute' in sizes:
558 sizes['minute'] = (self.dump_time - first_dump_time) / 60.0 576 sizes['minute'] = (self.dump_time - first_dump_time) / 60.0
559 if 'second' in sizes: 577 if 'second' in sizes:
560 sizes['second'] = self.dump_time - first_dump_time 578 sizes['second'] = self.dump_time - first_dump_time
561 579
562 return sizes 580 return sizes
563 581
564 @staticmethod 582 @staticmethod
565 def accumulate_size_for_expand(stacktrace_lines, rule_list, buckets, 583 def accumulate_size_for_expand(stacktrace_lines, rule_list, buckets,
566 component_name, depth, sizes, symbols): 584 component_name, depth, sizes, symbols,
585 typeinfo_symbols):
567 for line in stacktrace_lines: 586 for line in stacktrace_lines:
568 words = line.split() 587 words = line.split()
569 bucket = buckets.get(int(words[BUCKET_ID])) 588 bucket = buckets.get(int(words[BUCKET_ID]))
570 component_match = get_component(rule_list, bucket, symbols) 589 component_match = get_component(rule_list, bucket, symbols)
571 if component_match == component_name: 590 if component_match == component_name:
572 stacktrace_sequence = '' 591 stacktrace_sequence = ''
592 if bucket.typeinfo:
593 stacktrace_sequence += '(type=%s)' % typeinfo_symbols[bucket.typeinfo]
594 stacktrace_sequence += ' (type.name=%s) ' % bucket.typename
573 for address in bucket.stacktrace[0 : min(len(bucket.stacktrace), 595 for address in bucket.stacktrace[0 : min(len(bucket.stacktrace),
574 1 + depth)]: 596 1 + depth)]:
575 stacktrace_sequence += symbols[address] + ' ' 597 stacktrace_sequence += symbols[address] + ' '
576 if not stacktrace_sequence in sizes: 598 if not stacktrace_sequence in sizes:
577 sizes[stacktrace_sequence] = 0 599 sizes[stacktrace_sequence] = 0
578 sizes[stacktrace_sequence] += int(words[COMMITTED]) 600 sizes[stacktrace_sequence] += int(words[COMMITTED])
579 601
580 def expand(self, rule_list, buckets, component_name, depth, symbols): 602 def expand(
603 self, rule_list, buckets, component_name, depth, symbols,
604 typeinfo_symbols):
581 """Prints all stacktraces in a given component of given depth. 605 """Prints all stacktraces in a given component of given depth.
582 606
583 Args: 607 Args:
584 rule_list: A list of Rule objects. 608 rule_list: A list of Rule objects.
585 buckets: A dict mapping bucket ids to Bucket objects. 609 buckets: A dict mapping bucket ids to Bucket objects.
586 component_name: A name of component for filtering. 610 component_name: A name of component for filtering.
587 depth: An integer representing depth to be printed. 611 depth: An integer representing depth to be printed.
588 symbols: A dict mapping runtime addresses to symbol names. 612 symbols: A dict mapping runtime addresses to symbol names.
589 """ 613 """
590 sizes = {} 614 sizes = {}
591 615
592 self.accumulate_size_for_expand( 616 self.accumulate_size_for_expand(
593 self.stacktrace_lines, rule_list, buckets, component_name, 617 self.stacktrace_lines, rule_list, buckets, component_name,
594 depth, sizes, symbols) 618 depth, sizes, symbols, typeinfo_symbols)
595 619
596 sorted_sizes_list = sorted( 620 sorted_sizes_list = sorted(
597 sizes.iteritems(), key=(lambda x: x[1]), reverse=True) 621 sizes.iteritems(), key=(lambda x: x[1]), reverse=True)
598 total = 0 622 total = 0
599 for size_pair in sorted_sizes_list: 623 for size_pair in sorted_sizes_list:
600 sys.stdout.write('%10d %s\n' % (size_pair[1], size_pair[0])) 624 sys.stdout.write('%10d %s\n' % (size_pair[1], size_pair[0]))
601 total += size_pair[1] 625 total += size_pair[1]
602 sys.stderr.write('total: %d\n' % (total)) 626 sys.stderr.write('total: %d\n' % (total))
603 627
604 628
605 def update_symbols( 629 def update_symbols(
606 symbol_path, delayed_static_symbols, appeared_addresses, symbols): 630 symbol_path, delayed_static_symbols, appeared_addresses,
631 parameter_find_runtime_symbols_list, symbols):
607 """Updates address/symbol mapping on memory and in a .symbol cache file. 632 """Updates address/symbol mapping on memory and in a .symbol cache file.
608 633
609 It reads cached address/symbol mapping from a .symbol file if it exists. 634 It reads cached address/symbol mapping from a .symbol file if it exists.
610 Then, it resolves unresolved addresses from a Chrome binary with pprof. 635 Then, it resolves unresolved addresses from a Chrome binary with pprof.
611 Both mappings on memory and in a .symbol cache file are updated. 636 Both mappings on memory and in a .symbol cache file are updated.
612 637
613 Symbol files are formatted as follows: 638 Symbol files are formatted as follows:
614 <Address> <Symbol> 639 <Address> <Symbol>
615 <Address> <Symbol> 640 <Address> <Symbol>
616 <Address> <Symbol> 641 <Address> <Symbol>
617 ... 642 ...
618 643
619 Args: 644 Args:
620 symbol_path: A string representing a path for a .symbol file. 645 symbol_path: A string representing a path for a .symbol file.
621 delayed_static_symbols: A DelayedStaticSymbols object. 646 delayed_static_symbols: A DelayedStaticSymbols object.
622 appeared_addresses: A list of known addresses. 647 appeared_addresses: A list of known addresses.
648 parameter_find_runtime_symbols_list: A function to find symbols.
623 symbols: A dict mapping runtime addresses to symbol names. 649 symbols: A dict mapping runtime addresses to symbol names.
624 """ 650 """
625 with open(symbol_path, mode='a+') as symbol_f: 651 with open(symbol_path, mode='a+') as symbol_f:
626 symbol_lines = symbol_f.readlines() 652 symbol_lines = symbol_f.readlines()
627 if symbol_lines: 653 if symbol_lines:
628 for line in symbol_lines: 654 for line in symbol_lines:
629 items = line.split(None, 1) 655 items = line.split(None, 1)
630 if len(items) == 1: 656 if len(items) == 1:
631 items.append('??') 657 items.append('??')
632 symbols[int(items[0], 16)] = items[1].rstrip() 658 symbols[int(items[0], 16)] = items[1].rstrip()
633 if symbols: 659 if symbols:
634 sys.stderr.write(' Found %d symbols in cache.\n' % len(symbols)) 660 sys.stderr.write(' Found %d symbols in cache.\n' % len(symbols))
635 else: 661 else:
636 sys.stderr.write(' No symbols found in cache.\n') 662 sys.stderr.write(' No symbols found in cache.\n')
637 663
638 unresolved_addresses = sorted( 664 unresolved_addresses = sorted(
639 a for a in appeared_addresses if a not in symbols) 665 a for a in appeared_addresses if a not in symbols)
640 666
641 if not unresolved_addresses: 667 if not unresolved_addresses:
642 sys.stderr.write(' No need to resolve any more addresses.\n') 668 sys.stderr.write(' No need to resolve any more addresses.\n')
643 else: 669 else:
644 sys.stderr.write(' %d addresses unresolved.\n' % 670 sys.stderr.write(' %d addresses unresolved.\n' %
645 len(unresolved_addresses)) 671 len(unresolved_addresses))
646 static_symbols = delayed_static_symbols.get() 672
647 symbol_list = find_runtime_symbols_list( 673 sys.stderr.write(' Loading symbols\n')
648 static_symbols, unresolved_addresses) 674 symbols_in_process = delayed_static_symbols.get()
675 symbol_list = parameter_find_runtime_symbols_list(
676 symbols_in_process, unresolved_addresses)
677 sys.stderr.write(' Loaded\n')
649 678
650 for address, symbol in zip(unresolved_addresses, symbol_list): 679 for address, symbol in zip(unresolved_addresses, symbol_list):
651 if not symbol: 680 if not symbol:
652 symbol = '??' 681 symbol = '??'
653 stripped_symbol = symbol.strip() 682 stripped_symbol = symbol.strip()
654 symbols[address] = stripped_symbol 683 symbols[address] = stripped_symbol
655 symbol_f.write('%x %s\n' % (address, stripped_symbol)) 684 symbol_f.write('%x %s\n' % (address, stripped_symbol))
656 685
657 sys.stderr.write(' All symbols resolved.\n') 686 sys.stderr.write(' All symbols resolved.\n')
658 687
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 Args: 749 Args:
721 policy_path: A path for a policy file. 750 policy_path: A path for a policy file.
722 Returns: 751 Returns:
723 A loaded policy object. 752 A loaded policy object.
724 """ 753 """
725 with open(policy_path, mode='r') as f: 754 with open(policy_path, mode='r') as f:
726 policy = json.load(f) 755 policy = json.load(f)
727 756
728 rules = [] 757 rules = []
729 for rule in policy['rules']: 758 for rule in policy['rules']:
730 rules.append(Rule( 759 if 'typeinfo' in rule:
731 rule['name'], rule['allocator'] == 'mmap', rule['stacktrace'])) 760 rules.append(Rule(
761 rule['name'], rule['allocator'] == 'mmap', rule['stacktrace'],
762 rule['typeinfo']))
763 else:
764 rules.append(Rule(
765 rule['name'], rule['allocator'] == 'mmap', rule['stacktrace']))
732 return Policy(rules, policy['version'], policy['components']) 766 return Policy(rules, policy['version'], policy['components'])
733 767
734 768
735 def find_prefix(path): 769 def find_prefix(path):
736 return re.sub('\.[0-9][0-9][0-9][0-9]\.heap', '', path) 770 return re.sub('\.[0-9][0-9][0-9][0-9]\.heap', '', path)
737 771
738 772
739 def load_buckets(prefix): 773 def load_buckets(prefix):
740 # Reading buckets 774 # Reading buckets
741 sys.stderr.write('Loading bucket files.\n') 775 sys.stderr.write('Loading bucket files.\n')
776 appeared_typeinfo_addresses = set()
742 buckets = {} 777 buckets = {}
743 bucket_count = 0 778 bucket_count = 0
744 n = 0 779 n = 0
745 while True: 780 while True:
746 buckets_path = '%s.%04d.buckets' % (prefix, n) 781 buckets_path = '%s.%04d.buckets' % (prefix, n)
747 if not os.path.exists(buckets_path): 782 if not os.path.exists(buckets_path):
748 if n > 10: 783 if n > 10:
749 break 784 break
750 n += 1 785 n += 1
751 continue 786 continue
752 sys.stderr.write(' %s\n' % buckets_path) 787 sys.stderr.write(' %s\n' % buckets_path)
753 with open(buckets_path, 'r') as buckets_f: 788 with open(buckets_path, 'r') as buckets_f:
754 for line in buckets_f: 789 for line in buckets_f:
755 words = line.split() 790 words = line.split()
756 stacktrace = [int(address, 16) for address in words[2:]] 791 typeinfo = None
757 buckets[int(words[0])] = Bucket(stacktrace, words[1] == 'mmap') 792 typename = ''
793 stacktrace_begin = 2
794 for index, word in enumerate(words):
795 if index < 2:
796 continue
797 if word[0] == 't':
798 typeinfo = int(word[1:], 16)
799 appeared_typeinfo_addresses.add(typeinfo)
800 elif word[0] == 'n':
801 typename = word[1:]
802 else:
803 stacktrace_begin = index
804 break
805 stacktrace = [int(address, 16) for address in words[stacktrace_begin:]]
806 buckets[int(words[0])] = Bucket(
807 stacktrace, words[1] == 'mmap', typeinfo, typename)
758 n += 1 808 n += 1
759 809
760 return buckets 810 return buckets, appeared_typeinfo_addresses
761 811
762 812
763 def determine_dump_path_list(dump_path, prefix): 813 def determine_dump_path_list(dump_path, prefix):
764 dump_path_list = [dump_path] 814 dump_path_list = [dump_path]
765 815
766 # search for the sequence of files 816 # search for the sequence of files
767 n = int(dump_path[len(dump_path) - 9 : len(dump_path) - 5]) 817 n = int(dump_path[len(dump_path) - 9 : len(dump_path) - 5])
768 n += 1 # skip current file 818 n += 1 # skip current file
769 while True: 819 while True:
770 p = '%s.%04d.heap' % (prefix, n) 820 p = '%s.%04d.heap' % (prefix, n)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 appeared_addresses = set() 855 appeared_addresses = set()
806 dumps = [] 856 dumps = []
807 for path in dump_path_list: 857 for path in dump_path_list:
808 sys.stderr.write(' %s' % path) 858 sys.stderr.write(' %s' % path)
809 dumps.append(load_single_dump(path, buckets, appeared_addresses)) 859 dumps.append(load_single_dump(path, buckets, appeared_addresses))
810 sys.stderr.write('\n') 860 sys.stderr.write('\n')
811 return dumps, appeared_addresses 861 return dumps, appeared_addresses
812 862
813 863
814 def load_and_update_symbol_cache( 864 def load_and_update_symbol_cache(
815 prefix, appeared_addresses, delayed_static_symbols): 865 prefix, appeared_addresses, appeared_typeinfo_addresses,
866 delayed_static_symbols):
816 symbol_path = prefix + '.symbols' 867 symbol_path = prefix + '.symbols'
817 sys.stderr.write('Loading and updating symbol cache: "%s".\n' % symbol_path) 868 sys.stderr.write('Loading and updating symbol cache: "%s".\n' % symbol_path)
818 symbols = {} 869 symbols = {}
819 update_symbols( 870 update_symbols(
820 symbol_path, delayed_static_symbols, appeared_addresses, symbols) 871 symbol_path, delayed_static_symbols, appeared_addresses,
821 return symbols 872 find_runtime_symbols_list, symbols)
873
874 typeinfo_symbol_path = prefix + '.tsymbols'
875 sys.stderr.write('Loading and updating typeinfo symbol cache: "%s".\n' %
876 typeinfo_symbol_path)
877 typeinfo_symbols = {}
878 update_symbols(
879 typeinfo_symbol_path, delayed_static_symbols, appeared_typeinfo_addresses,
880 find_runtime_typeinfo_symbols_list, typeinfo_symbols)
881
882 return symbols, typeinfo_symbols
822 883
823 884
824 def load_default_policies(): 885 def load_default_policies():
825 with open(POLICIES_JSON_PATH, mode='r') as policies_f: 886 with open(POLICIES_JSON_PATH, mode='r') as policies_f:
826 default_policies = json.load(policies_f) 887 default_policies = json.load(policies_f)
827 return default_policies 888 return default_policies
828 889
829 890
830 def load_policy(policies_dict, policy_label): 891 def load_policy(policies_dict, policy_label):
831 policy_file = policies_dict[policy_label]['file'] 892 policy_file = policies_dict[policy_label]['file']
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 specified_policies[specified_policy] = ( 924 specified_policies[specified_policy] = (
864 default_policies[specified_policy]) 925 default_policies[specified_policy])
865 policies = load_policies_dict(specified_policies) 926 policies = load_policies_dict(specified_policies)
866 else: 927 else:
867 policies = load_policies_dict(default_policies) 928 policies = load_policies_dict(default_policies)
868 return policies 929 return policies
869 930
870 931
871 def load_basic_files_with_multiple_dumps(dump_path, keep): 932 def load_basic_files_with_multiple_dumps(dump_path, keep):
872 prefix = find_prefix(dump_path) 933 prefix = find_prefix(dump_path)
873 buckets = load_buckets(prefix) 934 buckets, appeared_typeinfo_addresses = load_buckets(prefix)
874 dumps, appeared_addresses = load_dumps( 935 dumps, appeared_addresses = load_dumps(
875 determine_dump_path_list(dump_path, prefix), buckets) 936 determine_dump_path_list(dump_path, prefix), buckets)
876 delayed_static_symbols = DelayedStaticSymbols(prefix, keep) 937 delayed_static_symbols = DelayedStaticSymbols(prefix, keep)
877 symbols = load_and_update_symbol_cache( 938 symbols, typeinfo_symbols = load_and_update_symbol_cache(
878 prefix, appeared_addresses, delayed_static_symbols) 939 prefix, appeared_addresses, appeared_typeinfo_addresses,
879 return buckets, dumps, appeared_addresses, delayed_static_symbols, symbols 940 delayed_static_symbols)
941 for bucket in buckets:
942 if buckets[bucket].typeinfo != None:
943 buckets[bucket].typeinfo_symbol = typeinfo_symbols[
944 buckets[bucket].typeinfo]
945
946 return (buckets, dumps, appeared_addresses, appeared_typeinfo_addresses,
947 delayed_static_symbols, symbols, typeinfo_symbols)
880 948
881 949
882 def load_basic_files_with_single_dump(dump_path, keep): 950 def load_basic_files_with_single_dump(dump_path, keep):
883 prefix = find_prefix(dump_path) 951 prefix = find_prefix(dump_path)
884 buckets = load_buckets(prefix) 952 buckets, appeared_typeinfo_addresses = load_buckets(prefix)
885 dump, appeared_addresses = load_dump(dump_path, buckets) 953 dump, appeared_addresses = load_dump(dump_path, buckets)
886 delayed_static_symbols = DelayedStaticSymbols(prefix, keep) 954 delayed_static_symbols = DelayedStaticSymbols(prefix, keep)
887 symbols = load_and_update_symbol_cache( 955 symbols, typeinfo_symbols = load_and_update_symbol_cache(
888 prefix, appeared_addresses, delayed_static_symbols) 956 prefix, appeared_addresses, appeared_typeinfo_addresses,
889 return buckets, dump, appeared_addresses, delayed_static_symbols, symbols 957 delayed_static_symbols)
958 for bucket in buckets:
959 if buckets[bucket].typeinfo != None:
960 buckets[bucket].typeinfo_symbol = typeinfo_symbols[
961 buckets[bucket].typeinfo]
962
963 return (buckets, dump, appeared_addresses, appeared_typeinfo_addresses,
964 delayed_static_symbols, symbols, typeinfo_symbols)
890 965
891 966
892 def do_stacktrace(sys_argv): 967 def do_stacktrace(sys_argv):
893 parser = optparse.OptionParser( 968 parser = optparse.OptionParser(
894 'Usage: %prog stacktrace [--keep] <dump>') 969 'Usage: %prog stacktrace [--keep] <dump>')
895 parser.add_option('--keep', dest='keep', action='store_true') 970 parser.add_option('--keep', dest='keep', action='store_true')
896 options, args = parser.parse_args(sys_argv) 971 options, args = parser.parse_args(sys_argv)
897 972
898 if len(args) != 2: 973 if len(args) != 2:
899 parser.error('needs 1 argument.') 974 parser.error('needs 1 argument.')
900 return 1 975 return 1
901 976
902 dump_path = args[1] 977 dump_path = args[1]
903 978
904 buckets, dump, appeared_addresses, delayed_static_symbols, symbols = ( 979 (buckets, dump, appeared_addresses, appeared_typeinfo_addresses,
905 load_basic_files_with_single_dump(dump_path, options.keep)) 980 delayed_static_symbols, symbols, typeinfo_symbols) = (
981 load_basic_files_with_single_dump(dump_path, options.keep))
906 982
907 dump.print_stacktrace(buckets, symbols) 983 dump.print_stacktrace(buckets, symbols)
908 984
909 return 0 985 return 0
910 986
911 987
912 def do_csv(sys_argv): 988 def do_csv(sys_argv):
913 parser = optparse.OptionParser( 989 parser = optparse.OptionParser(
914 'Usage: %prog csv [-p POLICY] [--keep] <first-dump>') 990 'Usage: %prog csv [-p POLICY] [--keep] <first-dump>')
915 parser.add_option('-p', '--policy', type='string', dest='policy', 991 parser.add_option('-p', '--policy', type='string', dest='policy',
916 help='profile with POLICY', metavar='POLICY') 992 help='profile with POLICY', metavar='POLICY')
917 parser.add_option('--keep', dest='keep', action='store_true') 993 parser.add_option('--keep', dest='keep', action='store_true')
918 options, args = parser.parse_args(sys_argv) 994 options, args = parser.parse_args(sys_argv)
919 995
920 if len(args) != 2: 996 if len(args) != 2:
921 parser.error('needs 1 argument.') 997 parser.error('needs 1 argument.')
922 return 1 998 return 1
923 999
924 dump_path = args[1] 1000 dump_path = args[1]
925 1001
926 buckets, dumps, appeared_addresses, delayed_static_symbols, symbols = ( 1002 (buckets, dumps, appeared_addresses, appeared_typeinfo_addresses,
927 load_basic_files_with_multiple_dumps(dump_path, options.keep)) 1003 delayed_static_symbols, symbols, typeinfo_symbols) = (
1004 load_basic_files_with_multiple_dumps(dump_path, options.keep))
1005
928 policies = load_policies(options.policy) 1006 policies = load_policies(options.policy)
929 1007
930 max_components = 0 1008 max_components = 0
931 for policy in policies: 1009 for policy in policies:
932 max_components = max(max_components, len(policies[policy].components)) 1010 max_components = max(max_components, len(policies[policy].components))
933 1011
934 for policy in sorted(policies): 1012 for policy in sorted(policies):
935 rule_list = policies[policy].rules 1013 rule_list = policies[policy].rules
936 components = policies[policy].components 1014 components = policies[policy].components
937 1015
(...skipping 27 matching lines...) Expand all
965 help='profile with POLICY', metavar='POLICY') 1043 help='profile with POLICY', metavar='POLICY')
966 parser.add_option('--keep', dest='keep', action='store_true') 1044 parser.add_option('--keep', dest='keep', action='store_true')
967 options, args = parser.parse_args(sys_argv) 1045 options, args = parser.parse_args(sys_argv)
968 1046
969 if len(args) != 2: 1047 if len(args) != 2:
970 parser.error('needs 1 argument.') 1048 parser.error('needs 1 argument.')
971 return 1 1049 return 1
972 1050
973 dump_path = args[1] 1051 dump_path = args[1]
974 1052
975 buckets, dumps, appeared_addresses, delayed_static_symbols, symbols = ( 1053 (buckets, dumps, appeared_addresses, appeared_typeinfo_addresses,
976 load_basic_files_with_multiple_dumps(dump_path, options.keep)) 1054 delayed_static_symbols, symbols, typeinfo_symbols) = (
1055 load_basic_files_with_multiple_dumps(dump_path, options.keep))
977 policies = load_policies(options.policy) 1056 policies = load_policies(options.policy)
978 1057
979 json_base = { 1058 json_base = {
980 'version': 'JSON_DEEP_2', 1059 'version': 'JSON_DEEP_2',
981 'policies': {}, 1060 'policies': {},
982 } 1061 }
983 1062
984 for policy in sorted(policies): 1063 for policy in sorted(policies):
985 rule_list = policies[policy].rules 1064 rule_list = policies[policy].rules
986 components = policies[policy].components 1065 components = policies[policy].components
(...skipping 26 matching lines...) Expand all
1013 help='profile with POLICY', metavar='POLICY') 1092 help='profile with POLICY', metavar='POLICY')
1014 parser.add_option('--keep', dest='keep', action='store_true') 1093 parser.add_option('--keep', dest='keep', action='store_true')
1015 options, args = parser.parse_args(sys_argv) 1094 options, args = parser.parse_args(sys_argv)
1016 1095
1017 if len(args) != 2: 1096 if len(args) != 2:
1018 parser.error('needs 1 argument.') 1097 parser.error('needs 1 argument.')
1019 return 1 1098 return 1
1020 1099
1021 dump_path = args[1] 1100 dump_path = args[1]
1022 1101
1023 buckets, dumps, appeared_addresses, delayed_static_symbols, symbols = ( 1102 (buckets, dumps, appeared_addresses, appeared_typeinfo_addresses,
1024 load_basic_files_with_multiple_dumps(dump_path, options.keep)) 1103 delayed_static_symbols, symbols, typeinfo_symbols) = (
1104 load_basic_files_with_multiple_dumps(dump_path, options.keep))
1025 policies = load_policies(options.policy) 1105 policies = load_policies(options.policy)
1026 1106
1027 for policy in sorted(policies): 1107 for policy in sorted(policies):
1028 rule_list = policies[policy].rules 1108 rule_list = policies[policy].rules
1029 components = policies[policy].components 1109 components = policies[policy].components
1030 1110
1031 component_sizes = dumps[0].apply_policy( 1111 component_sizes = dumps[0].apply_policy(
1032 rule_list, buckets, dumps[0].dump_time, components, symbols) 1112 rule_list, buckets, dumps[0].dump_time, components, symbols)
1033 sys.stdout.write('%s:\n' % policy) 1113 sys.stdout.write('%s:\n' % policy)
1034 for c in components: 1114 for c in components:
(...skipping 17 matching lines...) Expand all
1052 1132
1053 if len(args) != 5: 1133 if len(args) != 5:
1054 parser.error('needs 4 arguments.') 1134 parser.error('needs 4 arguments.')
1055 return 1 1135 return 1
1056 1136
1057 dump_path = args[1] 1137 dump_path = args[1]
1058 target_policy = args[2] 1138 target_policy = args[2]
1059 component_name = args[3] 1139 component_name = args[3]
1060 depth = args[4] 1140 depth = args[4]
1061 1141
1062 buckets, dump, appeared_addresses, delayed_static_symbols, symbols = ( 1142 (buckets, dump, appeared_addresses, appeared_typeinfo_addresses,
1063 load_basic_files_with_single_dump(dump_path, options.keep)) 1143 delayed_static_symbols, symbols, typeinfo_symbols) = (
1144 load_basic_files_with_single_dump(dump_path, options.keep))
1064 policies = load_policies(target_policy) 1145 policies = load_policies(target_policy)
1065 1146
1066 rule_list = policies[target_policy].rules 1147 rule_list = policies[target_policy].rules
1067 1148
1068 dump.expand(rule_list, buckets, component_name, int(depth), symbols) 1149 dump.expand(rule_list, buckets, component_name, int(depth), symbols,
1150 typeinfo_symbols)
1069 1151
1070 return 0 1152 return 0
1071 1153
1072 1154
1073 def do_pprof(sys_argv): 1155 def do_pprof(sys_argv):
1074 parser = optparse.OptionParser( 1156 parser = optparse.OptionParser(
1075 'Usage: %prog pprof [-c COMPONENT] [--keep] <dump> <policy>') 1157 'Usage: %prog pprof [-c COMPONENT] [--keep] <dump> <policy>')
1076 parser.add_option('-c', '--component', type='string', dest='component', 1158 parser.add_option('-c', '--component', type='string', dest='component',
1077 help='restrict to COMPONENT', metavar='COMPONENT') 1159 help='restrict to COMPONENT', metavar='COMPONENT')
1078 parser.add_option('--keep', dest='keep', action='store_true') 1160 parser.add_option('--keep', dest='keep', action='store_true')
1079 options, args = parser.parse_args(sys_argv) 1161 options, args = parser.parse_args(sys_argv)
1080 1162
1081 if len(args) != 3: 1163 if len(args) != 3:
1082 parser.error('needs 2 arguments.') 1164 parser.error('needs 2 arguments.')
1083 return 1 1165 return 1
1084 1166
1085 dump_path = args[1] 1167 dump_path = args[1]
1086 target_policy = args[2] 1168 target_policy = args[2]
1087 component = options.component 1169 component = options.component
1088 1170
1089 buckets, dump, appeared_addresses, delayed_static_symbols, symbols = ( 1171 (buckets, dump, appeared_addresses, appeared_typeinfo_addresses,
1090 load_basic_files_with_single_dump(dump_path, options.keep)) 1172 delayed_static_symbols, symbols, typeinfo_symbols) = (
1173 load_basic_files_with_single_dump(dump_path, options.keep))
1091 policies = load_policies(target_policy) 1174 policies = load_policies(target_policy)
1092 1175
1093 rule_list = policies[target_policy].rules 1176 rule_list = policies[target_policy].rules
1094 1177
1095 with open(find_prefix(dump_path) + '.maps', 'r') as maps_f: 1178 with open(find_prefix(dump_path) + '.maps', 'r') as maps_f:
1096 maps_lines = maps_f.readlines() 1179 maps_lines = maps_f.readlines()
1097 dump.print_for_pprof(rule_list, buckets, maps_lines, component, symbols) 1180 dump.print_for_pprof(rule_list, buckets, maps_lines, component, symbols)
1098 1181
1099 return 0 1182 return 0
1100 1183
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 dmprof stacktrace [--keep] <dump> 1222 dmprof stacktrace [--keep] <dump>
1140 """ % (sys.argv[0])) 1223 """ % (sys.argv[0]))
1141 sys.exit(1) 1224 sys.exit(1)
1142 action = sys.argv.pop(1) 1225 action = sys.argv.pop(1)
1143 1226
1144 return COMMANDS[action](sys.argv) 1227 return COMMANDS[action](sys.argv)
1145 1228
1146 1229
1147 if __name__ == '__main__': 1230 if __name__ == '__main__':
1148 sys.exit(main()) 1231 sys.exit(main())
OLDNEW
« no previous file with comments | « third_party/tcmalloc/chromium/src/deep-heap-profile.cc ('k') | tools/deep_memory_profiler/policies.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698