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

Side by Side Diff: tools/binary_size/query.py

Issue 2778963003: Revert of V2 of //tools/binary_size rewrite (diffs). (Closed)
Patch Set: Created 3 years, 8 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
« no previous file with comments | « tools/binary_size/models.py ('k') | tools/binary_size/symbols.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2017 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Tool for analyzing binary size of executables using nm or linker map files.
7
8 Map files can be created by passing "-Map Foo.map" to the linker. If a map file
9 is unavailable, this tool can also be pointed at an unstripped executable, but
10 the information does not seem to be as accurate in this case.
11
12 Inspired by SymbolSort for Windows:
13 https://github.com/adrianstone55/SymbolSort
14 """
15
16 import argparse
17 import code
18 import contextlib
19 import logging
20 import readline
21 import subprocess
22 import sys
23
24 import analyze
25 import helpers
26 import symbols
27
28
29 # Number of lines before using less for Print().
30 _THRESHOLD_FOR_PAGER = 30
31
32
33 @contextlib.contextmanager
34 def _LessPipe():
35 """Output to `less`. Yields the write function."""
36 try:
37 proc = subprocess.Popen(['less'], stdin=subprocess.PIPE, stdout=sys.stdout)
38 yield proc.stdin.write
39 proc.stdin.close()
40
41 proc.wait()
42 except IOError:
43 pass # Happens when less is quit before all data is written.
44 except KeyboardInterrupt:
45 pass # Assume used to break out of less.
46
47
48 def _PrintSymbolGroup(group, show_elided=True, use_pager=None):
49 """Prints out the given list of symbols.
50
51 Args:
52 show_elided: Whether to print out group.filtered_symbols.
53 """
54 by_size = group.Sorted()
55 # TODO(agrieve): Taking line-wrapping into account for groups vs. symbols
56 # would make sense here.
57 if use_pager is None:
58 count = sum(1 if s.IsGroup() else 2 for s in group)
59 if show_elided and group.filtered_symbols:
60 count += 1
61 use_pager = count > _THRESHOLD_FOR_PAGER
62
63 def write_to_func(write):
64 write('Showing {:,} results with total size: {:,} bytes\n'.format(
65 len(group), group.size))
66 for s in by_size:
67 if s.IsGroup():
68 write('{} {:<9,} {} ({})\n'.format(s.section, s.size, s.name, len(s)))
69 else:
70 template = '{}@0x{:<8x} {:<7} {}\n{:22}{}\n'
71 write(template.format(s.section, s.address, s.size,
72 s.path or '<no path>', '', s.name or '<no name>'))
73 if show_elided and group.filtered_symbols:
74 elided = group.Inverted()
75 write('* Filtered out {:,} symbols comprising {:<7,} bytes.\n'.format(
76 len(elided), elided.size))
77
78 if use_pager:
79 with _LessPipe() as write:
80 write_to_func(write)
81 else:
82 write_to_func(sys.stdout.write)
83
84
85 def main():
86 parser = argparse.ArgumentParser()
87 parser.add_argument('--query',
88 help='Print the result of the given snippet. Example: '
89 'all_syms.WhereInSection("d").WhereBiggerThan(100)')
90 analyze.AddOptions(parser)
91 args = helpers.AddCommonOptionsAndParseArgs(parser)
92
93 result = analyze.AnalyzeWithArgs(args)
94
95 variables = {
96 'Print': _PrintSymbolGroup,
97 'all_syms': result.symbol_group,
98 }
99
100 if args.query:
101 logging.info('Running query from command-line.')
102 eval_result = eval(args.query, locals=variables)
103 if isinstance(eval_result, symbols.SymbolGroup):
104 _PrintSymbolGroup(eval_result, show_elided=False, use_pager=False)
105 return
106
107 logging.info('Entering interactive console.')
108
109 print '*' * 80
110 print 'Entering interactive Python shell. Here is some inspiration:'
111 print
112 print '# Show two levels of .text, grouped by first two subdirectories'
113 print 'text_syms = all_syms.WhereInSection("t")'
114 print 'by_path = text_syms.GroupByPath(depth=2)'
115 print 'Print(by_path.WhereBiggerThan(1024, include_filtered=True))'
116 print
117 print '# Show all non-vtable generated symbols'
118 print 'Print(all_syms.WhereNameMatches(r"(?<!vtable)(?<!\[)\]$"))'
119 print
120 print '*' * 80
121 print
122 print 'locals:', variables.keys()
123 print 'method quick reference:', (
124 [m for m in dir(symbols.SymbolGroup) if m[0].isupper()])
125 print
126 print '*' * 80
127
128 # Without initializing readline, arrow keys don't even work!
129 readline.parse_and_bind('tab: complete')
130 code.InteractiveConsole(locals=variables).interact()
131
132
133 if __name__ == '__main__':
134 main()
OLDNEW
« no previous file with comments | « tools/binary_size/models.py ('k') | tools/binary_size/symbols.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698