Skip to content

fix(dwarf): handle origin-backed inline address selection #2

fix(dwarf): handle origin-backed inline address selection

fix(dwarf): handle origin-backed inline address selection #2

name: Container Multiple Trace Diagnose
on:
workflow_dispatch:
pull_request:
branches: [ main ]
permissions:
contents: read
jobs:
host-to-private-multiple-trace-diagnose:
name: Container Diagnose (host-to-private multiple-trace-targets)
runs-on: ubuntu-22.04
timeout-minutes: 45
env:
LLVM_SYS_181_PREFIX: /usr/lib/llvm-18
FIXTURE_BINARY: ghostscope/tests/fixtures/sample_program/sample_program_o2
E2E_CONTAINER_IMAGE: ghcr.io/swananan/ghostscope-e2e-runtime@sha256:d5df1b977c38f7a51bbf28b878f2246705a05b83ac6df7cb6be8f8a4de4105f4
E2E_CHILD_CONTAINER_IMAGE: ghcr.io/swananan/ghostscope-e2e-runtime@sha256:d5df1b977c38f7a51bbf28b878f2246705a05b83ac6df7cb6be8f8a4de4105f4
E2E_SANDBOX_SESSION: container-mtt-diagnose-${{ github.run_id }}-${{ github.run_attempt }}
E2E_GHOSTSCOPE_SANDBOX: host
E2E_TARGET_SANDBOX: docker-private
E2E_TARGET_MODE: same
E2E_GHOSTSCOPE_LOG_LEVEL: trace
E2E_GHOSTSCOPE_ENABLE_LOGGING: 1
E2E_GHOSTSCOPE_LOG_CONSOLE: 1
RUST_BACKTRACE: full
RUST_LOG: trace
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install LLVM 18 and Polly
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 18
sudo apt-get install -y llvm-18-dev libpolly-18-dev
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@1.88.0
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-registry-
- name: Cache cargo index
uses: actions/cache@v4
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-index-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: target
key: ${{ runner.os }}-${{ github.job }}-target-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ github.job }}-target-
- name: Build Diagnostic Tools And Fixture
shell: bash
run: |
set -euxo pipefail
cargo build -p dwarf-tool
make -C ghostscope/tests/fixtures/sample_program clean sample_program_o2
- name: Dump DWARF And Disassembly Diagnostics
shell: bash
run: |
set -euxo pipefail
mkdir -p /tmp/mtt-diagnose
fixture="$GITHUB_WORKSPACE/$FIXTURE_BINARY"
./target/debug/dwarf-tool -t "$fixture" function calculate_something --quiet --json \
| tee /tmp/mtt-diagnose/function-calculate_something.json
./target/debug/dwarf-tool -t "$fixture" source-line sample_program.c:16 --quiet --json \
| tee /tmp/mtt-diagnose/source-line-sample_program.c-16.json
dwarfdump_bin="$(command -v llvm-dwarfdump-18 || command -v llvm-dwarfdump)"
"$dwarfdump_bin" --name=calculate_something "$fixture" \
| tee /tmp/mtt-diagnose/llvm-dwarfdump-name-calculate_something.txt
readelf --debug-dump=info --wide "$fixture" \
| grep -n -E -C 6 'calculate_something|DW_TAG_subprogram|DW_TAG_inlined_subroutine|DW_AT_entry_pc|DW_AT_ranges|DW_AT_abstract_origin' \
| tee /tmp/mtt-diagnose/readelf-debug-info-snippet.txt || true
readelf --debug-dump=loc --wide "$fixture" \
> /tmp/mtt-diagnose/readelf-debug-loc.txt
objdump -d --no-show-raw-insn "$fixture" \
| tee /tmp/mtt-diagnose/objdump-disassembly.txt >/dev/null
python - <<'PY'
import json
import os
import pathlib
import subprocess
out_dir = pathlib.Path("/tmp/mtt-diagnose")
fixture = pathlib.Path(os.environ["GITHUB_WORKSPACE"]) / os.environ["FIXTURE_BINARY"]
def load_json_payload(path: pathlib.Path):
raw = path.read_text()
start = raw.find("{")
if start == -1:
raise RuntimeError(f"No JSON object found in {path}")
return json.loads(raw[start:])
def collect_addresses(path: pathlib.Path):
data = load_json_payload(path)
addrs = set()
for module in data.get("modules", []):
for entry in module.get("addresses", []):
addr_text = entry.get("address")
if addr_text:
addrs.add(int(addr_text, 16))
for entry in data.get("addresses", []):
addr_text = entry.get("address")
if addr_text:
addrs.add(int(addr_text, 16))
return sorted(addrs)
addresses = sorted(
set(collect_addresses(out_dir / "function-calculate_something.json"))
| set(collect_addresses(out_dir / "source-line-sample_program.c-16.json"))
)
(out_dir / "resolved-addresses.txt").write_text(
"".join(f"0x{addr:x}\n" for addr in addresses)
)
for addr in addresses:
start = max(0, addr - 16)
stop = addr + 32
disasm = subprocess.check_output(
[
"objdump",
"-d",
"--start-address",
hex(start),
"--stop-address",
hex(stop),
str(fixture),
],
text=True,
)
(out_dir / f"objdump-window-0x{addr:x}.txt").write_text(disasm)
PY
- name: Run Single Container Multiple Trace Test
shell: bash
run: |
set -euxo pipefail
sudo -E env \
E2E_CONTAINER_IMAGE="$E2E_CONTAINER_IMAGE" \
E2E_CHILD_CONTAINER_IMAGE="$E2E_CHILD_CONTAINER_IMAGE" \
E2E_SANDBOX_SESSION="$E2E_SANDBOX_SESSION" \
E2E_GHOSTSCOPE_SANDBOX="$E2E_GHOSTSCOPE_SANDBOX" \
E2E_TARGET_SANDBOX="$E2E_TARGET_SANDBOX" \
E2E_TARGET_MODE="$E2E_TARGET_MODE" \
E2E_GHOSTSCOPE_LOG_LEVEL="$E2E_GHOSTSCOPE_LOG_LEVEL" \
E2E_GHOSTSCOPE_ENABLE_LOGGING="$E2E_GHOSTSCOPE_ENABLE_LOGGING" \
E2E_GHOSTSCOPE_LOG_CONSOLE="$E2E_GHOSTSCOPE_LOG_CONSOLE" \
RUST_BACKTRACE="$RUST_BACKTRACE" \
RUST_LOG="$RUST_LOG" \
"$(which cargo)" test -p ghostscope --test script_execution test_multiple_trace_targets -- --nocapture \
2>&1 | tee /tmp/mtt-diagnose/test-multiple-trace-targets.log
- name: Collect Runtime Logs
if: always()
shell: bash
run: |
set -euxo pipefail
mkdir -p /tmp/mtt-diagnose
if [ -f ghostscope.log ]; then
cp ghostscope.log /tmp/mtt-diagnose/ghostscope.log
fi
if [ -f g.log ]; then
cp g.log /tmp/mtt-diagnose/g.log
fi
find /tmp/mtt-diagnose -maxdepth 1 -type f | sort > /tmp/mtt-diagnose/manifest.txt
- name: Upload Diagnostic Artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: container-mtt-diagnose-${{ github.run_id }}-${{ github.run_attempt }}
path: /tmp/mtt-diagnose
- name: Cleanup Session Sandboxes
if: always()
run: |
ids=$(docker ps -aq --filter "label=ghostscope.session=$E2E_SANDBOX_SESSION")
if [ -n "$ids" ]; then
docker rm -f $ids
fi