From 4e6ce2d27a0cd6d3b95b6b1920001143c4fd9a72 Mon Sep 17 00:00:00 2001 From: Vlad Zolotarov Date: Wed, 8 Jan 2025 16:41:23 -0500 Subject: [PATCH] scripts/addr2line.py: fix hanging with the new llvm-addr2line version addr2line.py invokes "addr2line" tool in a "server" mode where addresses are fed via stdin. It intentionally makes a corresponding "addr2line" tool generate a known "invalid address" pattern at the end of each address decoding by feeding it a "0x0" address in order to denote the end of it because a single address can be decoded into multiple lines due to inlining. The above strategy assumes that 0x0 address is always going to be interpreted as an invalid one by both add2line and by llvm-addr2line. However, at least llvm-addr2line 18.1.3 doesn't always interpret it this way. On the other hand an empty line does always generate an expected (invalid address) output. On top of that it looks like a new llvm-addr2line changed the "invalid address" pattern format. This patch adds a new "invalid input" pattern to a dummy_pattern and changes the way we generate such an output by pushing line that only has a ',' charachter instead of a 0x0 address. Ref #2609 Closes scylladb/seastar#2611 --- scripts/addr2line.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/addr2line.py b/scripts/addr2line.py index 659edb56aef..d9f8403678f 100755 --- a/scripts/addr2line.py +++ b/scripts/addr2line.py @@ -54,7 +54,9 @@ class Addr2Line: dummy_pattern = re.compile( r"(.*0x0000000000000000: \?\? \?\?:0\n)" # addr2line pattern r"|" - r"(.*0x0: \?\? at .*\n)" # llvm-addr2line pattern + r"(\?\? at \?\?:0\n)" # llvm-addr2line pattern for LLVM 18 and newer + r"|" + r"(,\n)" # llvm-addr2line pattern for LLVM 17 and older ) def __init__( @@ -97,7 +99,7 @@ def __init__( # will just exit. We need to be robust against that. We # can't just wait on self._addr2line since there is no # guarantee on what timeout is sufficient. - self._input.write('\n') + self._input.write(',\n') self._input.flush() res = self._output.readline() self._missing = res == '' @@ -129,9 +131,9 @@ def _read_resolved_address(self): def __call__(self, address: str): if self._missing: return " ".join([self._binary, address, '\n']) - # We print a dummy 0x0 address after the address we are interested in + # We trigger a dummy "invalid" address printout after the address we are interested in # which we can look for in _read_address - inputline = address + '\n0x0\n' + inputline = address + '\n,\n' self._parent.debug('Add2Line sending input to stdin:', inputline) self._input.write(inputline) self._input.flush()