mirror of
https://github.com/spoopyghosty0/frameport.git
synced 2026-10-24 20:02:18 +02:00
89 lines
7.3 KiB
Markdown
89 lines
7.3 KiB
Markdown
# Diagnostics and problem reports
|
||
|
||
Two ways users feed results back, both without a GitHub token:
|
||
|
||
- **Share working recipe…** (game menu, `frameport share-recipe <pkg>`): saves the recipe as a user catalog entry and
|
||
opens a prefilled issue from `.github/ISSUE_TEMPLATE/working-config.yml`. A maintainer checks it and adds the label
|
||
`catalog-accepted`. Then `.github/workflows/catalog-from-issue.yml` runs `scripts/catalog_from_issue.py`, which reads
|
||
only the YAML block, validates it, and writes `catalog/games/<pkg>.yaml`, and the workflow opens a PR.
|
||
- The PR step needs Settings → Actions → "Allow GitHub Actions to create and approve pull requests".
|
||
- Create the labels `working-config`, `catalog-accepted` and `bug` once.
|
||
- **Report a problem…** / **Collect logs** (game menu, Settings, the failure pop-up, `frameport diag report|collect`): writes
|
||
a redacted zip and opens a prefilled `bug-report.yml` issue.
|
||
- GitHub has no API for issue attachments, so the user drags the zip in (25 MB max; the bundle stays under 24 MB).
|
||
- Prefilled links are capped at about 7.5k characters. Free text is trimmed first; the recipe is never cut.
|
||
|
||
Code: `src/frameport/diag/` (`redact.py`, `bundle.py`, `issue.py`), agent command `collect_diag` (agent ≥ 21),
|
||
`Target.collect_diag`, `core/applog.py` (app log + saved job logs).
|
||
|
||
## Bundle layout (schema 1)
|
||
```
|
||
README.md what's where (for whoever opens it)
|
||
manifest.json versions (app, agent, tools, SteamOS build, Proton), games, warnings, redaction counts
|
||
app/app.log the app's log (<data>/logs/app.log, rotated 2 MB × 3)
|
||
app/jobs/*.log saved GUI job logs (<data>/logs/jobs, last 30): build, install, test, ...
|
||
app/settings.json library settings, catalog sources
|
||
app/display.json Flet/Flutter versions and last window state; on native Windows, display layout,
|
||
resolution, refresh rate, GPU driver metadata and up to 60 recent display/device
|
||
System event records (last 30 minutes; timestamps, providers and IDs only)
|
||
frame/info.json agent `info` (SteamOS build, Lepton, Proton, installed games, kernel keys)
|
||
frame/host.json OpenXR runtime + explicit layers, podman containers, containers.conf, uptime
|
||
frame/XRService-*.log the Frame's OpenXR runtime (SteamVR XRService) log, newest
|
||
games/<pkg>/entry.json library entry: analysis, recipe, build checks, installs, last_test (store text dropped)
|
||
games/<pkg>/recipe.yaml the recipe in catalog form; catalog-<origin>.yaml = the catalog entry it came from
|
||
games/<pkg>/triage.json newest local launch log re-triaged with the bundling app's signatures
|
||
games/<pkg>/logs/*.log launch-test logs kept on the PC (last 5)
|
||
games/<pkg>/package/ stand-in for the game files (no content):
|
||
apk_files.json every APK entry + size
|
||
AndroidManifest.xml decoded manifest
|
||
elf.json per lib/*.so: DT_NEEDED, ovr*/xr*/vrapi_/gl*/JNI exports + imports
|
||
files.json, pe.json Rift: file list; PE imports / delay imports of the exe and VR DLLs
|
||
games/<pkg>/target/ from the Frame (or the PC): launch.sh, settings.conf, deployment.json, launch.log,
|
||
launch-test.log (PC VR), lepton-steamlaunch-<appid>.log, logcat-{main,crash,system,...}.log,
|
||
ReviveInjector.txt / steam-<appid>.log / game-log-N.txt (PC VR), files.json (+ missing)
|
||
(game-log-N.txt: Unreal Saved/Logs + crash summaries, Unity Player.log / Player-prev.log /
|
||
output_log.txt + crash error.log from the Proton prefix, agent v67)
|
||
threads.txt (agent v79): saved while a Quest game runs (e.g. hangs), each thread's
|
||
state, CPU ms over 2 s, kernel wait and syscall, plus its TCP sockets (remote = loopback /
|
||
local / internet + port, no addresses); read once from /proc, the game isn't paused
|
||
games/<pkg>/target/shaders/ shader dumps (agent v72), when the game wrote any:
|
||
fp_vk_shaders/ adapter vk_shader_dump=1 (Vulkan shim): <size>_<sha256>.spv + index.txt
|
||
fp_spirv/ adapter zink_shader_dump=1 (OpenGL ES, shader-fix layer under Zink): <size>_<sha256>.spv
|
||
```
|
||
Each log keeps at most its last 4 MB (2 MB per file from the Frame). Shader dumps, SPIR-V unchanged (compiled game
|
||
shaders, not redacted): Vulkan (agent v74) every module the game's newest run (the last `# start` in `index.txt`)
|
||
created, last used first, each up to 4 MB and up to 30 MB in all, with that run's index lines, so a module created
|
||
well before a GPU hang comes along too (if the zip would pass 24 MB, the least recently used ones are left out
|
||
after the logs were cut); OpenGL ES (no index): the newest modules (by time written) up to 4 MB.
|
||
`index.txt` (Vulkan) lists every vkCreateShaderModule as
|
||
`<seq> <ms since the first module> <unix ms> <size>_<sha256>.spv new|known|again|failed`; match the unix time with
|
||
the kernel's `hangcheck detected gpu lockup` line (this-boot-kernel.txt). All modules stay in the game's storage on
|
||
the Frame (`Android/data/<pkg>/files/fp_vk_shaders/`, Files tab → the game's storage).
|
||
|
||
Display queries run only while collecting logs. The Windows event query has a five-second timeout and runs without
|
||
a console window; the result distinguishes no matching events from a failed or timed-out query. Window visibility,
|
||
focus and completed move/resize events are recorded in `app.log`, with UTC timestamps for comparison with Windows
|
||
events. There is no display polling loop or change to display settings. Empty System event results do not rule out
|
||
a rendering or monitor-link problem.
|
||
|
||
## Redaction
|
||
`diag/redact.py` runs on every file and on the issue text.
|
||
- **Exact values:** the data dir → `<data>`, home dirs → `<home>`, user names → `<user>`, PC and Frame host names and
|
||
saved Frame addresses → `<host>`, Steam account ids from the Frame's `info` and the PC's Steam → `<steam-id>`, the
|
||
folders holding the user's game dumps → `<source>`.
|
||
- **Patterns:** IPv4 addresses (first octet ≥ 10, so version numbers survive), IPv6, MAC, SteamID64, `userdata/<id>`,
|
||
email addresses (file names like `x@123.txt` excluded), and any `/home/<u>`, `/Users/<u>`, `C:\Users\<u>` or
|
||
`/mnt/c/Users/<u>`.
|
||
- **Kept:** generic accounts that identify no one: `steamos`, `steamuser` (Proton), `root`, `deck`.
|
||
|
||
## Debugging from a bundle (no game, no Frame, no GUI)
|
||
1. `frameport diag inspect <zip>` (`--json` for everything). It prints the versions and warnings, the last launch
|
||
test, and a fresh triage of the newest launch log with the current `catalog/triage.yaml`.
|
||
2. Match the findings and log lines against `docs/PLAYBOOK.md` (symptom → cause → fix) and `docs/FRAME_RUNTIME.md`.
|
||
3. Check the analysis in `entry.json` (engine, XR API, `extra`: missing ovr symbols, features, Unreal version) and
|
||
`package/elf.json` against the heuristics in CLAUDE.md. Compare `recipe.yaml` with catalog games that use the same
|
||
engine and API.
|
||
4. Compare `manifest.json → env.frame.build_id` with the build the docs describe: SteamOS updates change the runtime.
|
||
5. A new failure signature means adding a patch module, a `triage.yaml` signature, a PLAYBOOK row and a unit test (see
|
||
Conventions). Then `diag inspect` on the same zip should report it.
|