1 #!/usr/bin/env python 2 # Copyright (c) 2013 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 """ 7 Dumps a list of files with static initializers. Use with release builds. 8 9 Usage: 10 tools/mac/dump-static-initializers.py out/Release/Chromium\ Framework.framework.dSYM/Contents/Resources/DWARF/Chromium\ Framework 11 12 Do NOT use mac_strip_release=0 or component=shared_library if you want to use 13 this script. 14 """ 15 16 import optparse 17 import re 18 import subprocess 19 import sys 20 21 # Matches for example: 22 # [ 1] 000001ca 64 (N_SO ) 00 0000 0000000000000000 'test.cc' 23 dsymutil_file_re = re.compile("N_SO.*'([^']*)'") 24 25 # Matches for example: 26 # [ 2] 000001d2 66 (N_OSO ) 00 0001 000000004ed856a0 '/Volumes/MacintoshHD2/src/chrome-git/src/test.o' 27 dsymutil_o_file_re = re.compile("N_OSO.*'([^']*)'") 28 29 # Matches for example: 30 # [ 8] 00000233 24 (N_FUN ) 01 0000 0000000000001b40 '__GLOBAL__I_s' 31 # [185989] 00dc69ef 26 (N_STSYM ) 02 0000 00000000022e2290 '__GLOBAL__I_a' 32 dsymutil_re = re.compile(r"(?:N_FUN|N_STSYM).*\s[0-9a-f]*\s'__GLOBAL__I_") 33 34 def ParseDsymutil(binary): 35 """Given a binary, prints source and object filenames for files with 36 static initializers. 37 """ 38 39 child = subprocess.Popen(['dsymutil', '-s', binary], stdout=subprocess.PIPE) 40 for line in child.stdout: 41 file_match = dsymutil_file_re.search(line) 42 if file_match: 43 current_filename = file_match.group(1) 44 else: 45 o_file_match = dsymutil_o_file_re.search(line) 46 if o_file_match: 47 current_o_filename = o_file_match.group(1) 48 else: 49 match = dsymutil_re.search(line) 50 if match: 51 print current_filename 52 print current_o_filename 53 print 54 55 56 def main(): 57 parser = optparse.OptionParser(usage='%prog filename') 58 opts, args = parser.parse_args() 59 if len(args) != 1: 60 parser.error('missing filename argument') 61 return 1 62 binary = args[0] 63 64 ParseDsymutil(binary) 65 return 0 66 67 68 if '__main__' == __name__: 69 sys.exit(main()) 70