#!/usr/bin/env python3
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# DO NOT EDIT. Auto-generated by tools/gen_amalgamated_python_tools
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import atexit
import os
import shutil
import signal
import subprocess
import sys
import tempfile
import time
import uuid


# ----- Amalgamator: begin of python/perfetto/prebuilts/manifests/traceconv.py
# This file has been generated by: /Users/hjd/src/perfetto/tools/roll-prebuilts v35.0
TRACECONV_MANIFEST = [{
    'arch':
        'mac-amd64',
    'file_name':
        'traceconv',
    'file_size':
        8118096,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/mac-amd64/traceconv',
    'sha256':
        '38927d082f6a36cc86f0ede0bebe00ce75069e3183a52884b29a9d38d0f259b2',
    'platform':
        'darwin',
    'machine': ['x86_64']
}, {
    'arch':
        'mac-arm64',
    'file_name':
        'traceconv',
    'file_size':
        6720184,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/mac-arm64/traceconv',
    'sha256':
        '6907eb5010866454bcd7430b154a2320c97c9637cf20c249302e3ea58347ceb6',
    'platform':
        'darwin',
    'machine': ['arm64']
}, {
    'arch':
        'linux-amd64',
    'file_name':
        'traceconv',
    'file_size':
        7871712,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/linux-amd64/traceconv',
    'sha256':
        'c5f261e8a910a0c4192e916c0f0e96cfe1bf599b1cdb415058cd3a533e05f956',
    'platform':
        'linux',
    'machine': ['x86_64']
}, {
    'arch':
        'linux-arm',
    'file_name':
        'traceconv',
    'file_size':
        5802976,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/linux-arm/traceconv',
    'sha256':
        'b4796052b8761cd1cc9e64831764224fb8dfbc80e067db963a27eed3caf56f0d',
    'platform':
        'linux',
    'machine': ['armv6l', 'armv7l', 'armv8l']
}, {
    'arch':
        'linux-arm64',
    'file_name':
        'traceconv',
    'file_size':
        7366464,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/linux-arm64/traceconv',
    'sha256':
        '2760c807601d07e9073d5f9266417f07466a1cd706a404b6d535846dd463160e',
    'platform':
        'linux',
    'machine': ['aarch64']
}, {
    'arch':
        'android-arm',
    'file_name':
        'traceconv',
    'file_size':
        5448160,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/android-arm/traceconv',
    'sha256':
        'fab85439606a467847c67d5fa9952e433d4eacdc49ef37b94542dc9b891bcfbc'
}, {
    'arch':
        'android-arm64',
    'file_name':
        'traceconv',
    'file_size':
        6716048,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/android-arm64/traceconv',
    'sha256':
        '03e2473ddcac1b99fe670d2ab32381b8bdb4e3f3f406bf964c635fac91add543'
}, {
    'arch':
        'android-x86',
    'file_name':
        'traceconv',
    'file_size':
        7487908,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/android-x86/traceconv',
    'sha256':
        '3a0372d6f308c836732bdccc913a6ef2c76977a2fa626bf527b4d7128cb9cce3'
}, {
    'arch':
        'android-x64',
    'file_name':
        'traceconv',
    'file_size':
        7662280,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/android-x64/traceconv',
    'sha256':
        '7abcc69eba8a5722fb03c6076500ee9958659d5393a63c8e1983cb17f1b92bcb'
}, {
    'arch':
        'windows-amd64',
    'file_name':
        'traceconv.exe',
    'file_size':
        7147008,
    'url':
        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v35.0/windows-amd64/traceconv.exe',
    'sha256':
        '7af5f61a0fa53aa3741a71546ca3a9cf7ad0e24b5d7c6331cf032b18f93a93c7',
    'platform':
        'win32',
    'machine': ['amd64']
}]

# ----- Amalgamator: end of python/perfetto/prebuilts/manifests/traceconv.py

# ----- Amalgamator: begin of python/perfetto/prebuilts/perfetto_prebuilts.py
# Copyright (C) 2021 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Functions to fetch pre-pinned Perfetto prebuilts.

This function is used in different places:
- Into the //tools/{trace_processor, traceconv} scripts, which are just plain
  wrappers around executables.
- Into the //tools/{heap_profiler, record_android_trace} scripts, which contain
  some other hand-written python code.

The manifest argument looks as follows:
TRACECONV_MANIFEST = [
  {
    'arch': 'mac-amd64',
    'file_name': 'traceconv',
    'file_size': 7087080,
    'url': https://commondatastorage.googleapis.com/.../trace_to_text',
    'sha256': 7d957c005b0dc130f5bd855d6cec27e060d38841b320d04840afc569f9087490',
    'platform': 'darwin',
    'machine': 'x86_64'
  },
  ...
]

The intended usage is:

  from perfetto.prebuilts.manifests.traceconv import TRACECONV_MANIFEST
  bin_path = get_perfetto_prebuilt(TRACECONV_MANIFEST)
  subprocess.call(bin_path, ...)
"""

import hashlib
import os
import platform
import subprocess
import sys


def download_or_get_cached(file_name, url, sha256):
  """ Downloads a prebuilt or returns a cached version

  The first time this is invoked, it downloads the |url| and caches it into
  ~/.local/share/perfetto/prebuilts/$tool_name. On subsequent invocations it
  just runs the cached version.
  """
  dir = os.path.join(
      os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts')
  os.makedirs(dir, exist_ok=True)
  bin_path = os.path.join(dir, file_name)
  sha256_path = os.path.join(dir, file_name + '.sha256')
  needs_download = True

  # Avoid recomputing the SHA-256 on each invocation. The SHA-256 of the last
  # download is cached into file_name.sha256, just check if that matches.
  if os.path.exists(bin_path) and os.path.exists(sha256_path):
    with open(sha256_path, 'rb') as f:
      digest = f.read().decode()
      if digest == sha256:
        needs_download = False

  if needs_download:
    # Either the filed doesn't exist or the SHA256 doesn't match.
    tmp_path = bin_path + '.tmp'
    print('Downloading ' + url)
    subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url])
    with open(tmp_path, 'rb') as fd:
      actual_sha256 = hashlib.sha256(fd.read()).hexdigest()
    if actual_sha256 != sha256:
      raise Exception('Checksum mismatch for %s (actual: %s, expected: %s)' %
                      (url, actual_sha256, sha256))
    os.chmod(tmp_path, 0o755)
    os.replace(tmp_path, bin_path)
    with open(sha256_path, 'w') as f:
      f.write(sha256)
  return bin_path


def get_perfetto_prebuilt(manifest, soft_fail=False, arch=None):
  """ Downloads the prebuilt, if necessary, and returns its path on disk. """
  plat = sys.platform.lower()
  machine = platform.machine().lower()
  manifest_entry = None
  for entry in manifest:
    # If the caller overrides the arch, just match that (for Android prebuilts).
    if arch:
      if entry.get('arch') == arch:
        manifest_entry = entry
        break
      continue
    # Otherwise guess the local machine arch.
    if entry.get('platform') == plat and machine in entry.get('machine', []):
      manifest_entry = entry
      break
  if manifest_entry is None:
    if soft_fail:
      return None
    raise Exception(
        ('No prebuilts available for %s-%s\n' % (plat, machine)) +
        'See https://perfetto.dev/docs/contributing/build-instructions')

  return download_or_get_cached(
      file_name=manifest_entry['file_name'],
      url=manifest_entry['url'],
      sha256=manifest_entry['sha256'])


def run_perfetto_prebuilt(manifest):
  bin_path = get_perfetto_prebuilt(manifest)
  if sys.platform.lower() == 'win32':
    sys.exit(subprocess.check_call([bin_path, *sys.argv[1:]]))
  os.execv(bin_path, [bin_path] + sys.argv[1:])

# ----- Amalgamator: end of python/perfetto/prebuilts/perfetto_prebuilts.py

NULL = open(os.devnull)
NOOUT = {
    'stdout': NULL,
    'stderr': NULL,
}

UUID = str(uuid.uuid4())[-6:]

PACKAGES_LIST_CFG = '''data_sources {
  config {
    name: "android.packages_list"
  }
}
'''

CFG_INDENT = '      '
CFG = '''buffers {{
  size_kb: 63488
}}

data_sources {{
  config {{
    name: "android.heapprofd"
    heapprofd_config {{
      shmem_size_bytes: {shmem_size}
      sampling_interval_bytes: {interval}
{target_cfg}
    }}
  }}
}}

duration_ms: {duration}
write_into_file: true
flush_timeout_ms: 30000
flush_period_ms: 604800000
'''

# flush_period_ms of 1 week to suppress trace_processor_shell warning.

CONTINUOUS_DUMP = """
      continuous_dump_config {{
        dump_phase_ms: 0
        dump_interval_ms: {dump_interval}
      }}
"""

PROFILE_LOCAL_PATH = os.path.join(tempfile.gettempdir(), UUID)

IS_INTERRUPTED = False


def sigint_handler(sig, frame):
  global IS_INTERRUPTED
  IS_INTERRUPTED = True


def print_no_profile_error():
  print("No profiles generated", file=sys.stderr)
  print(
      "If this is unexpected, check "
      "https://perfetto.dev/docs/data-sources/native-heap-profiler#troubleshooting.",
      file=sys.stderr)


def known_issues_url(number):
  return ('https://perfetto.dev/docs/data-sources/native-heap-profiler'
          '#known-issues-android{}'.format(number))


KNOWN_ISSUES = {
    '10': known_issues_url(10),
    'Q': known_issues_url(10),
    '11': known_issues_url(11),
    'R': known_issues_url(11),
}


def maybe_known_issues():
  release_or_codename = subprocess.check_output(
      ['adb', 'shell', 'getprop',
       'ro.build.version.release_or_codename']).decode('utf-8').strip()
  return KNOWN_ISSUES.get(release_or_codename, None)


SDK = {
    'R': 30,
}


def release_or_newer(release):
  sdk = int(
      subprocess.check_output(
          ['adb', 'shell', 'getprop',
           'ro.system.build.version.sdk']).decode('utf-8').strip())
  if sdk >= SDK[release]:
    return True
  codename = subprocess.check_output(
      ['adb', 'shell', 'getprop',
       'ro.build.version.codename']).decode('utf-8').strip()
  return codename == release


ORDER = ['-n', '-p', '-i', '-o']


def arg_order(action):
  result = len(ORDER)
  for opt in action.option_strings:
    if opt in ORDER:
      result = min(ORDER.index(opt), result)
  return result, action.option_strings[0].strip('-')


def print_options(parser):
  for action in sorted(parser._actions, key=arg_order):
    if action.help is argparse.SUPPRESS:
      continue
    opts = ', '.join('`' + x + '`' for x in action.option_strings)
    metavar = '' if action.metavar is None else ' _' + action.metavar + '_'
    print('{}{}'.format(opts, metavar))
    print(':    {}'.format(action.help))
    print()


def main(argv):
  parser = argparse.ArgumentParser()
  parser.add_argument(
      "-i",
      "--interval",
      help="Sampling interval. "
      "Default 4096 (4KiB)",
      type=int,
      default=4096)
  parser.add_argument(
      "-d",
      "--duration",
      help="Duration of profile (ms). 0 to run until interrupted. "
      "Default: until interrupted by user.",
      type=int,
      default=0)
  # This flag is a no-op now. We never start heapprofd explicitly using system
  # properties.
  parser.add_argument(
      "--no-start", help="Do not start heapprofd.", action='store_true')
  parser.add_argument(
      "-p",
      "--pid",
      help="Comma-separated list of PIDs to "
      "profile.",
      metavar="PIDS")
  parser.add_argument(
      "-n",
      "--name",
      help="Comma-separated list of process "
      "names to profile.",
      metavar="NAMES")
  parser.add_argument(
      "-c",
      "--continuous-dump",
      help="Dump interval in ms. 0 to disable continuous dump.",
      type=int,
      default=0)
  parser.add_argument(
      "--heaps",
      help="Comma-separated list of heaps to collect, e.g: malloc,art. "
      "Requires Android 12.",
      metavar="HEAPS")
  parser.add_argument(
      "--all-heaps",
      action="store_true",
      help="Collect allocations from all heaps registered by target.")
  parser.add_argument(
      "--no-android-tree-symbolization",
      action="store_true",
      help="Do not symbolize using currently lunched target in the "
      "Android tree.")
  parser.add_argument(
      "--disable-selinux",
      action="store_true",
      help="Disable SELinux enforcement for duration of "
      "profile.")
  parser.add_argument(
      "--no-versions",
      action="store_true",
      help="Do not get version information about APKs.")
  parser.add_argument(
      "--no-running",
      action="store_true",
      help="Do not target already running processes. Requires Android 11.")
  parser.add_argument(
      "--no-startup",
      action="store_true",
      help="Do not target processes that start during "
      "the profile. Requires Android 11.")
  parser.add_argument(
      "--shmem-size",
      help="Size of buffer between client and "
      "heapprofd. Default 8MiB. Needs to be a power of two "
      "multiple of 4096, at least 8192.",
      type=int,
      default=8 * 1048576)
  parser.add_argument(
      "--block-client",
      help="When buffer is full, block the "
      "client to wait for buffer space. Use with caution as "
      "this can significantly slow down the client. "
      "This is the default",
      action="store_true")
  parser.add_argument(
      "--block-client-timeout",
      help="If --block-client is given, do not block any allocation for "
      "longer than this timeout (us).",
      type=int)
  parser.add_argument(
      "--no-block-client",
      help="When buffer is full, stop the "
      "profile early.",
      action="store_true")
  parser.add_argument(
      "--idle-allocations",
      help="Keep track of how many "
      "bytes were unused since the last dump, per "
      "callstack",
      action="store_true")
  parser.add_argument(
      "--dump-at-max",
      help="Dump the maximum memory usage "
      "rather than at the time of the dump.",
      action="store_true")
  parser.add_argument(
      "--disable-fork-teardown",
      help="Do not tear down client in forks. This can be useful for programs "
      "that use vfork. Android 11+ only.",
      action="store_true")
  parser.add_argument(
      "--simpleperf",
      action="store_true",
      help="Get simpleperf profile of heapprofd. This is "
      "only for heapprofd development.")
  parser.add_argument(
      "--traceconv-binary", help="Path to local trace to text. For debugging.")
  parser.add_argument(
      "--no-annotations",
      help="Do not suffix the pprof function names with Android ART mode "
      "annotations such as [jit].",
      action="store_true")
  parser.add_argument(
      "--print-config",
      action="store_true",
      help="Print config instead of running. For debugging.")
  parser.add_argument(
      "-o",
      "--output",
      help="Output directory.",
      metavar="DIRECTORY",
      default=None)
  parser.add_argument(
      "--print-options", action="store_true", help=argparse.SUPPRESS)

  args = parser.parse_args()
  if args.print_options:
    print_options(parser)
    return 0
  fail = False
  if args.block_client and args.no_block_client:
    print(
        "FATAL: Both block-client and no-block-client given.", file=sys.stderr)
    fail = True
  if args.pid is None and args.name is None:
    print("FATAL: Neither PID nor NAME given.", file=sys.stderr)
    fail = True
  if args.duration is None:
    print("FATAL: No duration given.", file=sys.stderr)
    fail = True
  if args.interval is None:
    print("FATAL: No interval given.", file=sys.stderr)
    fail = True
  if args.shmem_size % 4096:
    print("FATAL: shmem-size is not a multiple of 4096.", file=sys.stderr)
    fail = True
  if args.shmem_size < 8192:
    print("FATAL: shmem-size is less than 8192.", file=sys.stderr)
    fail = True
  if args.shmem_size & (args.shmem_size - 1):
    print("FATAL: shmem-size is not a power of two.", file=sys.stderr)
    fail = True

  target_cfg = ""
  if not args.no_block_client:
    target_cfg += CFG_INDENT + "block_client: true\n"
  if args.block_client_timeout:
    target_cfg += (
        CFG_INDENT +
        "block_client_timeout_us: %s\n" % args.block_client_timeout)
  if args.no_startup:
    target_cfg += CFG_INDENT + "no_startup: true\n"
  if args.no_running:
    target_cfg += CFG_INDENT + "no_running: true\n"
  if args.dump_at_max:
    target_cfg += CFG_INDENT + "dump_at_max: true\n"
  if args.disable_fork_teardown:
    target_cfg += CFG_INDENT + "disable_fork_teardown: true\n"
  if args.all_heaps:
    target_cfg += CFG_INDENT + "all_heaps: true\n"
  if args.pid:
    for pid in args.pid.split(','):
      try:
        pid = int(pid)
      except ValueError:
        print("FATAL: invalid PID %s" % pid, file=sys.stderr)
        fail = True
      target_cfg += CFG_INDENT + 'pid: {}\n'.format(pid)
  if args.name:
    for name in args.name.split(','):
      target_cfg += CFG_INDENT + 'process_cmdline: "{}"\n'.format(name)
  if args.heaps:
    for heap in args.heaps.split(','):
      target_cfg += CFG_INDENT + 'heaps: "{}"\n'.format(heap)

  if fail:
    parser.print_help()
    return 1

  traceconv_binary = args.traceconv_binary

  if args.continuous_dump:
    target_cfg += CONTINUOUS_DUMP.format(dump_interval=args.continuous_dump)
  cfg = CFG.format(
      interval=args.interval,
      duration=args.duration,
      target_cfg=target_cfg,
      shmem_size=args.shmem_size)
  if not args.no_versions:
    cfg += PACKAGES_LIST_CFG

  if args.print_config:
    print(cfg)
    return 0

  # Do this AFTER print_config so we do not download traceconv only to
  # print out the config.
  if traceconv_binary is None:
    traceconv_binary = get_perfetto_prebuilt(TRACECONV_MANIFEST, soft_fail=True)

  known_issues = maybe_known_issues()
  if known_issues:
    print('If you are experiencing problems, please see the known issues for '
          'your release: {}.'.format(known_issues))

  # TODO(fmayer): Maybe feature detect whether we can remove traces instead of
  # this.
  uuid_trace = release_or_newer('R')
  if uuid_trace:
    profile_device_path = '/data/misc/perfetto-traces/profile-' + UUID
  else:
    user = subprocess.check_output(['adb', 'shell',
                                    'whoami']).decode('utf-8').strip()
    profile_device_path = '/data/misc/perfetto-traces/profile-' + user

  perfetto_cmd = ('CFG=\'{cfg}\'; echo ${{CFG}} | '
                  'perfetto --txt -c - -o ' + profile_device_path + ' -d')

  if args.disable_selinux:
    enforcing = subprocess.check_output(['adb', 'shell',
                                         'getenforce']).decode('utf-8').strip()
    atexit.register(
        subprocess.check_call,
        ['adb', 'shell', 'su root setenforce %s' % enforcing])
    subprocess.check_call(['adb', 'shell', 'su root setenforce 0'])

  if args.simpleperf:
    subprocess.check_call([
        'adb', 'shell', 'mkdir -p /data/local/tmp/heapprofd_profile && '
        'cd /data/local/tmp/heapprofd_profile &&'
        '(nohup simpleperf record -g -p $(pidof heapprofd) 2>&1 &) '
        '> /dev/null'
    ])

  profile_target = PROFILE_LOCAL_PATH
  if args.output is not None:
    profile_target = args.output
  else:
    os.mkdir(profile_target)

  if not os.path.isdir(profile_target):
    print(
        "Output directory {} not found".format(profile_target), file=sys.stderr)
    return 1

  if os.listdir(profile_target):
    print(
        "Output directory {} not empty".format(profile_target), file=sys.stderr)
    return 1

  perfetto_pid = subprocess.check_output(
      ['adb', 'exec-out', perfetto_cmd.format(cfg=cfg)]).strip()
  try:
    perfetto_pid = int(perfetto_pid.strip())
  except ValueError:
    print("Failed to invoke perfetto: {}".format(perfetto_pid), file=sys.stderr)
    return 1

  old_handler = signal.signal(signal.SIGINT, sigint_handler)
  print("Profiling active. Press Ctrl+C to terminate.")
  print("You may disconnect your device.")
  print()
  exists = True
  device_connected = True
  while not device_connected or (exists and not IS_INTERRUPTED):
    exists = subprocess.call(
        ['adb', 'shell', '[ -d /proc/{} ]'.format(perfetto_pid)], **NOOUT) == 0
    device_connected = subprocess.call(['adb', 'shell', 'true'], **NOOUT) == 0
    time.sleep(1)
  print("Waiting for profiler shutdown...")
  signal.signal(signal.SIGINT, old_handler)
  if IS_INTERRUPTED:
    # Not check_call because it could have existed in the meantime.
    subprocess.call(['adb', 'shell', 'kill', '-INT', str(perfetto_pid)])
  if args.simpleperf:
    subprocess.check_call(['adb', 'shell', 'killall', '-INT', 'simpleperf'])
    print("Waiting for simpleperf to exit.")
    while subprocess.call(
        ['adb', 'shell', '[ -f /proc/$(pidof simpleperf)/exe ]'], **NOOUT) == 0:
      time.sleep(1)
    subprocess.check_call(
        ['adb', 'pull', '/data/local/tmp/heapprofd_profile', profile_target])
    print("Pulled simpleperf profile to " + profile_target +
          "/heapprofd_profile")

  # Wait for perfetto cmd to return.
  while exists:
    exists = subprocess.call(
        ['adb', 'shell', '[ -d /proc/{} ]'.format(perfetto_pid)]) == 0
    time.sleep(1)

  profile_host_path = os.path.join(profile_target, 'raw-trace')
  subprocess.check_call(['adb', 'pull', profile_device_path, profile_host_path],
                        stdout=NULL)
  if uuid_trace:
    subprocess.check_call(['adb', 'shell', 'rm', profile_device_path],
                          stdout=NULL)

  if traceconv_binary is None:
    print('Wrote profile to {}'.format(profile_host_path))
    print(
        'This file can be opened using the Perfetto UI, https://ui.perfetto.dev'
    )
    return 0

  binary_path = os.getenv('PERFETTO_BINARY_PATH')
  if not args.no_android_tree_symbolization:
    product_out = os.getenv('ANDROID_PRODUCT_OUT')
    if product_out:
      product_out_symbols = product_out + '/symbols'
    else:
      product_out_symbols = None

    if binary_path is None:
      binary_path = product_out_symbols
    elif product_out_symbols is not None:
      binary_path += ":" + product_out_symbols

  trace_file = os.path.join(profile_target, 'raw-trace')
  concat_files = [trace_file]

  if binary_path is not None:
    with open(os.path.join(profile_target, 'symbols'), 'w') as fd:
      ret = subprocess.call([
          traceconv_binary, 'symbolize',
          os.path.join(profile_target, 'raw-trace')
      ],
                            env=dict(
                                os.environ, PERFETTO_BINARY_PATH=binary_path),
                            stdout=fd)
    if ret == 0:
      concat_files.append(os.path.join(profile_target, 'symbols'))
    else:
      print("Failed to symbolize. Continuing without symbols.", file=sys.stderr)

  proguard_map = os.getenv('PERFETTO_PROGUARD_MAP')
  if proguard_map is not None:
    with open(os.path.join(profile_target, 'deobfuscation-packets'), 'w') as fd:
      ret = subprocess.call([
          traceconv_binary, 'deobfuscate',
          os.path.join(profile_target, 'raw-trace')
      ],
                            env=dict(
                                os.environ, PERFETTO_PROGUARD_MAP=proguard_map),
                            stdout=fd)
    if ret == 0:
      concat_files.append(os.path.join(profile_target, 'deobfuscation-packets'))
    else:
      print(
          "Failed to deobfuscate. Continuing without deobfuscated.",
          file=sys.stderr)

  if len(concat_files) > 1:
    with open(os.path.join(profile_target, 'symbolized-trace'), 'wb') as out:
      for fn in concat_files:
        with open(fn, 'rb') as inp:
          while True:
            buf = inp.read(4096)
            if not buf:
              break
            out.write(buf)
    trace_file = os.path.join(profile_target, 'symbolized-trace')

  conversion_args = [traceconv_binary, 'profile'] + (
      ['--no-annotations'] if args.no_annotations else []) + [trace_file]
  traceconv_output = subprocess.check_output(conversion_args)
  profile_path = None
  for word in traceconv_output.decode('utf-8').split():
    if 'heap_profile-' in word:
      profile_path = word
  if profile_path is None:
    print_no_profile_error()
    return 1

  profile_files = os.listdir(profile_path)
  if not profile_files:
    print_no_profile_error()
    return 1

  for profile_file in profile_files:
    shutil.copy(os.path.join(profile_path, profile_file), profile_target)

  symlink_path = None
  if not sys.platform.startswith('win'):
    subprocess.check_call(
        ['gzip'] + [os.path.join(profile_target, x) for x in profile_files])
    if args.output is None:
      symlink_path = os.path.join(
          os.path.dirname(profile_target), "heap_profile-latest")
      if os.path.lexists(symlink_path):
        os.unlink(symlink_path)
      os.symlink(profile_target, symlink_path)

  if symlink_path is not None:
    print("Wrote profiles to {} (symlink {})".format(profile_target,
                                                     symlink_path))
  else:
    print("Wrote profiles to {}".format(profile_target))

  print("The raw-trace file can be viewed using https://ui.perfetto.dev.")
  print("The heap_dump.* files can be viewed using pprof/ (Googlers only) " +
        "or https://www.speedscope.app/.")
  print("The two above are equivalent. The raw-trace contains the union of " +
        "all the heap dumps.")


if __name__ == '__main__':
  sys.exit(main(sys.argv))
