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 |