mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
125 lines
3.4 KiB
Python
Executable File
125 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
# Copyright 2013 The Flutter Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
""" Gather the build_id, prefix_dir, and exec_name given the path to executable
|
|
also copies to the specified destination.
|
|
|
|
The structure of debug symbols is as follows:
|
|
.build-id/<prefix>/<exec_name>[.debug]
|
|
"""
|
|
|
|
import argparse
|
|
import errno
|
|
import json
|
|
import os
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
|
|
def Touch(fname):
|
|
with open(fname, 'a'):
|
|
os.utime(fname, None)
|
|
|
|
|
|
def GetBuildIdParts(exec_path, read_elf):
|
|
sha1_pattern = re.compile(r'[0-9a-fA-F\-]+')
|
|
file_out = subprocess.check_output([read_elf, '-n', exec_path])
|
|
build_id_line = file_out.splitlines()[-1].split()
|
|
if (build_id_line[0] != 'Build' or
|
|
build_id_line[1] != 'ID:' or not
|
|
sha1_pattern.match(build_id_line[-1]) or not
|
|
len(build_id_line[-1]) > 2):
|
|
raise Exception('Expected the last line of llvm-readelf to match "Build ID <Hex String>" Got: %s' % file_out)
|
|
|
|
build_id = build_id_line[-1]
|
|
return {
|
|
'build_id': build_id,
|
|
'prefix_dir': build_id[:2],
|
|
'exec_name': build_id[2:]
|
|
}
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument(
|
|
'--executable-name',
|
|
dest='exec_name',
|
|
action='store',
|
|
required=True,
|
|
help='This is the name of the executable that we wish to layout debug symbols for.'
|
|
)
|
|
parser.add_argument(
|
|
'--executable-path',
|
|
dest='exec_path',
|
|
action='store',
|
|
required=True,
|
|
help='Path to the executable on the filesystem.')
|
|
parser.add_argument(
|
|
'--destination-base',
|
|
dest='dest',
|
|
action='store',
|
|
required=True,
|
|
help='Path to the base directory where the debug symbols are to be laid out.'
|
|
)
|
|
parser.add_argument(
|
|
'--stripped',
|
|
dest='stripped',
|
|
action='store_true',
|
|
default=True,
|
|
help='Executable at the specified path is stripped.')
|
|
parser.add_argument(
|
|
'--unstripped',
|
|
dest='stripped',
|
|
action='store_false',
|
|
help='Executable at the specified path is unstripped.')
|
|
parser.add_argument(
|
|
'--read-elf',
|
|
dest='read_elf',
|
|
action='store',
|
|
required=True,
|
|
help='Path to read-elf executable.')
|
|
|
|
args = parser.parse_args()
|
|
assert os.path.exists(args.exec_path)
|
|
assert os.path.exists(args.dest)
|
|
assert os.path.exists(args.read_elf)
|
|
|
|
parts = GetBuildIdParts(args.exec_path, args.read_elf)
|
|
dbg_prefix_base = os.path.join(args.dest, parts['prefix_dir'])
|
|
|
|
# Multiple processes may be trying to create the same directory.
|
|
# TODO(dnfield): use exist_ok when we upgrade to python 3, rather than try
|
|
try:
|
|
os.makedirs(dbg_prefix_base)
|
|
except OSError as e:
|
|
if e.errno != errno.EEXIST:
|
|
raise
|
|
|
|
if not os.path.exists(dbg_prefix_base):
|
|
print 'Unable to create directory: %s.' % dbg_prefix_base
|
|
return 1
|
|
|
|
dbg_suffix = ''
|
|
if not args.stripped:
|
|
dbg_suffix = '.debug'
|
|
dbg_file_name = '%s%s' % (parts['exec_name'], dbg_suffix)
|
|
dbg_file_path = os.path.join(dbg_prefix_base, dbg_file_name)
|
|
|
|
shutil.copyfile(args.exec_path, dbg_file_path)
|
|
|
|
# Note this needs to be in sync with debug_symbols.gni
|
|
completion_file = os.path.join(args.dest, '.%s_dbg_success' % args.exec_name)
|
|
Touch(completion_file)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|