def show_results(mallocs): root = tree.TreeNode(TreeKey('All', None)) lost = 0 unfreed = 0 for buf in mallocs: for desc in mallocs[buf]: alloc_type = root.get_or_add(TreeKey(desc.alloc_type, None)) align = alloc_type.get_or_add(TreeKey(desc.align, 'alignment')) alloc_size = align.get_or_add(TreeKey(desc.alloc_len, 'allocated')) req_size = alloc_size.get_or_add(TreeKey(desc.req_len, 'requested')) req_size.key.alloc += 1 if not desc.is_freed: req_size.key.unfreed_count += 1 req_size.key.unfreed_bytes += desc.alloc_len req_size.key.lost_bytes += desc.alloc_len - desc.req_len def propagate(parent, node): for child in node.children: propagate(node, child) if parent: parent.key.alloc += node.key.alloc parent.key.unfreed_count += node.key.unfreed_count parent.key.unfreed_bytes += node.key.unfreed_bytes parent.key.lost_bytes += node.key.lost_bytes propagate(None, root) def formatter(key): return key.key.__str__() tree.print_tree(root, formatter)
def print_profile(samples, symbol_resolver, caller_oriented=False, printer=default_printer, time_range=None, src_addr_formatter=debug.SourceAddress.__str__, node_filter=None, order=None, root_function=None, max_levels=None, grouping=None): groups = {} for sample in samples: if time_range: sample = sample.intersection(time_range) if not sample: continue frames = [symbol_resolver(addr - 1) for addr in sample.backtrace] frames = strip_garbage(frames) if caller_oriented: frames.reverse() if root_function: i = find_frame_index(frames, root_function) if i: frames = frames[i:] else: frames = None if frames: key = grouping.get_group(sample) if grouping else None node = groups.get(key, None) if not node: node = ProfNode('All') groups[key] = node node.hit(sample.resident_time) for src_addr in frames: node = node.get_or_add(src_addr_formatter(src_addr)) node.hit(sample.resident_time) def format_node(node, root): attributes = '' percentage_subject_getter = attrgetter('hit_count') if root.resident_time: attributes += format_time(node.resident_time) + ' ' percentage_subject_getter = attrgetter('resident_time') bracket_attributes = [] if percentage_subject_getter(root): percentage = float(percentage_subject_getter(node)) * 100 / percentage_subject_getter(root) bracket_attributes.append('%.2f%%' % percentage) bracket_attributes.append('#%d' % node.hit_count) label = '\n '.join([node.key] + node.tail) return "%s(%s) %s" % (attributes, ', '.join(bracket_attributes), label) if not order: order = lambda node: (-node.resident_time, -node.hit_count) for group, tree_root in sorted(groups.iteritems(), key=lambda (thread, node): order(node)): collapse_similar(tree_root) if max_levels: strip_level(tree_root, max_levels) if grouping: printer('\n=== ' + grouping.format(group) + ' ===\n\n') tree.print_tree(tree_root, formatter=lambda node: format_node(node, tree_root), order_by=order, printer=printer, node_filter=lambda node: node_filter(node, tree_root))
def print_profile(samples, symbol_resolver, caller_oriented=False, merge_threads=True, printer=sys.stdout.write, time_range=None, src_addr_formatter=debug.SourceAddress.__str__, node_filter=None, order=None, root_function=None, max_levels=None): thread_profiles = {} if merge_threads: root = ProfNode('All') thread_profiles['All'] = root for sample in samples: if time_range: sample = sample.intersection(time_range) if not sample: continue frames = [symbol_resolver(addr - 1) for addr in sample.backtrace] frames = strip_garbage(frames) if caller_oriented: frames.reverse() if root_function: i = find_frame_index(frames, root_function) if i: frames = frames[i:] else: frames = None if frames: if merge_threads: node = root else: node = thread_profiles.get(sample.thread, None) if not node: node = ProfNode('All') thread_profiles[sample.thread] = node node.hit(sample.resident_time) for src_addr in frames: node = node.get_or_add(src_addr_formatter(src_addr)) node.hit(sample.resident_time) def format_node(node, root): attributes = '' percentage_subject_getter = attrgetter('hit_count') if root.resident_time: attributes += format_time(node.resident_time) + ' ' percentage_subject_getter = attrgetter('resident_time') bracket_attributes = [] if percentage_subject_getter(root): percentage = float(percentage_subject_getter(node)) * 100 / percentage_subject_getter(root) bracket_attributes.append('%.2f%%' % percentage) bracket_attributes.append('#%d' % node.hit_count) label = '\n '.join([node.key] + node.tail) return "%s(%s) %s" % (attributes, ', '.join(bracket_attributes), label) if not order: order = lambda node: (-node.resident_time, -node.hit_count) for thread, tree_root in sorted(thread_profiles.iteritems(), key=lambda (thread, node): order(node)): collapse_similar(tree_root) if max_levels: strip_level(tree_root, max_levels) if not merge_threads: printer("\n=== Thread 0x%x ===\n\n" % thread) tree.print_tree(tree_root, formatter=lambda node: format_node(node, tree_root), order_by=order, printer=printer, node_filter=node_filter)
def print_profile(samples, symbol_resolver, caller_oriented=False, printer=default_printer, time_range=None, src_addr_formatter=debug.SourceAddress.__str__, node_filter=None, order=None, root_function=None, max_levels=None, grouping=None): groups = {} for sample in samples: if time_range: sample = sample.intersection(time_range) if not sample: continue frames = list( debug.resolve_all(symbol_resolver, (addr - 1 for addr in sample.backtrace))) frames = strip_garbage(frames) if caller_oriented: frames.reverse() if root_function: i = find_frame_index(frames, root_function) if i: frames = frames[i:] else: frames = None if frames: key = grouping.get_group(sample) if grouping else None node = groups.get(key, None) if not node: node = ProfNode('All') groups[key] = node node.hit(sample.resident_time) for src_addr in frames: node = node.get_or_add(src_addr_formatter(src_addr)) node.hit(sample.resident_time) def format_node(node, root): attributes = '' percentage_subject_getter = attrgetter('hit_count') if root.resident_time: attributes += format_time(node.resident_time) + ' ' percentage_subject_getter = attrgetter('resident_time') bracket_attributes = [] if percentage_subject_getter(root): percentage = float(percentage_subject_getter( node)) * 100 / percentage_subject_getter(root) bracket_attributes.append('%.2f%%' % percentage) bracket_attributes.append('#%d' % node.hit_count) label = '\n '.join([node.key] + node.tail) return "%s(%s) %s" % (attributes, ', '.join(bracket_attributes), label) if not order: order = lambda node: (-node.resident_time, -node.hit_count) for group, tree_root in sorted( iter(groups.items()), key=lambda thread_node: order(thread_node[1])): collapse_similar(tree_root) if max_levels: strip_level(tree_root, max_levels) if grouping: printer('\n=== ' + grouping.format(group) + ' ===\n\n') tree.print_tree(tree_root, formatter=lambda node: format_node(node, tree_root), order_by=order, printer=printer, node_filter=lambda node: node_filter(node, tree_root))
def show_results(mallocs, node_filters, sorter, group_by, symbol_resolver, src_addr_formatter=debug.SourceAddress.__str__, max_levels=None, show_backtrace=True, printer=prof.default_printer): root = tree.TreeNode(TreeKey('All', None)) lost = 0 unfreed = 0 for buf in mallocs: for desc in mallocs[buf]: node = root for gr in group_by: node = node.get_or_add(groups[gr](desc)) if desc.backtrace and show_backtrace: frames = list( debug.resolve_all(symbol_resolver, (addr - 1 for addr in desc.backtrace))) frames = prof.strip_garbage(frames) frames = strip_malloc(frames) level = max_levels bt = node for frame in frames: src_addr = src_addr_formatter(frame) bt = bt.get_or_add(TreeBacktrace(src_addr, node)) bt.key.hit() if max_levels: level -= 1 if not level: break node.key.alloc += 1 node.key.total_bytes += desc.alloc_len node.key.lost_bytes += desc.alloc_len - desc.req_len def flatten(node): for child in node.children: flatten(child) if node.has_only_one_child(): node.key.backtrace += '\n' + next(node.children).key.backtrace node.remove_all() def propagate(parent, node): if isinstance(node.key, TreeBacktrace): flatten(node) return for child in node.children: propagate(node, child) if parent: parent.key.alloc += node.key.alloc parent.key.total_bytes += node.key.total_bytes parent.key.lost_bytes += node.key.lost_bytes propagate(None, root) def formatter(node): return node.key.__str__() def node_filter(*args): for filter in node_filters: if not list(filter(*args)): return False return True def order_by(node): if isinstance(node.key, TreeBacktrace): return -node.key.count return sorters[sorter](node) tree.print_tree(root, formatter, printer=printer, order_by=order_by, node_filter=node_filter)
def show_results(mallocs, node_filters, sorter, group_by, symbol_resolver, src_addr_formatter=debug.SourceAddress.__str__, max_levels=None, show_backtrace=True, printer=prof.default_printer): root = tree.TreeNode(TreeKey('All', None)) lost = 0 unfreed = 0 for buf in mallocs: for desc in mallocs[buf]: node = root for gr in group_by: node = node.get_or_add(groups[gr](desc)) if desc.backtrace and show_backtrace: frames = list(debug.resolve_all(symbol_resolver, (addr - 1 for addr in desc.backtrace))) frames = prof.strip_garbage(frames) frames = strip_malloc(frames) level = max_levels bt = node for frame in frames: src_addr = src_addr_formatter(frame) bt = bt.get_or_add(TreeBacktrace(src_addr, node)) bt.key.hit() if max_levels: level -= 1 if not level: break node.key.alloc += 1 node.key.total_bytes += desc.alloc_len node.key.lost_bytes += desc.alloc_len - desc.req_len def flatten(node): for child in node.children: flatten(child) if node.has_only_one_child(): node.key.backtrace += '\n' + next(node.children).key.backtrace node.remove_all() def propagate(parent, node): if isinstance(node.key, TreeBacktrace): flatten(node) return for child in node.children: propagate(node, child) if parent: parent.key.alloc += node.key.alloc parent.key.total_bytes += node.key.total_bytes parent.key.lost_bytes += node.key.lost_bytes propagate(None, root) def formatter(node): return node.key.__str__() def node_filter(*args): for filter in node_filters: if not filter(*args): return False return True def order_by(node): if isinstance(node.key, TreeBacktrace): return -node.key.count return sorters[sorter](node) tree.print_tree(root, formatter, printer=printer, order_by=order_by, node_filter=node_filter)