Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions apps/OScope-harness/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# OScope-harness

`OScope-harness` is packaged as a thin TGOSKits entrypoint. The harness source is not vendored in this repository; `prebuild.sh` clones `cg24-THU/tgoskit-harness_kit` at commit `762c22725024a065e85b26e0b01121eccea651c0` and reuses that checkout from `target/tgoskit-harness-kit/`.

## CLI

From the TGOSKits repository root:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

此文件与 dev 存在 add/add 冲突。dev 已合并 app-only 版本 README。本 PR 是合并版,应保留本 PR 版本。请 merge 最新 dev 解决。

```bash
python3 apps/OScope-harness/harness.py doctor --no-docker
python3 apps/OScope-harness/harness.py discover --no-docker --arch riscv64
python3 apps/OScope-harness/harness.py perf-profile --no-docker --arch riscv64 --timeout 20 --format all
python3 apps/OScope-harness/harness.py ui --no-docker --host 127.0.0.1 --port 8765 --open
```

The wrapper keeps the original OScope command surface while the implementation stays in the fixed external harness kit commit.
This package also wires the Starry qperf runtime into `cargo xtask starry perf`
so profiling commands can run through the app wrapper.

## qperf Smoke

```bash
apps/OScope-harness/scripts/qperf-smoke.sh boot

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个文档化 smoke 在当前 head 上还不能作为可复现验证。我本地运行 apps/OScope-harness/scripts/qperf-smoke.sh boot 时,pinned harness checkout 成功后进入 cargo xtask starry perf --timeout 20 --case boot,但立即失败于缺少 riscv64-linux-musl-gcc,且本机没有 zig fallback:StarryOS qperf riscv64 build requires ...。新增 app/tool workflow 需要把必需 host 依赖写进文档并提供 preflight,或调整默认 smoke 到 CI/普通开发环境可运行的路径;否则这个 PR 只证明了 wrapper 存在,不能证明 qperf smoke 可用。

```

qperf smoke commands use the enhanced Starry runtime added here, including
`--case`, marker, and shell-init support:

```bash
apps/OScope-harness/scripts/qperf-smoke.sh boot
```

## MCP

Example MCP server configuration:

```json
{
"mcpServers": {
"OScope-harness": {
"command": "python3",
"args": [
"/path/to/tgoskits/apps/OScope-harness/mcp_server.py",
"--repo",
"/path/to/tgoskits"
]
}
}
}
```
28 changes: 28 additions & 0 deletions apps/OScope-harness/harness.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
from pathlib import Path


def harness_kit_checkout() -> Path:
prebuild = Path(__file__).resolve().with_name("prebuild.sh")
result = subprocess.run(
[str(prebuild)],
check=True,
text=True,
stdout=subprocess.PIPE,
)
lines = [line.strip() for line in result.stdout.splitlines() if line.strip()]
if not lines:
raise SystemExit(f"{prebuild} did not print a harness kit checkout path")
return Path(lines[-1])


def main() -> None:
target = harness_kit_checkout() / "tools/starry-syscall-harness/harness.py"
os.execv(sys.executable, [sys.executable, str(target), *sys.argv[1:]])


if __name__ == "__main__":
main()
28 changes: 28 additions & 0 deletions apps/OScope-harness/mcp_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
from pathlib import Path


def harness_kit_checkout() -> Path:
prebuild = Path(__file__).resolve().with_name("prebuild.sh")
result = subprocess.run(
[str(prebuild)],
check=True,
text=True,
stdout=subprocess.PIPE,
)
lines = [line.strip() for line in result.stdout.splitlines() if line.strip()]
if not lines:
raise SystemExit(f"{prebuild} did not print a harness kit checkout path")
return Path(lines[-1])


def main() -> None:
target = harness_kit_checkout() / "tools/starry-syscall-harness/mcp_server.py"
os.execv(sys.executable, [sys.executable, str(target), *sys.argv[1:]])


if __name__ == "__main__":
main()
5 changes: 5 additions & 0 deletions apps/OScope-harness/prebuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$script_dir/../common/prebuild-harness-kit.sh" "$@"
22 changes: 22 additions & 0 deletions apps/OScope-harness/scripts/qperf-smoke.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
workspace="${STARRY_WORKSPACE:-}"
if [[ -z "$workspace" ]]; then
workspace="$(git -C "$script_dir" rev-parse --show-toplevel 2>/dev/null || pwd)"
fi

if ! grep -q "pub case:" "$workspace/scripts/axbuild/src/starry/mod.rs" 2>/dev/null; then
cat >&2 <<'EOF'
error: qperf smoke requires the enhanced Starry qperf runtime.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

此文件与 dev 存在 add/add 冲突。dev 的错误信息引用 runtime companion,本 PR 是合并版应保留。请 merge 最新 dev 时取 PR 版本。

The current checkout does not expose the `cargo xtask starry perf --case`
runtime interface needed by the OScope-harness qperf smoke wrapper.
EOF
exit 1
fi

checkout="$("$script_dir/../prebuild.sh")"

exec "$checkout/tools/starry-syscall-harness/scripts/qperf-smoke.sh" "$@"
96 changes: 96 additions & 0 deletions apps/common/prebuild-harness-kit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env bash
set -euo pipefail

HARNESS_KIT_REPO="https://github.com/cg24-THU/tgoskit-harness_kit.git"
HARNESS_KIT_COMMIT="762c22725024a065e85b26e0b01121eccea651c0"

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
workspace="${STARRY_WORKSPACE:-}"
if [[ -z "$workspace" ]]; then
workspace="$(git -C "$script_dir" rev-parse --show-toplevel 2>/dev/null || pwd)"
fi

override_checkout="${TGOSKIT_HARNESS_KIT_DIR:-}"
checkout="${override_checkout:-$workspace/target/tgoskit-harness-kit/$HARNESS_KIT_COMMIT}"
tmp_checkout="$checkout.tmp.$$"

cleanup() {
rm -rf "$tmp_checkout"
}
trap cleanup EXIT

is_git_checkout() {
git -C "$1" rev-parse --is-inside-work-tree >/dev/null 2>&1
}

require_file() {
local path="$1"
local file="$2"
if [[ ! -f "$path/$file" ]]; then
echo "error: missing $file in $path" >&2
exit 1
fi
}

validate_checkout() {
local path="$1"
local label="$2"

require_file "$path" "tools/qperf/Cargo.toml"
require_file "$path" "tools/qperf/analyzer/Cargo.toml"
require_file "$path" "tools/starry-syscall-harness/harness.py"

if ! is_git_checkout "$path"; then
echo "error: $label is not a git checkout; cannot verify pinned harness kit commit $HARNESS_KIT_COMMIT" >&2
exit 1
fi

actual="$(git -C "$path" rev-parse HEAD)"
if [[ "$actual" != "$HARNESS_KIT_COMMIT" ]]; then
echo "error: $label is at commit $actual, expected $HARNESS_KIT_COMMIT" >&2
if [[ -n "$override_checkout" ]]; then
echo "error: TGOSKIT_HARNESS_KIT_DIR is read-only and will not be fetched, reset, or replaced" >&2
fi
exit 1
fi
}

ensure_checkout() {
if [[ -n "$override_checkout" ]]; then
validate_checkout "$checkout" "TGOSKIT_HARNESS_KIT_DIR=$checkout"
return
fi

if ! is_git_checkout "$checkout"; then
mkdir -p "$(dirname "$checkout")"
git init -q "$tmp_checkout"
git -C "$tmp_checkout" remote add origin "$HARNESS_KIT_REPO"
git -C "$tmp_checkout" fetch --depth 1 origin "$HARNESS_KIT_COMMIT"
git -C "$tmp_checkout" checkout --detach FETCH_HEAD >/dev/null
actual="$(git -C "$tmp_checkout" rev-parse HEAD)"
if [[ "$actual" != "$HARNESS_KIT_COMMIT" ]]; then
echo "error: fetched $actual, expected $HARNESS_KIT_COMMIT" >&2
exit 1
fi
rm -rf "$checkout"
mv "$tmp_checkout" "$checkout"
else
actual="$(git -C "$checkout" rev-parse HEAD)"
if [[ "$actual" != "$HARNESS_KIT_COMMIT" ]]; then
git -C "$checkout" fetch --depth 1 origin "$HARNESS_KIT_COMMIT"
git -C "$checkout" checkout --detach "$HARNESS_KIT_COMMIT" >/dev/null
git -C "$checkout" reset --hard "$HARNESS_KIT_COMMIT" >/dev/null
fi
fi

validate_checkout "$checkout" "$checkout"
}

ensure_checkout

if [[ $# -gt 0 ]]; then
cd "$checkout"
exec "$@"
fi

printf '%s\n' "$checkout"
18 changes: 18 additions & 0 deletions apps/qperf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# qperf

`qperf` is packaged as a thin TGOSKits entrypoint. The QEMU plugin and analyzer source is not vendored in this repository; `prebuild.sh` clones `cg24-THU/tgoskit-harness_kit` at commit `762c22725024a065e85b26e0b01121eccea651c0` and reuses that checkout from `target/tgoskit-harness-kit/`.

Build the fixed qperf checkout:

```bash
apps/qperf/prebuild.sh cargo build --manifest-path tools/qperf/Cargo.toml --release
apps/qperf/prebuild.sh cargo build --manifest-path tools/qperf/analyzer/Cargo.toml --release --features flamegraph
```

Run the synthetic folded-stack demo:

```bash
apps/qperf/prebuild.sh python3 tools/qperf/examples/long_chain_flamegraph_demo.py --no-svg --output-dir target/qperf-long-chain-demo-smoke
```

Run `apps/qperf/prebuild.sh` without arguments to print the fixed checkout path.
5 changes: 5 additions & 0 deletions apps/qperf/prebuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$script_dir/../common/prebuild-harness-kit.sh" "$@"
Loading
Loading