diff --git a/common/util.py b/common/util.py index b5e5538..b050542 100644 --- a/common/util.py +++ b/common/util.py @@ -1,6 +1,7 @@ """Utility functions.""" import os +import re import shutil from argparse import ArgumentTypeError from collections.abc import Callable @@ -490,3 +491,29 @@ def find_darwin_heap_regions(process: SBProcess) -> Union[list[tuple[int, int]], return None return heap_regions + + +def parse_llvm_version_string(version: str) -> Union[list[int], None]: + """ + Parse the version string for an LLDB version built from the official LLVM sources + (e.g. 'lldb version 16.0.0'). + + :param version: The version string to parse. + :return: A list of integers representing the version, or None if parsing failed. + """ + if match := re.search(r"lldb version\s+([\d.]+)", version): + return [int(x) for x in match.group(1).split(".")] + return None + + +def parse_apple_clang_version_string(version: str) -> Union[list[int], None]: + """ + Parse the version string for an LLDB version shipped with Apple Clang + (e.g. 'lldb-1600.0.36.3'). + + :param version: The version string to parse. + :return: A list of integers representing the version, or None if parsing failed. + """ + if match := re.search(r"lldb-(\d+[\d.]+)", version): + return [int(x) for x in match.group(1).split(".")] + return None diff --git a/llef.py b/llef.py index 34e32d1..3a3840a 100644 --- a/llef.py +++ b/llef.py @@ -35,6 +35,7 @@ from commands.settings import SettingsCommand from commands.xinfo import XinfoCommand from common.state import LLEFState +from common.util import lldb_version_to_clang, parse_apple_clang_version_string, parse_llvm_version_string from handlers.stop_hook import StopHookHandler @@ -69,8 +70,19 @@ def __lldb_init_module(debugger: SBDebugger, _: dict[Any, Any]) -> None: LLEFState.platform = platform.system() if LLEFState.platform == "Darwin": - # Getting Clang version (e.g. lldb-1600.0.36.3) - LLEFState.version = [int(x) for x in debugger.GetVersionString().split()[0].split("-")[1].split(".")] + # On Darwin, we have two possibilities: + # - LLDB shipped with Apple Clang + # - LLDB built from the LLVM sources + # Those have different versioning schemes, and they need to be normalized to the Apple Clang version + # to adhere to the assumptions taken in other places regarding LLDB on Darwin. + if version := parse_apple_clang_version_string(debugger.GetVersionString()): + LLEFState.version = version + elif version := parse_llvm_version_string(debugger.GetVersionString()): + LLEFState.version = lldb_version_to_clang(version) + else: + raise ValueError(f"Unable to parse LLDB version string: {debugger.GetVersionString()}") else: - # Getting LLDB version (e.g. lldb version 16.0.0) - LLEFState.version = [int(x) for x in debugger.GetVersionString().split("version")[1].split()[0].split(".")] + if version := parse_llvm_version_string(debugger.GetVersionString()): + LLEFState.version = version + else: + raise ValueError(f"Unable to parse LLDB version string: {debugger.GetVersionString()}")