blob: bedd70c8c3be15bd3e327ae162d380693291c325 [file] [log] [blame]
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from recipe_engine import recipe_api
class SymbolizeApi(recipe_api.RecipeApi):
"""Symbolizes logs."""
OUTPUT_JSON = 'symbolizer-output.json'
LOG = 'symbolized_log.txt'
def __call__(self,
symbolize_tool,
llvm_symbolizer,
data,
level='debug',
build_id_dirs=(),
debug_symbol_gcs_bucket=None,
symbolizer_output=None,
json_output=None,
presentation=None):
"""Invokes zircon's symbolization script to symbolize the given data.
Args:
symbolize_tool (Path): The path to the symbolize tool.
llvm_symbolizer (Path): The path to the llvm_symbolizer tool.
data (String): Step output.
level (String): Debug level passed to the symbolize tool.
build_id_dirs (seq(Path)): A list of build-id directories.
debug_symbol_gcs_bucket (str): A GCS bucket hosting debug symbols.
symbolizer_output (Path): The path to save the symbolizer stdout to.
json_output (Path): The path to save the symbolizer json trigger
information to.
presentation (StepPresentation or None): The step presentation to add the
symbolized logs to.
Returns:
Symbolizer output, split into lines.
"""
assert build_id_dirs or debug_symbol_gcs_bucket,\
'one of a build-id directory or debug_symbol_gcs_bucket must be supplied'
presentation = presentation or self.m.step.active_result.presentation
# Value of llvm-symbolizer-restart-interval chosen to avoid running out of
# memory on 1-core GCE VMs.
# TODO(42018): Remove restart flag when fixed.
symbolize_cmd = [symbolize_tool, '-llvm-symbolizer-restart-interval', '2']
if level:
symbolize_cmd.extend(['-level', level])
for build_id_dir in build_id_dirs:
symbolize_cmd.extend(['-build-id-dir', build_id_dir])
if debug_symbol_gcs_bucket:
# The symbolize tool accepts a "symbol-server" argument which
# in reality is a GCS bucket hosting debug symbols indexed by build ID.
symbolize_cmd.extend(['-symbol-server', debug_symbol_gcs_bucket])
symbolize_cmd.extend(
['-symbol-cache', self.m.path['cache'].join('symbol')])
symbolize_cmd.extend(['-llvm-symbolizer', llvm_symbolizer])
if json_output:
# We intentionally avoid using a json output placeholder here because
# doing so would require loading the entire (possibly massive) symbolizer
# output json into memory, which can cause OOMs.
symbolize_cmd.extend(['-json-output', json_output])
symbolize_result = self.m.step(
'symbolize logs',
symbolize_cmd,
stdin=self.m.raw_io.input(data=data),
stdout=self.m.raw_io.output(leak_to=symbolizer_output, name=self.LOG),
step_test_data=lambda: self.m.raw_io.test_api.stream_output(
'blah\nblah\n'),
infra_step=True)
symbolized_lines = symbolize_result.stdout.splitlines()
if symbolized_lines:
presentation.logs['symbolized log'] = symbolized_lines
return symbolized_lines