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

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: refactored. Created 8 years, 4 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=0, 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 = '(type=%s) ' % typeinfo_symbols[bucket.typeinfo]
592 stacktrace_sequence +='(type.name=%s) ' % bucket.typename
573 for address in bucket.stacktrace[0 : min(len(bucket.stacktrace), 593 for address in bucket.stacktrace[0 : min(len(bucket.stacktrace),
574 1 + depth)]: 594 1 + depth)]:
575 stacktrace_sequence += symbols[address] + ' ' 595 stacktrace_sequence += symbols[address] + ' '
576 if not stacktrace_sequence in sizes: 596 if not stacktrace_sequence in sizes:
577 sizes[stacktrace_sequence] = 0 597 sizes[stacktrace_sequence] = 0
578 sizes[stacktrace_sequence] += int(words[COMMITTED]) 598 sizes[stacktrace_sequence] += int(words[COMMITTED])
579 599
580 def expand(self, rule_list, buckets, component_name, depth, symbols): 600 def expand(
601 self, rule_list, buckets, component_name, depth, symbols,
602 typeinfo_symbols):
581 """Prints all stacktraces in a given component of given depth. 603 """Prints all stacktraces in a given component of given depth.
582 604
583 Args: 605 Args:
584 rule_list: A list of Rule objects. 606 rule_list: A list of Rule objects.
585 buckets: A dict mapping bucket ids to Bucket objects. 607 buckets: A dict mapping bucket ids to Bucket objects.
586 component_name: A name of component for filtering. 608 component_name: A name of component for filtering.
587 depth: An integer representing depth to be printed. 609 depth: An integer representing depth to be printed.
588 symbols: A dict mapping runtime addresses to symbol names. 610 symbols: A dict mapping runtime addresses to symbol names.
589 """ 611 """
590 sizes = {} 612 sizes = {}
591 613
592 self.accumulate_size_for_expand( 614 self.accumulate_size_for_expand(
593 self.stacktrace_lines, rule_list, buckets, component_name, 615 self.stacktrace_lines, rule_list, buckets, component_name,
594 depth, sizes, symbols) 616 depth, sizes, symbols, typeinfo_symbols)
595 617
596 sorted_sizes_list = sorted( 618 sorted_sizes_list = sorted(
597 sizes.iteritems(), key=(lambda x: x[1]), reverse=True) 619 sizes.iteritems(), key=(lambda x: x[1]), reverse=True)
598 total = 0 620 total = 0
599 for size_pair in sorted_sizes_list: 621 for size_pair in sorted_sizes_list:
600 sys.stdout.write('%10d %s\n' % (size_pair[1], size_pair[0])) 622 sys.stdout.write('%10d %s\n' % (size_pair[1], size_pair[0]))
601 total += size_pair[1] 623 total += size_pair[1]
602 sys.stderr.write('total: %d\n' % (total)) 624 sys.stderr.write('total: %d\n' % (total))
603 625
604 626
605 def update_symbols( 627 def update_symbols(
606 symbol_path, delayed_static_symbols, appeared_addresses, symbols): 628 symbol_path, delayed_static_symbols, appeared_addresses,
629 parameter_find_runtime_symbols_list, symbols):
607 """Updates address/symbol mapping on memory and in a .symbol cache file. 630 """Updates address/symbol mapping on memory and in a .symbol cache file.
608 631
609 It reads cached address/symbol mapping from a .symbol file if it exists. 632 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. 633 Then, it resolves unresolved addresses from a Chrome binary with pprof.
611 Both mappings on memory and in a .symbol cache file are updated. 634 Both mappings on memory and in a .symbol cache file are updated.
612 635
613 Symbol files are formatted as follows: 636 Symbol files are formatted as follows:
614 <Address> <Symbol> 637 <Address> <Symbol>
615 <Address> <Symbol> 638 <Address> <Symbol>
616 <Address> <Symbol> 639 <Address> <Symbol>
617 ... 640 ...
618 641
619 Args: 642 Args:
620 symbol_path: A string representing a path for a .symbol file. 643 symbol_path: A string representing a path for a .symbol file.
621 delayed_static_symbols: A DelayedStaticSymbols object. 644 delayed_static_symbols: A DelayedStaticSymbols object.
622 appeared_addresses: A list of known addresses. 645 appeared_addresses: A list of known addresses.
646 parameter_find_runtime_symbols_list: A function to find symbols.
623 symbols: A dict mapping runtime addresses to symbol names. 647 symbols: A dict mapping runtime addresses to symbol names.
624 """ 648 """
625 with open(symbol_path, mode='a+') as symbol_f: 649 with open(symbol_path, mode='a+') as symbol_f:
626 symbol_lines = symbol_f.readlines() 650 symbol_lines = symbol_f.readlines()
627 if symbol_lines: 651 if symbol_lines:
628 for line in symbol_lines: 652 for line in symbol_lines:
629 items = line.split(None, 1) 653 items = line.split(None, 1)
630 if len(items) == 1: 654 if len(items) == 1:
631 items.append('??') 655 items.append('??')
632 symbols[int(items[0], 16)] = items[1].rstrip() 656 symbols[int(items[0], 16)] = items[1].rstrip()
633 if symbols: 657 if symbols:
634 sys.stderr.write(' Found %d symbols in cache.\n' % len(symbols)) 658 sys.stderr.write(' Found %d symbols in cache.\n' % len(symbols))
635 else: 659 else:
636 sys.stderr.write(' No symbols found in cache.\n') 660 sys.stderr.write(' No symbols found in cache.\n')
637 661
638 unresolved_addresses = sorted( 662 unresolved_addresses = sorted(
639 a for a in appeared_addresses if a not in symbols) 663 a for a in appeared_addresses if a not in symbols)
640 664
641 if not unresolved_addresses: 665 if not unresolved_addresses:
642 sys.stderr.write(' No need to resolve any more addresses.\n') 666 sys.stderr.write(' No need to resolve any more addresses.\n')
643 else: 667 else:
644 sys.stderr.write(' %d addresses unresolved.\n' % 668 sys.stderr.write(' %d addresses unresolved.\n' %
645 len(unresolved_addresses)) 669 len(unresolved_addresses))
646 static_symbols = delayed_static_symbols.get() 670
647 symbol_list = find_runtime_symbols_list( 671 sys.stderr.write(' Loading symbols\n')
648 static_symbols, unresolved_addresses) 672 symbols_in_process = delayed_static_symbols.get()
673 symbol_list = parameter_find_runtime_symbols_list(
674 symbols_in_process, unresolved_addresses)
675 sys.stderr.write(' Loaded\n')
649 676
650 for address, symbol in zip(unresolved_addresses, symbol_list): 677 for address, symbol in zip(unresolved_addresses, symbol_list):
651 if not symbol: 678 if not symbol:
652 symbol = '??' 679 symbol = '??'
653 stripped_symbol = symbol.strip() 680 stripped_symbol = symbol.strip()
654 symbols[address] = stripped_symbol 681 symbols[address] = stripped_symbol
655 symbol_f.write('%x %s\n' % (address, stripped_symbol)) 682 symbol_f.write('%x %s\n' % (address, stripped_symbol))
656 683
657 sys.stderr.write(' All symbols resolved.\n') 684 sys.stderr.write(' All symbols resolved.\n')
658 685
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 Args: 747 Args:
721 policy_path: A path for a policy file. 748 policy_path: A path for a policy file.
722 Returns: 749 Returns:
723 A loaded policy object. 750 A loaded policy object.
724 """ 751 """
725 with open(policy_path, mode='r') as f: 752 with open(policy_path, mode='r') as f:
726 policy = json.load(f) 753 policy = json.load(f)
727 754
728 rules = [] 755 rules = []
729 for rule in policy['rules']: 756 for rule in policy['rules']:
730 rules.append(Rule( 757 if 'typeinfo' in rule:
731 rule['name'], rule['allocator'] == 'mmap', rule['stacktrace'])) 758 rules.append(Rule(
759 rule['name'], rule['allocator'] == 'mmap', rule['stacktrace'],
760 rule['typeinfo']))
761 else:
762 rules.append(Rule(
763 rule['name'], rule['allocator'] == 'mmap', rule['stacktrace']))
732 return Policy(rules, policy['version'], policy['components']) 764 return Policy(rules, policy['version'], policy['components'])
733 765
734 766
735 def find_prefix(path): 767 def find_prefix(path):
736 return re.sub('\.[0-9][0-9][0-9][0-9]\.heap', '', path) 768 return re.sub('\.[0-9][0-9][0-9][0-9]\.heap', '', path)
737 769
738 770
739 def load_buckets(prefix): 771 def load_buckets(prefix):
740 # Reading buckets 772 # Reading buckets
741 sys.stderr.write('Loading bucket files.\n') 773 sys.stderr.write('Loading bucket files.\n')
774 appeared_typeinfo_addresses = set()
742 buckets = {} 775 buckets = {}
743 bucket_count = 0 776 bucket_count = 0
744 n = 0 777 n = 0
745 while True: 778 while True:
746 buckets_path = '%s.%04d.buckets' % (prefix, n) 779 buckets_path = '%s.%04d.buckets' % (prefix, n)
747 if not os.path.exists(buckets_path): 780 if not os.path.exists(buckets_path):
748 if n > 10: 781 if n > 10:
749 break 782 break
750 n += 1 783 n += 1
751 continue 784 continue
752 sys.stderr.write(' %s\n' % buckets_path) 785 sys.stderr.write(' %s\n' % buckets_path)
753 with open(buckets_path, 'r') as buckets_f: 786 with open(buckets_path, 'r') as buckets_f:
754 for line in buckets_f: 787 for line in buckets_f:
755 words = line.split() 788 words = line.split()
756 stacktrace = [int(address, 16) for address in words[2:]] 789 typeinfo = 0
757 buckets[int(words[0])] = Bucket(stacktrace, words[1] == 'mmap') 790 typename = ''
791 stacktrace_begin = 2
792 for index, word in enumerate(words):
793 if index < 2:
794 continue
795 if word[0] == 't':
796 typeinfo = int(word[1:], 16)
797 appeared_typeinfo_addresses.add(typeinfo)
798 elif word[0] == 'n':
799 typename = word[1:]
800 else:
801 stacktrace_begin = index
802 break
803 stacktrace = [int(address, 16) for address in words[stacktrace_begin:]]
804 buckets[int(words[0])] = Bucket(
805 stacktrace, words[1] == 'mmap', typeinfo, typename)
758 n += 1 806 n += 1
759 807
760 return buckets 808 return buckets, appeared_typeinfo_addresses
761 809
762 810
763 def determine_dump_path_list(dump_path, prefix): 811 def determine_dump_path_list(dump_path, prefix):
764 dump_path_list = [dump_path] 812 dump_path_list = [dump_path]
765 813
766 # search for the sequence of files 814 # search for the sequence of files
767 n = int(dump_path[len(dump_path) - 9 : len(dump_path) - 5]) 815 n = int(dump_path[len(dump_path) - 9 : len(dump_path) - 5])
768 n += 1 # skip current file 816 n += 1 # skip current file
769 while True: 817 while True:
770 p = '%s.%04d.heap' % (prefix, n) 818 p = '%s.%04d.heap' % (prefix, n)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 appeared_addresses = set() 853 appeared_addresses = set()
806 dumps = [] 854 dumps = []
807 for path in dump_path_list: 855 for path in dump_path_list:
808 sys.stderr.write(' %s' % path) 856 sys.stderr.write(' %s' % path)
809 dumps.append(load_single_dump(path, buckets, appeared_addresses)) 857 dumps.append(load_single_dump(path, buckets, appeared_addresses))
810 sys.stderr.write('\n') 858 sys.stderr.write('\n')
811 return dumps, appeared_addresses 859 return dumps, appeared_addresses
812 860
813 861
814 def load_and_update_symbol_cache( 862 def load_and_update_symbol_cache(
815 prefix, appeared_addresses, delayed_static_symbols): 863 prefix, appeared_addresses, appeared_typeinfo_addresses,
864 delayed_static_symbols):
816 symbol_path = prefix + '.symbols' 865 symbol_path = prefix + '.symbols'
817 sys.stderr.write('Loading and updating symbol cache: "%s".\n' % symbol_path) 866 sys.stderr.write('Loading and updating symbol cache: "%s".\n' % symbol_path)
818 symbols = {} 867 symbols = {}
819 update_symbols( 868 update_symbols(
820 symbol_path, delayed_static_symbols, appeared_addresses, symbols) 869 symbol_path, delayed_static_symbols, appeared_addresses,
821 return symbols 870 find_runtime_symbols_list, symbols)
871
872 typeinfo_symbol_path = prefix + '.tsymbols'
873 sys.stderr.write('Loading and updating typeinfo symbol cache: "%s".\n' %
874 typeinfo_symbol_path)
875 typeinfo_symbols = {}
876 update_symbols(
877 typeinfo_symbol_path, delayed_static_symbols, appeared_typeinfo_addresses,
878 find_runtime_typeinfo_symbols_list, typeinfo_symbols)
879
880 return symbols, typeinfo_symbols
822 881
823 882
824 def load_default_policies(): 883 def load_default_policies():
825 with open(POLICIES_JSON_PATH, mode='r') as policies_f: 884 with open(POLICIES_JSON_PATH, mode='r') as policies_f:
826 default_policies = json.load(policies_f) 885 default_policies = json.load(policies_f)
827 return default_policies 886 return default_policies
828 887
829 888
830 def load_policy(policies_dict, policy_label): 889 def load_policy(policies_dict, policy_label):
831 policy_file = policies_dict[policy_label]['file'] 890 policy_file = policies_dict[policy_label]['file']
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 specified_policies[specified_policy] = ( 922 specified_policies[specified_policy] = (
864 default_policies[specified_policy]) 923 default_policies[specified_policy])
865 policies = load_policies_dict(specified_policies) 924 policies = load_policies_dict(specified_policies)
866 else: 925 else:
867 policies = load_policies_dict(default_policies) 926 policies = load_policies_dict(default_policies)
868 return policies 927 return policies
869 928
870 929
871 def load_basic_files_with_multiple_dumps(dump_path, keep): 930 def load_basic_files_with_multiple_dumps(dump_path, keep):
872 prefix = find_prefix(dump_path) 931 prefix = find_prefix(dump_path)
873 buckets = load_buckets(prefix) 932 buckets, appeared_typeinfo_addresses = load_buckets(prefix)
874 dumps, appeared_addresses = load_dumps( 933 dumps, appeared_addresses = load_dumps(
875 determine_dump_path_list(dump_path, prefix), buckets) 934 determine_dump_path_list(dump_path, prefix), buckets)
876 delayed_static_symbols = DelayedStaticSymbols(prefix, keep) 935 delayed_static_symbols = DelayedStaticSymbols(prefix, keep)
877 symbols = load_and_update_symbol_cache( 936 symbols, typeinfo_symbols = load_and_update_symbol_cache(
878 prefix, appeared_addresses, delayed_static_symbols) 937 prefix, appeared_addresses, appeared_typeinfo_addresses,
879 return buckets, dumps, appeared_addresses, delayed_static_symbols, symbols 938 delayed_static_symbols)
939 for bucket in buckets:
940 if buckets[bucket].typeinfo != None:
M-A Ruel 2012/08/19 02:40:00 if buckets[bucket].typeinfo: ?
Dai Mikurube (NOT FULLTIME) 2012/08/20 10:35:27 Actually, buckets[bucket].typeinfo can be 0, but i
M-A Ruel 2012/08/20 18:12:13 Ok
941 buckets[bucket].typeinfo_symbol = typeinfo_symbols[
942 buckets[bucket].typeinfo]
943
944 return (buckets, dumps, appeared_addresses, appeared_typeinfo_addresses,
945 delayed_static_symbols, symbols, typeinfo_symbols)
880 946
881 947
882 def load_basic_files_with_single_dump(dump_path, keep): 948 def load_basic_files_with_single_dump(dump_path, keep):
883 prefix = find_prefix(dump_path) 949 prefix = find_prefix(dump_path)
884 buckets = load_buckets(prefix) 950 buckets, appeared_typeinfo_addresses = load_buckets(prefix)
885 dump, appeared_addresses = load_dump(dump_path, buckets) 951 dump, appeared_addresses = load_dump(dump_path, buckets)
886 delayed_static_symbols = DelayedStaticSymbols(prefix, keep) 952 delayed_static_symbols = DelayedStaticSymbols(prefix, keep)
887 symbols = load_and_update_symbol_cache( 953 symbols, typeinfo_symbols = load_and_update_symbol_cache(
888 prefix, appeared_addresses, delayed_static_symbols) 954 prefix, appeared_addresses, appeared_typeinfo_addresses,
889 return buckets, dump, appeared_addresses, delayed_static_symbols, symbols 955 delayed_static_symbols)
956 for bucket in buckets:
957 if buckets[bucket].typeinfo != None:
958 buckets[bucket].typeinfo_symbol = typeinfo_symbols[
959 buckets[bucket].typeinfo]
960
961 return (buckets, dump, appeared_addresses, appeared_typeinfo_addresses,
962 delayed_static_symbols, symbols, typeinfo_symbols)
890 963
891 964
892 def do_stacktrace(sys_argv): 965 def do_stacktrace(sys_argv):
893 parser = optparse.OptionParser( 966 parser = optparse.OptionParser(
894 'Usage: %prog stacktrace [--keep] <dump>') 967 'Usage: %prog stacktrace [--keep] <dump>')
895 parser.add_option('--keep', dest='keep', action='store_true') 968 parser.add_option('--keep', dest='keep', action='store_true')
896 options, args = parser.parse_args(sys_argv) 969 options, args = parser.parse_args(sys_argv)
897 970
898 if len(args) != 2: 971 if len(args) != 2:
899 parser.error('needs 1 argument.') 972 parser.error('needs 1 argument.')
900 return 1 973 return 1
901 974
902 dump_path = args[1] 975 dump_path = args[1]
903 976
904 buckets, dump, appeared_addresses, delayed_static_symbols, symbols = ( 977 (buckets, dump, appeared_addresses, appeared_typeinfo_addresses,
905 load_basic_files_with_single_dump(dump_path, options.keep)) 978 delayed_static_symbols, symbols, typeinfo_symbols) = (
979 load_basic_files_with_single_dump(dump_path, options.keep))
906 980
907 dump.print_stacktrace(buckets, symbols) 981 dump.print_stacktrace(buckets, symbols)
908 982
909 return 0 983 return 0
910 984
911 985
912 def do_csv(sys_argv): 986 def do_csv(sys_argv):
913 parser = optparse.OptionParser( 987 parser = optparse.OptionParser(
914 'Usage: %prog csv [-p POLICY] [--keep] <first-dump>') 988 'Usage: %prog csv [-p POLICY] [--keep] <first-dump>')
915 parser.add_option('-p', '--policy', type='string', dest='policy', 989 parser.add_option('-p', '--policy', type='string', dest='policy',
916 help='profile with POLICY', metavar='POLICY') 990 help='profile with POLICY', metavar='POLICY')
917 parser.add_option('--keep', dest='keep', action='store_true') 991 parser.add_option('--keep', dest='keep', action='store_true')
918 options, args = parser.parse_args(sys_argv) 992 options, args = parser.parse_args(sys_argv)
919 993
920 if len(args) != 2: 994 if len(args) != 2:
921 parser.error('needs 1 argument.') 995 parser.error('needs 1 argument.')
922 return 1 996 return 1
923 997
924 dump_path = args[1] 998 dump_path = args[1]
925 999
926 buckets, dumps, appeared_addresses, delayed_static_symbols, symbols = ( 1000 (buckets, dumps, appeared_addresses, appeared_typeinfo_addresses,
927 load_basic_files_with_multiple_dumps(dump_path, options.keep)) 1001 delayed_static_symbols, symbols, typeinfo_symbols) = (
1002 load_basic_files_with_multiple_dumps(dump_path, options.keep))
1003
928 policies = load_policies(options.policy) 1004 policies = load_policies(options.policy)
929 1005
930 max_components = 0 1006 max_components = 0
931 for policy in policies: 1007 for policy in policies:
932 max_components = max(max_components, len(policies[policy].components)) 1008 max_components = max(max_components, len(policies[policy].components))
933 1009
934 for policy in sorted(policies): 1010 for policy in sorted(policies):
935 rule_list = policies[policy].rules 1011 rule_list = policies[policy].rules
936 components = policies[policy].components 1012 components = policies[policy].components
937 1013
(...skipping 27 matching lines...) Expand all
965 help='profile with POLICY', metavar='POLICY') 1041 help='profile with POLICY', metavar='POLICY')
966 parser.add_option('--keep', dest='keep', action='store_true') 1042 parser.add_option('--keep', dest='keep', action='store_true')
967 options, args = parser.parse_args(sys_argv) 1043 options, args = parser.parse_args(sys_argv)
968 1044
969 if len(args) != 2: 1045 if len(args) != 2:
970 parser.error('needs 1 argument.') 1046 parser.error('needs 1 argument.')
971 return 1 1047 return 1
972 1048
973 dump_path = args[1] 1049 dump_path = args[1]
974 1050
975 buckets, dumps, appeared_addresses, delayed_static_symbols, symbols = ( 1051 (buckets, dumps, appeared_addresses, appeared_typeinfo_addresses,
976 load_basic_files_with_multiple_dumps(dump_path, options.keep)) 1052 delayed_static_symbols, symbols, typeinfo_symbols) = (
1053 load_basic_files_with_multiple_dumps(dump_path, options.keep))
977 policies = load_policies(options.policy) 1054 policies = load_policies(options.policy)
978 1055
979 json_base = { 1056 json_base = {
980 'version': 'JSON_DEEP_2', 1057 'version': 'JSON_DEEP_2',
981 'policies': {}, 1058 'policies': {},
982 } 1059 }
983 1060
984 for policy in sorted(policies): 1061 for policy in sorted(policies):
985 rule_list = policies[policy].rules 1062 rule_list = policies[policy].rules
986 components = policies[policy].components 1063 components = policies[policy].components
(...skipping 26 matching lines...) Expand all
1013 help='profile with POLICY', metavar='POLICY') 1090 help='profile with POLICY', metavar='POLICY')
1014 parser.add_option('--keep', dest='keep', action='store_true') 1091 parser.add_option('--keep', dest='keep', action='store_true')
1015 options, args = parser.parse_args(sys_argv) 1092 options, args = parser.parse_args(sys_argv)
1016 1093
1017 if len(args) != 2: 1094 if len(args) != 2:
1018 parser.error('needs 1 argument.') 1095 parser.error('needs 1 argument.')
1019 return 1 1096 return 1
1020 1097
1021 dump_path = args[1] 1098 dump_path = args[1]
1022 1099
1023 buckets, dumps, appeared_addresses, delayed_static_symbols, symbols = ( 1100 (buckets, dumps, appeared_addresses, appeared_typeinfo_addresses,
1024 load_basic_files_with_multiple_dumps(dump_path, options.keep)) 1101 delayed_static_symbols, symbols, typeinfo_symbols) = (
1102 load_basic_files_with_multiple_dumps(dump_path, options.keep))
1025 policies = load_policies(options.policy) 1103 policies = load_policies(options.policy)
1026 1104
1027 for policy in sorted(policies): 1105 for policy in sorted(policies):
1028 rule_list = policies[policy].rules 1106 rule_list = policies[policy].rules
1029 components = policies[policy].components 1107 components = policies[policy].components
1030 1108
1031 component_sizes = dumps[0].apply_policy( 1109 component_sizes = dumps[0].apply_policy(
1032 rule_list, buckets, dumps[0].dump_time, components, symbols) 1110 rule_list, buckets, dumps[0].dump_time, components, symbols)
1033 sys.stdout.write('%s:\n' % policy) 1111 sys.stdout.write('%s:\n' % policy)
1034 for c in components: 1112 for c in components:
(...skipping 17 matching lines...) Expand all
1052 1130
1053 if len(args) != 5: 1131 if len(args) != 5:
1054 parser.error('needs 4 arguments.') 1132 parser.error('needs 4 arguments.')
1055 return 1 1133 return 1
1056 1134
1057 dump_path = args[1] 1135 dump_path = args[1]
1058 target_policy = args[2] 1136 target_policy = args[2]
1059 component_name = args[3] 1137 component_name = args[3]
1060 depth = args[4] 1138 depth = args[4]
1061 1139
1062 buckets, dump, appeared_addresses, delayed_static_symbols, symbols = ( 1140 (buckets, dump, appeared_addresses, appeared_typeinfo_addresses,
1063 load_basic_files_with_single_dump(dump_path, options.keep)) 1141 delayed_static_symbols, symbols, typeinfo_symbols) = (
1142 load_basic_files_with_single_dump(dump_path, options.keep))
1064 policies = load_policies(target_policy) 1143 policies = load_policies(target_policy)
1065 1144
1066 rule_list = policies[target_policy].rules 1145 rule_list = policies[target_policy].rules
1067 1146
1068 dump.expand(rule_list, buckets, component_name, int(depth), symbols) 1147 dump.expand(rule_list, buckets, component_name, int(depth), symbols,
1148 typeinfo_symbols)
1069 1149
1070 return 0 1150 return 0
1071 1151
1072 1152
1073 def do_pprof(sys_argv): 1153 def do_pprof(sys_argv):
1074 parser = optparse.OptionParser( 1154 parser = optparse.OptionParser(
1075 'Usage: %prog pprof [-c COMPONENT] [--keep] <dump> <policy>') 1155 'Usage: %prog pprof [-c COMPONENT] [--keep] <dump> <policy>')
1076 parser.add_option('-c', '--component', type='string', dest='component', 1156 parser.add_option('-c', '--component', type='string', dest='component',
1077 help='restrict to COMPONENT', metavar='COMPONENT') 1157 help='restrict to COMPONENT', metavar='COMPONENT')
1078 parser.add_option('--keep', dest='keep', action='store_true') 1158 parser.add_option('--keep', dest='keep', action='store_true')
1079 options, args = parser.parse_args(sys_argv) 1159 options, args = parser.parse_args(sys_argv)
1080 1160
1081 if len(args) != 3: 1161 if len(args) != 3:
1082 parser.error('needs 2 arguments.') 1162 parser.error('needs 2 arguments.')
1083 return 1 1163 return 1
1084 1164
1085 dump_path = args[1] 1165 dump_path = args[1]
1086 target_policy = args[2] 1166 target_policy = args[2]
1087 component = options.component 1167 component = options.component
1088 1168
1089 buckets, dump, appeared_addresses, delayed_static_symbols, symbols = ( 1169 (buckets, dump, appeared_addresses, appeared_typeinfo_addresses,
1090 load_basic_files_with_single_dump(dump_path, options.keep)) 1170 delayed_static_symbols, symbols, typeinfo_symbols) = (
1171 load_basic_files_with_single_dump(dump_path, options.keep))
1091 policies = load_policies(target_policy) 1172 policies = load_policies(target_policy)
1092 1173
1093 rule_list = policies[target_policy].rules 1174 rule_list = policies[target_policy].rules
1094 1175
1095 with open(find_prefix(dump_path) + '.maps', 'r') as maps_f: 1176 with open(find_prefix(dump_path) + '.maps', 'r') as maps_f:
1096 maps_lines = maps_f.readlines() 1177 maps_lines = maps_f.readlines()
1097 dump.print_for_pprof(rule_list, buckets, maps_lines, component, symbols) 1178 dump.print_for_pprof(rule_list, buckets, maps_lines, component, symbols)
1098 1179
1099 return 0 1180 return 0
1100 1181
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 dmprof stacktrace [--keep] <dump> 1220 dmprof stacktrace [--keep] <dump>
1140 """ % (sys.argv[0])) 1221 """ % (sys.argv[0]))
1141 sys.exit(1) 1222 sys.exit(1)
1142 action = sys.argv.pop(1) 1223 action = sys.argv.pop(1)
1143 1224
1144 return COMMANDS[action](sys.argv) 1225 return COMMANDS[action](sys.argv)
1145 1226
1146 1227
1147 if __name__ == '__main__': 1228 if __name__ == '__main__':
1148 sys.exit(main()) 1229 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698