| # 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" |
| |
| def __call__( |
| self, |
| symbolizer_tool, |
| data, |
| name="symbolize logs", |
| build_id_dirs=(), |
| debug_symbol_url=None, |
| symbolizer_output=None, |
| json_output=None, |
| ): |
| """Invokes zircon's symbolization script to symbolize the given data. |
| |
| Args: |
| symbolizer_tool (Path): The path to the symbolizer tool. |
| data (String): Step output. |
| build_id_dirs (seq(Path)): A list of build-id directories. |
| debug_symbol_url (str): A GCS URL 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. |
| |
| Returns: |
| Symbolizer output, split into lines. |
| """ |
| assert ( |
| build_id_dirs or debug_symbol_url |
| ), "one of a build-id directory or debug_symbol_url must be supplied" |
| |
| symbolizer_cmd = [symbolizer_tool] |
| |
| for build_id_dir in build_id_dirs: |
| symbolizer_cmd.extend(["--build-id-dir", build_id_dir]) |
| if debug_symbol_url: |
| # The symbolize tool accepts a "symbol-server" argument which |
| # in reality is a GCS URL hosting debug symbols indexed by build ID. |
| symbolizer_cmd.extend(["--symbol-server", debug_symbol_url]) |
| symbolizer_cmd.extend( |
| ["--symbol-cache", self.m.path["cache"].join("symbol")] |
| ) |
| |
| 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. |
| symbolizer_cmd.extend(["--dumpfile-output", json_output]) |
| |
| try: |
| return self.m.step( |
| name, |
| symbolizer_cmd, |
| stdin=self.m.raw_io.input(data=data), |
| stdout=self.m.raw_io.output(leak_to=symbolizer_output), |
| step_test_data=lambda: self.m.raw_io.test_api.stream_output(data), |
| infra_step=True, |
| ).stdout |
| except self.m.step.StepFailure: |
| step = self.m.step.active_result |
| # Log stdin and stdout for easier debugging. |
| step.presentation.logs["stdin"] = data.splitlines() |
| # We could use the `add_output_log` arg to raw_io.output() to add |
| # this log, but it results in a less concise log name, and isn't |
| # supported for input placeholders, so stdout and stdin would be |
| # logged in different ways. |
| step.presentation.logs["stdout"] = step.stdout.splitlines() |
| raise |