Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 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 """Generate a spatial analysis against an arbitrary library. | 6 """Generate a spatial analysis against an arbitrary library. |
| 7 | 7 |
| 8 To use, build the 'binary_size_tool' target. Then run this tool, passing | 8 To use, build the 'binary_size_tool' target. Then run this tool, passing |
| 9 in the location of the library to be analyzed along with any other options | 9 in the location of the library to be analyzed along with any other options |
| 10 you desire. | 10 you desire. |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 537 def _find_in_system_path(binary): | 537 def _find_in_system_path(binary): |
| 538 """Locate the full path to binary in the system path or return None | 538 """Locate the full path to binary in the system path or return None |
| 539 if not found.""" | 539 if not found.""" |
| 540 system_path = os.environ["PATH"].split(os.pathsep) | 540 system_path = os.environ["PATH"].split(os.pathsep) |
| 541 for path in system_path: | 541 for path in system_path: |
| 542 binary_path = os.path.join(path, binary) | 542 binary_path = os.path.join(path, binary) |
| 543 if os.path.isfile(binary_path): | 543 if os.path.isfile(binary_path): |
| 544 return binary_path | 544 return binary_path |
| 545 return None | 545 return None |
| 546 | 546 |
| 547 def CheckDebugFormatSupport(library, addr2line_binary, nm_binary): | |
| 548 """There are two common versions of the DWARF debug formats and | |
|
Primiano Tucci (use gerrit)
2014/05/27 09:40:10
Nit: docstring format (1 line + blank line + descr
Daniel Bratell
2014/06/04 13:31:02
Done.
| |
| 549 since we are right now transitioning from DWARF2 to newer formats, | |
| 550 it's possible to have a mix of tools that are not compatible. Detect | |
| 551 that and abort rather than produce meaningless output.""" | |
| 552 tool_output = subprocess.check_output([addr2line_binary, "--version"]) | |
| 553 version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M) | |
|
Primiano Tucci (use gerrit)
2014/05/27 09:40:10
Please be consistent with quotes (double vs single
Daniel Bratell
2014/06/04 13:31:02
Done.
| |
| 554 parsed_output = version_re.match(tool_output) | |
| 555 major = int(parsed_output.group(1)) | |
| 556 minor = int(parsed_output.group(2)) | |
| 557 supports_dwarf4 = major > 2 or major == 2 and minor > 22 | |
| 558 | |
| 559 if supports_dwarf4: | |
| 560 return | |
| 561 | |
| 562 print("Checking version of debug information in %s." % library) | |
| 563 debug_info = subprocess.check_output(["readelf", "--debug-dump=info", | |
| 564 "--dwarf-depth=1", library]) | |
| 565 dwarf_version_re = re.compile(r"^\s+Version:\s+(\d+)$", re.M) | |
| 566 parsed_dwarf_format_output = dwarf_version_re.search(debug_info) | |
| 567 version = int(parsed_dwarf_format_output.group(1)) | |
| 568 if version > 2: | |
| 569 print("""\ | |
|
Primiano Tucci (use gerrit)
2014/05/27 09:40:10
From code style:
Yes:
print ("This is much nice
Daniel Bratell
2014/06/04 13:31:02
Will fix, but the suggested format is really bad i
| |
| 570 The supplied tools only support DWARF2 debug data but the binary | |
| 571 uses DWARF%d. Update the tools or compile the binary with -gdwarf-2.""" % | |
| 572 version) | |
| 573 sys.exit(1) | |
| 574 | |
| 547 | 575 |
| 548 def main(): | 576 def main(): |
| 549 usage = """%prog [options] | 577 usage = """%prog [options] |
| 550 | 578 |
| 551 Runs a spatial analysis on a given library, looking up the source locations | 579 Runs a spatial analysis on a given library, looking up the source locations |
| 552 of its symbols and calculating how much space each directory, source file, | 580 of its symbols and calculating how much space each directory, source file, |
| 553 and so on is taking. The result is a report that can be used to pinpoint | 581 and so on is taking. The result is a report that can be used to pinpoint |
| 554 sources of large portions of the binary, etceteras. | 582 sources of large portions of the binary, etceteras. |
| 555 | 583 |
| 556 Under normal circumstances, you only need to pass two arguments, thusly: | 584 Under normal circumstances, you only need to pass two arguments, thusly: |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 631 'Use --addr2line-binary to specify location.' | 659 'Use --addr2line-binary to specify location.' |
| 632 | 660 |
| 633 if opts.nm_binary: | 661 if opts.nm_binary: |
| 634 assert os.path.isfile(opts.nm_binary) | 662 assert os.path.isfile(opts.nm_binary) |
| 635 nm_binary = opts.nm_binary | 663 nm_binary = opts.nm_binary |
| 636 else: | 664 else: |
| 637 nm_binary = _find_in_system_path('nm') | 665 nm_binary = _find_in_system_path('nm') |
| 638 assert nm_binary, 'Unable to find nm in the path. Use --nm-binary '\ | 666 assert nm_binary, 'Unable to find nm in the path. Use --nm-binary '\ |
| 639 'to specify location.' | 667 'to specify location.' |
| 640 | 668 |
| 669 print('addr2line: %s' % addr2line_binary) | |
| 641 print('nm: %s' % nm_binary) | 670 print('nm: %s' % nm_binary) |
| 642 print('addr2line: %s' % addr2line_binary) | 671 |
| 672 CheckDebugFormatSupport(opts.library, addr2line_binary, nm_binary) | |
| 643 | 673 |
| 644 symbols = GetNmSymbols(opts.nm_in, opts.nm_out, opts.library, | 674 symbols = GetNmSymbols(opts.nm_in, opts.nm_out, opts.library, |
| 645 opts.jobs, opts.verbose is True, | 675 opts.jobs, opts.verbose is True, |
| 646 addr2line_binary, nm_binary) | 676 addr2line_binary, nm_binary) |
| 647 if not os.path.exists(opts.destdir): | 677 if not os.path.exists(opts.destdir): |
| 648 os.makedirs(opts.destdir, 0755) | 678 os.makedirs(opts.destdir, 0755) |
| 649 | 679 |
| 650 | 680 |
| 651 if opts.legacy: # legacy report | 681 if opts.legacy: # legacy report |
| 652 DumpTreemap(symbols, os.path.join(opts.destdir, 'treemap-dump.js')) | 682 DumpTreemap(symbols, os.path.join(opts.destdir, 'treemap-dump.js')) |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 681 print('Copying index.html') | 711 print('Copying index.html') |
| 682 shutil.copy(os.path.join(template_src, 'index.html'), opts.destdir) | 712 shutil.copy(os.path.join(template_src, 'index.html'), opts.destdir) |
| 683 shutil.copy(os.path.join(template_src, 'D3SymbolTreeMap.js'), opts.destdir) | 713 shutil.copy(os.path.join(template_src, 'D3SymbolTreeMap.js'), opts.destdir) |
| 684 | 714 |
| 685 if opts.verbose: | 715 if opts.verbose: |
| 686 print 'Report saved to ' + opts.destdir + '/index.html' | 716 print 'Report saved to ' + opts.destdir + '/index.html' |
| 687 | 717 |
| 688 | 718 |
| 689 if __name__ == '__main__': | 719 if __name__ == '__main__': |
| 690 sys.exit(main()) | 720 sys.exit(main()) |
| OLD | NEW |