1#!/usr/bin/env python3 2# Copyright (C) 2019 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16# This file should do the same thing when being invoked in any of these ways: 17# ./trace_processor 18# python trace_processor 19# bash trace_processor 20# cat ./trace_processor | bash 21# cat ./trace_processor | python - 22 23BASH_FALLBACK = """ " 24exec python3 - "$@" <<'#'EOF 25#""" 26 27import hashlib 28import os 29import sys 30import tempfile 31import subprocess 32import platform 33 34TRACE_PROCESSOR_SHELL_SHAS = { 35 'linux': 'a3ce2cbf4cbe4f86cc10b02957db727cecfafae8', 36 'mac': 'c39a5be9a3831911ef2e50d66d11c12d877688f3', 37} 38TRACE_PROCESSOR_SHELL_PATH = tempfile.gettempdir() 39TRACE_PROCESSOR_SHELL_BASE_URL = ('https://storage.googleapis.com/perfetto/') 40 41 42def DownloadURL(url, out_file): 43 subprocess.check_call(['curl', '-L', '-#', '-o', out_file, url]) 44 45 46def check_hash(file_name, sha_value): 47 with open(file_name, 'rb') as fd: 48 file_hash = hashlib.sha1(fd.read()).hexdigest() 49 return file_hash == sha_value 50 51 52def load_trace_processor_shell(platform): 53 sha_value = TRACE_PROCESSOR_SHELL_SHAS[platform] 54 file_name = 'trace_processor_shell-' + platform + '-' + sha_value 55 local_file = os.path.join(TRACE_PROCESSOR_SHELL_PATH, file_name) 56 57 if os.path.exists(local_file): 58 if not check_hash(local_file, sha_value): 59 os.remove(local_file) 60 else: 61 return local_file 62 63 url = TRACE_PROCESSOR_SHELL_BASE_URL + file_name 64 DownloadURL(url, local_file) 65 if not check_hash(local_file, sha_value): 66 os.remove(local_file) 67 raise ValueError("Invalid signature.") 68 os.chmod(local_file, 0o755) 69 return local_file 70 71 72def main(argv): 73 os_name = None 74 if sys.platform.startswith('linux'): 75 os_name = 'linux' 76 elif sys.platform.startswith('darwin'): 77 os_name = 'mac' 78 else: 79 print("Invalid platform: {}".format(sys.platform)) 80 return 1 81 82 arch = platform.machine() 83 if arch not in ['x86_64', 'amd64']: 84 print("Prebuilts are only available for x86_64 (found '{}' instead).".format(arch)) 85 print("Follow https://perfetto.dev/docs/contributing/build-instructions to build locally.") 86 return 1 87 88 trace_processor_shell_binary = load_trace_processor_shell(os_name) 89 os.execv(trace_processor_shell_binary, 90 [trace_processor_shell_binary] + argv[1:]) 91 92 93if __name__ == '__main__': 94 sys.exit(main(sys.argv)) 95 96#EOF 97