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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 else: | 448 else: |
| 449 speed = 0 | 449 speed = 0 |
| 450 progress_percent = (100.0 * (progress.count + progress.skip_count) / | 450 progress_percent = (100.0 * (progress.count + progress.skip_count) / |
| 451 nm_output_lines_len) | 451 nm_output_lines_len) |
| 452 print('%.1f%%: Looked up %d symbols (%d collisions) - %.1f lookups/s.' % | 452 print('%.1f%%: Looked up %d symbols (%d collisions) - %.1f lookups/s.' % |
| 453 (progress_percent, progress.count, progress.collisions, speed)) | 453 (progress_percent, progress.count, progress.collisions, speed)) |
| 454 | 454 |
| 455 symbolizer = elf_symbolizer.ELFSymbolizer(library, addr2line_binary, | 455 symbolizer = elf_symbolizer.ELFSymbolizer(library, addr2line_binary, |
| 456 map_address_symbol, | 456 map_address_symbol, |
| 457 max_concurrent_jobs=jobs) | 457 max_concurrent_jobs=jobs) |
| 458 for line in nm_output_lines: | 458 user_interrupted = False |
| 459 match = sNmPattern.match(line) | 459 try: |
| 460 if match: | 460 for line in nm_output_lines: |
| 461 location = match.group(5) | 461 match = sNmPattern.match(line) |
| 462 if not location: | 462 if match: |
| 463 addr = int(match.group(1), 16) | 463 location = match.group(5) |
| 464 size = int(match.group(2), 16) | 464 if not location: |
| 465 if addr in address_symbol: # Already looked up, shortcut ELFSymbolizer. | 465 addr = int(match.group(1), 16) |
| 466 map_address_symbol(address_symbol[addr], addr) | 466 size = int(match.group(2), 16) |
| 467 continue | 467 if addr in address_symbol: # Already looked up, shortcut |
| 468 elif size == 0: | 468 # ELFSymbolizer. |
| 469 # Save time by not looking up empty symbols (do they even exist?) | 469 map_address_symbol(address_symbol[addr], addr) |
| 470 print('Empty symbol: ' + line) | 470 continue |
| 471 else: | 471 elif size == 0: |
| 472 symbolizer.SymbolizeAsync(addr, addr) | 472 # Save time by not looking up empty symbols (do they even exist?) |
| 473 continue | 473 print('Empty symbol: ' + line) |
| 474 else: | |
| 475 symbolizer.SymbolizeAsync(addr, addr) | |
| 476 continue | |
| 474 | 477 |
| 475 progress.skip_count += 1 | 478 progress.skip_count += 1 |
| 479 except KeyboardInterrupt: | |
| 480 user_interrupted = True | |
| 476 | 481 |
| 477 symbolizer.Join() | 482 if user_interrupted: |
| 483 print('Interrupting - killing subprocesses.') | |
|
Primiano Tucci (use gerrit)
2014/05/27 09:31:46
Can you move this (and indent) to line 481, in the
| |
| 484 | |
| 485 try: | |
| 486 symbolizer.Join() | |
| 487 except KeyboardInterrupt: | |
| 488 # Don't want to abort here since we will be finished in a few seconds. | |
| 489 user_interrupted = True | |
| 490 print('Patience you must have my young padawan.') | |
|
Primiano Tucci (use gerrit)
2014/05/27 09:31:46
:-D
| |
| 491 | |
| 492 if user_interrupted: | |
| 493 print('Skipping the rest of the file mapping. ' | |
| 494 'Output will not be fully classified.') | |
| 478 | 495 |
| 479 with open(outfile, 'w') as out: | 496 with open(outfile, 'w') as out: |
| 480 for line in nm_output_lines: | 497 for line in nm_output_lines: |
| 481 match = sNmPattern.match(line) | 498 match = sNmPattern.match(line) |
| 482 if match: | 499 if match: |
| 483 location = match.group(5) | 500 location = match.group(5) |
| 484 if not location: | 501 if not location: |
| 485 addr = int(match.group(1), 16) | 502 addr = int(match.group(1), 16) |
| 486 symbol = address_symbol[addr] | 503 symbol = address_symbol.get(addr) |
| 487 path = '??' | 504 if symbol is not None: |
| 488 if symbol.source_path is not None: | 505 path = '??' |
| 489 path = symbol.source_path | 506 if symbol.source_path is not None: |
| 490 line_number = 0 | 507 path = symbol.source_path |
| 491 if symbol.source_line is not None: | 508 line_number = 0 |
| 492 line_number = symbol.source_line | 509 if symbol.source_line is not None: |
| 493 out.write('%s\t%s:%d\n' % (line, path, line_number)) | 510 line_number = symbol.source_line |
| 494 continue | 511 out.write('%s\t%s:%d\n' % (line, path, line_number)) |
| 512 continue | |
| 495 | 513 |
| 496 out.write('%s\n' % line) | 514 out.write('%s\n' % line) |
| 497 | 515 |
| 498 print('%d symbols in the results.' % len(address_symbol)) | 516 print('%d symbols in the results.' % len(address_symbol)) |
| 499 | 517 |
| 500 | 518 |
| 501 def RunNm(binary, nm_binary): | 519 def RunNm(binary, nm_binary): |
| 502 print('Starting nm') | 520 print('Starting nm') |
| 503 cmd = [nm_binary, '-C', '--print-size', binary] | 521 cmd = [nm_binary, '-C', '--print-size', '--size-sort', '--reverse-sort', |
| 522 binary] | |
| 504 nm_process = subprocess.Popen(cmd, | 523 nm_process = subprocess.Popen(cmd, |
| 505 stdout=subprocess.PIPE, | 524 stdout=subprocess.PIPE, |
| 506 stderr=subprocess.PIPE) | 525 stderr=subprocess.PIPE) |
| 507 (process_output, err_output) = nm_process.communicate() | 526 (process_output, err_output) = nm_process.communicate() |
| 508 | 527 |
| 509 if nm_process.returncode != 0: | 528 if nm_process.returncode != 0: |
| 510 if err_output: | 529 if err_output: |
| 511 raise Exception, err_output | 530 raise Exception, err_output |
| 512 else: | 531 else: |
| 513 raise Exception, process_output | 532 raise Exception, process_output |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 671 if not os.path.exists(d3_out): | 690 if not os.path.exists(d3_out): |
| 672 os.makedirs(d3_out, 0755) | 691 os.makedirs(d3_out, 0755) |
| 673 d3_src = os.path.join(os.path.dirname(__file__), | 692 d3_src = os.path.join(os.path.dirname(__file__), |
| 674 '..', | 693 '..', |
| 675 '..', | 694 '..', |
| 676 'third_party', 'd3', 'src') | 695 'third_party', 'd3', 'src') |
| 677 template_src = os.path.join(os.path.dirname(__file__), | 696 template_src = os.path.join(os.path.dirname(__file__), |
| 678 'template') | 697 'template') |
| 679 shutil.copy(os.path.join(d3_src, 'LICENSE'), d3_out) | 698 shutil.copy(os.path.join(d3_src, 'LICENSE'), d3_out) |
| 680 shutil.copy(os.path.join(d3_src, 'd3.js'), d3_out) | 699 shutil.copy(os.path.join(d3_src, 'd3.js'), d3_out) |
| 681 print('Copying index.html') | |
| 682 shutil.copy(os.path.join(template_src, 'index.html'), opts.destdir) | 700 shutil.copy(os.path.join(template_src, 'index.html'), opts.destdir) |
| 683 shutil.copy(os.path.join(template_src, 'D3SymbolTreeMap.js'), opts.destdir) | 701 shutil.copy(os.path.join(template_src, 'D3SymbolTreeMap.js'), opts.destdir) |
| 684 | 702 |
| 685 if opts.verbose: | 703 print 'Report saved to ' + opts.destdir + '/index.html' |
| 686 print 'Report saved to ' + opts.destdir + '/index.html' | |
| 687 | 704 |
| 688 | 705 |
| 689 if __name__ == '__main__': | 706 if __name__ == '__main__': |
| 690 sys.exit(main()) | 707 sys.exit(main()) |
| OLD | NEW |