From b311b11e60e62b2bdd2868de356a3236ea042f27 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Wed, 28 Feb 2024 15:04:12 -0800 Subject: [PATCH] Fix addr2line detection Summary: Detection and running did not correctly deal with `addr2line` from `PATH`. Reviewed By: ssj933 Differential Revision: D54259734 fbshipit-source-id: 056a22dbe0dec8180f4333fe0be668028ac6606f --- pyredex/bintools.py | 58 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/pyredex/bintools.py b/pyredex/bintools.py index 42e7c4272fc..17f40043013 100755 --- a/pyredex/bintools.py +++ b/pyredex/bintools.py @@ -10,6 +10,7 @@ import enum import itertools +import logging import os import platform import re @@ -73,19 +74,51 @@ def _has_addr2line() -> bool: try: global ADDR2LINE_PATH path = ADDR2LINE_PATH - if path: - if os.path.exists(path) or shutil.which(path): - return True - subprocess.check_call( - ["addr2line", "-v"], - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - ) - ADDR2LINE_PATH = "addr2line" - return True + def _try_run(cmd: typing.Optional[str]) -> typing.Optional[str]: + if not cmd: + return None + + # Try directly. Only if it exists as path. + if os.path.exists(cmd): + cmd = os.path.abspath(cmd) + try: + subprocess.check_call( + [cmd, "-v"], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + logging.info("Found addr2line at %s", cmd) + return cmd + except Exception: + pass + + # Try as PATH reference. + cmd = shutil.which(cmd) + if cmd: + cmd = os.path.abspath(cmd) + try: + subprocess.check_call( + [cmd, "-v"], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + logging.info("Found addr2line at %s from `which`", cmd) + return cmd + except Exception: + pass + + return None + + path = _try_run(path) or _try_run("addr2line") + + if path: + ADDR2LINE_PATH = path + return True except (subprocess.CalledProcessError, FileNotFoundError): - return False + pass + + return False _ADDR2LINE_BASE_ARGS = ["-f", "-i", "-C", "-e"] @@ -96,8 +129,7 @@ def _symbolize(filename: str, offset: str) -> typing.List[str]: try: path = ADDR2LINE_PATH assert path - - path = os.path.abspath(path) + assert os.path.isabs(path) output = subprocess.check_output( [path] + _ADDR2LINE_BASE_ARGS + [filename, offset]