CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
95 lines
3.8 KiB
Python
95 lines
3.8 KiB
Python
# DExTer : Debugging Experience Tester
|
|
# ~~~~~~ ~ ~~ ~ ~~
|
|
#
|
|
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
# See https://llvm.org/LICENSE.txt for license information.
|
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
"""Utilities for matching debugger state, such as the call stack, conditions, or historical state (e.g. breakpoint
|
|
hitcounts) to descriptions of expected state in a DexterScript."""
|
|
|
|
import os
|
|
from typing import Dict, List, Tuple
|
|
|
|
from dex.dextIR import FrameIR, StepIR
|
|
from dex.test_script import DexterScript, Scope
|
|
from dex.test_script.Nodes import Expect, Value, Where
|
|
|
|
|
|
def is_subpath(subpath: str, superpath: str) -> bool:
|
|
"""Returns True if subpath is a trailing subpath of superpath, i.e. if `superpath` ends with `subpath` after
|
|
normalizing both paths."""
|
|
normalized_subpath: str = os.path.normcase(os.path.normpath(subpath))
|
|
normalized_superpath: str = os.path.normcase(os.path.normpath(superpath))
|
|
return normalized_superpath.endswith(normalized_subpath)
|
|
|
|
|
|
# A very simple matcher, returns True iff `where` matches `frame`.
|
|
def match_where_to_frame(
|
|
where: Where,
|
|
frame: FrameIR,
|
|
) -> bool:
|
|
"""A very simple matcher, returns True iff `where` matches `frame`."""
|
|
if where.file is not None and not is_subpath(where.file, frame.loc.path):
|
|
return False
|
|
if where.function is not None:
|
|
fn = frame.function
|
|
if "(" in fn:
|
|
fn = fn.split("(")[0]
|
|
if where.function != fn:
|
|
return False
|
|
if where.lines is not None:
|
|
if frame.loc.lineno not in where.get_lines():
|
|
return False
|
|
if (
|
|
where.for_hit_count is not None
|
|
or where.after_hit_count is not None
|
|
or where.conditions is not None
|
|
):
|
|
raise NotImplementedError(
|
|
"!where hit counts and conditions currently unsupported."
|
|
)
|
|
return True
|
|
|
|
|
|
def get_active_where_expects(
|
|
script: DexterScript, step_info: StepIR
|
|
) -> Dict[Where, Tuple[int, List[Value]]]:
|
|
"""Match the script against the step_info, producing a dict that maps each !where that matches a stack frame to the
|
|
index of the (rootmost) stack frame that it matches, and if the frame that it matches is the current stack frame
|
|
(i.e. the frame index is 0), also includes a list of every direct child !expect node for that !where.
|
|
"""
|
|
active_where_expects: Dict[Where, Tuple[int, List[Value]]] = {}
|
|
|
|
def get_active_wheres(where: Where, scope: Scope):
|
|
if scope.where:
|
|
raise NotImplementedError(
|
|
"Support for nested !where nodes currently unimplemented."
|
|
)
|
|
# For this !where, search for the rootmost stack frame that matches it.
|
|
matching_frame_idx = next(
|
|
(
|
|
frame_idx
|
|
for frame_idx, frame in reversed(list(enumerate(step_info.frames)))
|
|
if match_where_to_frame(where, frame)
|
|
),
|
|
None,
|
|
)
|
|
if matching_frame_idx is not None:
|
|
active_where_expects[where] = (matching_frame_idx, [])
|
|
|
|
# As we visit the script nodes in pre-order traversal, we can always assume that an expect's parent !where
|
|
# has already been visited, and thus should have an entry in active_where_expects if it is active.
|
|
def get_active_expects(expect: Expect, expected_value, scope: Scope):
|
|
assert isinstance(
|
|
expect, Value
|
|
), "Values should be the only type of expect possible!"
|
|
if (
|
|
scope.where in active_where_expects
|
|
and active_where_expects[scope.where][0] == 0
|
|
):
|
|
active_where_expects[scope.where][1].append(expect)
|
|
|
|
script.visit_script(visit_where=get_active_wheres, visit_expect=get_active_expects)
|
|
|
|
return active_where_expects
|