Skip to content

Commit b0b9c5d

Browse files
committed
fix: independent v0.1.1 review R1-R7 — rollback restores user INI, exclusive restore copies, random exclusive temps, real glibc floor via CArchive ELF parse, backup validation, doctor session scope, staged kit refresh
1 parent 143457d commit b0b9c5d

17 files changed

Lines changed: 764 additions & 97 deletions

‎.github/workflows/release.yml‎

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,50 @@ jobs:
7575
test ! -e "$SGAME/version.dll" && test ! -e "$SGAME/dlssg_sm86.ini"
7676
test -f "$SGAME/game.exe"
7777
echo "packaged binary smoke OK"
78-
- name: Measure glibc requirement (linux)
78+
- name: Measure real glibc floor (extract embedded ELF libs)
7979
if: matrix.platform == 'linux-x64'
8080
id: glibc
8181
shell: bash
8282
run: |
83-
# 全文件扫描(含 PyInstaller 内嵌 .so),避免只看外层启动器漏掉真实下限
84-
FLOOR=$(grep -ao 'GLIBC_[0-9.]*' "dist/${{ matrix.binary }}" | sort -Vu | tail -1 | cut -d_ -f2)
85-
echo "floor=$FLOOR" >> "$GITHUB_OUTPUT"
86-
echo "measured glibc symbol floor: $FLOOR"
83+
set -e
84+
python - <<'PY'
85+
# 单文件程序内嵌的 .so 是 zlib 压缩的,外层字符串扫描会漏报真实下限
86+
# (v0.1.1 独立复核 R4)。解包 CArchive、解析每个内嵌 ELF 的动态符号版本。
87+
import glob, os, re, subprocess, sys, tempfile
88+
from PyInstaller.archive.readers import CArchiveReader
89+
90+
app = "dist/dlss-combo"
91+
92+
def glibc_max(path):
93+
out = subprocess.run(
94+
["objdump", "-T", path], capture_output=True, text=True
95+
).stdout
96+
best = (0, 0)
97+
for m in re.finditer(r"GLIBC_(\d+)\.(\d+)", out):
98+
best = max(best, (int(m.group(1)), int(m.group(2))))
99+
return best
100+
101+
overall = glibc_max(app) # 外层启动器
102+
with tempfile.TemporaryDirectory() as td:
103+
reader = CArchiveReader(app)
104+
for name in list(reader.toc.keys()):
105+
try:
106+
reader.extract(name, td)
107+
except Exception:
108+
continue
109+
for p in glob.glob(os.path.join(td, "**"), recursive=True):
110+
if os.path.isfile(p):
111+
with open(p, "rb") as fh:
112+
if fh.read(4) == b"\x7fELF":
113+
overall = max(overall, glibc_max(p))
114+
if overall == (0, 0):
115+
sys.exit("no GLIBC version references found - measurement failed")
116+
floor = f"{overall[0]}.{overall[1]}"
117+
print("measured real glibc floor (CArchive-extracted ELF .gnu.version_r):", floor)
118+
with open("glibc_floor.txt", "w") as fh:
119+
fh.write(floor)
120+
PY
121+
echo "floor=$(cat glibc_floor.txt)" >> "$GITHUB_OUTPUT"
87122
- name: Write build info and quickstart into package
88123
shell: bash
89124
run: |
@@ -164,6 +199,10 @@ jobs:
164199
merge-multiple: true
165200
- name: Merge checksums
166201
run: cat dist-artifacts/SHA256SUMS-*.txt > dist-artifacts/SHA256SUMS.txt
202+
- name: Read measured glibc floor
203+
run: |
204+
FLOOR=$(grep -o 'GLIBC_[0-9.]*' dist-artifacts/build-info.txt | head -1 | cut -d_ -f2-)
205+
echo "GLIBC_FLOOR=${FLOOR:-unknown}" >> "$GITHUB_ENV"
167206
- name: Create GitHub Release (pre-release)
168207
uses: softprops/action-gh-release@v2
169208
with:
@@ -202,10 +241,10 @@ jobs:
202241
### Linux x86-64 — experimental
203242
204243
`dlss-combo-${{ github.ref_name }}-linux-x64.zip`. Built on Ubuntu
205-
22.04; the whole-binary GLIBC symbol floor is measured at build
206-
time and ships in `build-info.txt` (current build: 2.14). Other
207-
distros are unverified — glibc >= 2.17 (manylinux2014-era) is the
208-
conservative recommendation, or run from source. For Steam games, find the real game folder via
244+
22.04. The real glibc floor is measured at build time by extracting
245+
the embedded ELF libraries from the PyInstaller archive (outer-file
246+
string scans under-report); this build: **glibc >= ${{ env.GLIBC_FLOOR }}**
247+
(see `build-info.txt`). Other distros are unverified — or run from source. For Steam games, find the real game folder via
209248
Steam → Manage → *Browse local files*, then target the folder
210249
containing the rendering EXE. Proton launch options some setups
211250
use (`WINEDLLOVERRIDES="version=n,b" PROTON_ENABLE_NVAPI=1

‎CHANGELOG.md‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,41 @@ All notable changes to this project are documented here. The format follows
55
[SemVer](https://semver.org/) with a `0.x` experimental prefix. Evidence links
66
point to files in this repository (`docs/`) so the trail is auditable offline.
77

8+
## [0.1.2] — 2026-09-20
9+
10+
### Fixed (independent v0.1.1 review, R1–R7)
11+
12+
- **R1**: first-install failures now restore the user's original INI at every
13+
failure point (DLL copy, manifest write, backup write; reinstall failures
14+
restore the previous working state). Covered by fault-injection tests in
15+
`tests/test_review4.py`.
16+
- **R2**: uninstall never overwrites any existing file or symlink when saving
17+
a restore copy — copies are created exclusively (`O_CREAT|O_EXCL`) with
18+
numbered fallback names (`*.pre-existing.1`, …).
19+
- **R3**: temporary files use random, exclusively-created names
20+
(`tempfile.mkstemp`, same directory) — predictable-name symlink attacks are
21+
inert — and cleanup touches only paths registered by the current operation.
22+
- **R4**: the Linux glibc floor is now measured by extracting the embedded
23+
ELF libraries from the PyInstaller CArchive and parsing their
24+
`.gnu.version_r` requirements (outer-file string scans under-report);
25+
docs state the real floor (**glibc >= 2.35**, from the embedded
26+
libpython3.13) and the release notes read the measured value per build.
27+
- **R5**: a missing or corrupted pre-existing backup aborts uninstall before
28+
any deletion (backups now record a SHA256 that is verified when present).
29+
- **R6**: doctor treats the newest log as the diagnostic scope; a newer
30+
session without route events reports "未验证/unverified" while older
31+
route events are labelled historical.
32+
- **R7**: kit refreshes download into a staging directory and switch only
33+
after every file is fetched — an interrupted refresh leaves the previous
34+
kit fully valid (offline fallback preserved).
35+
36+
The eight reproduced scenarios from
37+
[`docs/reviews/2026-09-20-v0.1.1-independent-repro.py`](docs/reviews/2026-09-20-v0.1.1-independent-repro.py)
38+
all assert fixed, and are migrated into formal regressions
39+
(`tests/test_review4.py`). Docs consistency: STATUS links/counts, README
40+
quick-start no longer forces `--arch` (auto-detection first), Linux
41+
requirements updated.
42+
843
## [0.1.1] — 2026-09-20
944

1045
### Fixed
@@ -84,5 +119,6 @@ The nine reproduced problem behaviors are pinned by
84119
`docs/reviews/2026-09-20-repro.py` (all report fixed) and migrated into
85120
regression tests (`tests/test_review2.py`).
86121

122+
[0.1.2]: https://github.com/ztwzeroo/DLSS5-FrameGen/releases/tag/v0.1.2
87123
[0.1.1]: https://github.com/ztwzeroo/DLSS5-FrameGen/releases/tag/v0.1.1
88124
[0.1.0]: https://github.com/ztwzeroo/DLSS5-FrameGen/releases/tag/v0.1.0

‎README.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Use an independently backed-up or disposable game copy. Uninstall validates its
7878

7979
```powershell
8080
.\dlss-combo.exe fetch
81-
.\dlss-combo.exe install "C:/Games/TestCopy/Binaries/Win64" --mfg 4x
81+
.\dlss-combo.exe install "C:/Games/TestCopy/Binaries/Win64"
8282
```
8383

8484
**From source:** [download the source ZIP](https://github.com/ztwzeroo/DLSS5-FrameGen/archive/refs/heads/main.zip), extract it, and open PowerShell in the extracted folder. Then run:
@@ -137,11 +137,11 @@ Use `py -m dlss_combo --help` or `py -m dlss_combo install --help` for the full
137137

138138
## Linux / Steam Proton
139139

140-
Windows games running through Proton are still Windows processes, so the frame-generation layer is expected to apply the same way — **not yet verified end-to-end by this project on Linux**. Grab `dlss-combo-<version>-linux-x64.zip`, then point the CLI at the folder containing the game's **rendering EXE**. The reliable way to find it is Steam → *Manage* → **Browse local files** (for Proton installs that lands you inside the prefix's `drive_c`; don't assume a fixed prefix layout — always locate the actual EXE folder):
140+
Windows games running through Proton are still Windows processes, so the frame-generation layer is expected to apply the same way — **not yet verified end-to-end by this project on Linux**. Grab `dlss-combo-<version>-linux-x64.zip`, then point the CLI at the folder containing the game's **rendering EXE**. The reliable way to find it is Steam → *Manage* → **Browse local files** (Proton installs often live under the prefix's `drive_c`, but the layout is not guaranteed — the Browse-local-files location is the reliable reference):
141141

142142
```bash
143143
chmod +x dlss-combo
144-
./dlss-combo install "/path/to/Game/Binaries/Win64" --arch sm86
144+
./dlss-combo install "/path/to/Game/Binaries/Win64"
145145
```
146146

147147
Some setups add Steam launch options so Wine loads the proxy and Proton exposes
@@ -154,7 +154,7 @@ WINEDLLOVERRIDES="version=n,b" PROTON_ENABLE_NVAPI=1 PROTON_NVIDIA_NVCUDA=1 %com
154154
> These options are community convention (the route [DLSS Unlocked](https://github.com/ShyVortex/DLSS-Unlocked) documents), **not verified with this toolkit** — check your Proton version's behavior against [Valve's config notes](https://github.com/ValveSoftware/Proton#runtime-config-options) before relying on them. Substitute the actual proxy name (`winmm`/`dbghelp`/…) if it is not `version.dll`.
155155
156156
- The image layer (DLSS5-Swapper) is a Windows GUI app; running it via Wine is upstream-experimental — on Linux, validate the frame-generation layer first.
157-
- **Linux binaries**: built on Ubuntu 22.04; the whole-binary GLIBC symbol floor is measured per build (current: 2.14, in each zip's `build-info.txt`). Other distros are unverified — glibc >= 2.17 (manylinux2014-era) is the conservative recommendation, or run from source.
157+
- **Linux binaries require glibc >= 2.35** — the real floor is measured per build by extracting the embedded ELF libraries from the PyInstaller archive (an outer-file string scan under-reports it; the current build's floor is in each zip's `build-info.txt`). Other distros are unverified; to target older systems, run from source.
158158

159159
## What has actually been tested?
160160

‎README.zh-CN.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ Windows EXE 与 Linux x64 二进制(GitHub Actions 从打 tag 的提交构建
2121

2222
> Linux/Steam Proton(实验性):用 Steam“浏览本地文件”定位含渲染 EXE 的实际目录;
2323
> 启动选项 `WINEDLLOVERRIDES="version=n,b" PROTON_ENABLE_NVAPI=1 …` 为社区惯例、未经本组合实测。
24-
> Linux 包由 Ubuntu 22.04 构建,全文件 GLIBC 符号下限按构建实测(当前 2.14,见包内 build-info.txt);
25-
> 其他发行版未验证,保守建议 glibc ≥ 2.17,或直接源码运行。
24+
> Linux 包需 glibc ≥ 2.35:下限按构建时解包 PyInstaller 归档、解析内嵌 ELF 实测(外层字符串扫描会漏报;
25+
> 当前值见包内 build-info.txt)。其他发行版未验证;要跑更旧系统请用源码方式。
2626
2727
[How it works / 工作原理](#how-it-works--工作原理) · [Getting started / 开始使用](#getting-started--开始使用) · [Known issues / 已知问题](docs/reviews/2026-09-20-project-review.md) · [Report results / 反馈实测](https://github.com/ztwzeroo/DLSS5-FrameGen/issues)
2828

‎docs/STATUS.md‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@
44

55
**This is an experimental source preview, not a stable installer.** It is intended for contributors and experienced modders working on disposable directories or independently backed-up game copies.
66

7-
This page describes the tree after the 2026-09-20 review fixes landed (see [the review](2026-09-20-project-review.md) and [repro script](2026-09-20-repro.py); all nine reproduced behaviors now assert fixed). In-game behavior remains unverified.
7+
This page describes the tree after the 2026-09-20 review fixes landed (see [the review](reviews/2026-09-20-project-review.md) and [repro script](reviews/2026-09-20-repro.py), plus the [v0.1.1 independent review](reviews/2026-09-20-v0.1.1-independent-review.md) and its [repro](reviews/2026-09-20-v0.1.1-independent-repro.py) — all seventeen reproduced behaviors now assert fixed). In-game behavior remains unverified.
88

99
## Evidence so far
1010

11-
- 107 offline Python tests pass; CI runs them on Windows/Linux/macOS on every push.
11+
- 122 offline Python tests pass; CI runs them on Windows/Linux/macOS on every push.
1212
- A Python wheel builds, and an isolated CLI version check succeeds.
1313
- The nine reproduced problem behaviors from the 2026-09-20 review are fixed and covered by regression tests; the repro script reports all nine as fixed.
1414
- No Windows/NVIDIA game session, image-quality comparison, latency test or FPS benchmark has been validated by this project.
1515

1616
Upstream support claims and configuration limits are not a substitute for testing the combined setup. A `4x` or `6x` setting is a frame-generation ceiling, not a measured performance improvement.
1717

18+
## Fixed in v0.1.2 (independent v0.1.1 review, R1–R7)
19+
20+
First-install rollback now restores the user's original INI at every failure point (DLL/manifest/backup write); uninstall never overwrites any existing file or symlink when saving a restore copy (exclusive `O_CREAT|O_EXCL` with numbered fallbacks); temp files are random and exclusively created, and only paths registered by the current operation are cleaned; a missing or corrupted pre-existing backup aborts uninstall before any deletion; doctor treats the newest log as the diagnostic scope and labels older route events as historical; interrupted kit refreshes stage and switch atomically, leaving the previous kit usable. Evidence: `tests/test_review4.py` and the flipped independent repro script (all eight scenarios fixed). The glibc floor is now measured from the CArchive-extracted embedded ELF libraries (see the release workflow).
21+
1822
## Known issues
1923

2024
### File deletion and ownership — FIXED 2026-09-20
@@ -55,6 +59,6 @@ The project targets Windows 10/11 x64, RTX 20/30, and D3D12 games with native DL
5559

5660
Prioritize bounded filesystem operations, ownership checks, original-file restoration, strict checksums, and failure recovery. Regression tests should assert that unrelated files remain byte-for-byte unchanged.
5761

58-
The [detailed audit (Chinese)](reviews/2026-09-20-project-review.md) includes file locations, reproduction results and acceptance criteria. The [reproduction script](reviews/2026-09-20-repro.py) uses temporary files and does not launch real binaries. **Its successful completion means the known bugs are reproducible, not that the tool is safe.**
62+
The [detailed audit (Chinese)](reviews/2026-09-20-project-review.md) includes file locations, reproduction results and acceptance criteria. The [reproduction script](reviews/2026-09-20-repro.py) uses temporary files and does not launch real binaries. **Since v0.1.2 both scripts assert the FIXED behavior: successful completion means the reproduced defects no longer trigger — a specific regression guard, not proof that all file-safety concerns are resolved.**
5963

6064
For real game reports, use the [game-test form](https://github.com/ztwzeroo/DLSS5-FrameGen/issues/new?template=game-test.yml). Include unsuccessful attempts and clearly label what you did and did not measure.

‎docs/devlog/2026-09-20.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@
6060
- **产出**:[v0.1.1 Release](https://github.com/ztwzeroo/DLSS5-FrameGen/releases/tag/v0.1.1)
6161
(110 测试,两平台烟雾测试通过,SHA256 校验实测)。
6262

63+
### 第 6 轮 · v0.1.1 独立复核 → v0.1.2
64+
65+
- 详档:[2026-09-20-v0.1.1-independent-review.md](../reviews/2026-09-20-v0.1.1-independent-review.md);
66+
复现脚本:[2026-09-20-v0.1.1-independent-repro.py](../reviews/2026-09-20-v0.1.1-independent-repro.py)(8 场景)。
67+
- **R1–R7 全部修复**:首装回滚还原用户 INI(四类故障注入测试)、卸载副本排他创建、
68+
随机排他临时件 + 登记式清理、备份缺失拒绝删除(含备份 SHA256)、doctor 最新会话范围、
69+
kit 刷新 staging 切换、glibc 真实量测(解包 CArchive 解析内嵌 ELF,实测 ≥ 2.35,
70+
外层字符串扫描确会漏报)。
71+
- 测试 110 → 122;新旧复现脚本合计 17 场景全部断言"已修复"。
72+
- **产出**:[v0.1.2 Release](https://github.com/ztwzeroo/DLSS5-FrameGen/releases/tag/v0.1.2)。
73+
6374
## 尚未验证的事项(如实)
6475

6576
- Windows + RTX 20/30 真机:游戏内加载代理、DLSS-G 后端激活、画质层生效、

0 commit comments

Comments
 (0)