fix(reverse): avoid stopping Wine during probes

Repeated SIGSTOP-based injection can suspend Wine while its Win16 mutex is held
and eventually strand the timer callback. Make the short process-memory write
sequence the default between 30 ms callbacks, while retaining whole-process
stopping as an explicit single-probe diagnostic option.

Test Plan:
- `ruff check original/tools/trace_original_state.py original/tools/inject_original_state.py` -- passed
- live no-stop ball-state injection -- passed
- subsequent original timer updates remained observable
- `git diff --cached --check` -- passed
This commit is contained in:
2026-08-22 20:52:03 +02:00
parent 7caf460022
commit 5c2a80cfa5
2 changed files with 11 additions and 4 deletions
+5 -3
View File
@@ -93,8 +93,8 @@ velocities, flipper inputs and states, and claw animation state whenever any of
them changes. It neither patches `TDKPIN.EXE` nor pauses Wine. The tracing helper them changes. It neither patches `TDKPIN.EXE` nor pauses Wine. The tracing helper
is Linux-only development infrastructure; it is not part of the Rust replica. is Linux-only development infrastructure; it is not part of the Rust replica.
`tools/inject_original_state.py` briefly stops the opted-in process and updates `tools/inject_original_state.py` updates all recovered copies of the ball
all recovered copies of the ball position and velocity atomically. This permits position and velocity between the original 30 ms callbacks. This permits
repeatable probes at individual walls, circles, gates, and mechanism triggers: repeatable probes at individual walls, circles, gates, and mechanism triggers:
```sh ```sh
@@ -106,7 +106,9 @@ process is modified. Run the injector while the ball is waiting in the launcher
so it can identify the live game object, or supply the previously reported so it can identify the live game object, or supply the previously reported
`--object-base` to both the injector and tracer during a sequence of active `--object-base` to both the injector and tracer during a sequence of active
probes. `--substeps 1` isolates one collision integration step; omitting it probes. `--substeps 1` isolates one collision integration step; omitting it
retains the original configured detail level. retains the original configured detail level. `--stop-process` is available for
single probes, but repeated whole-process stops can strand Wine while a Win16
mutex is held and therefore are not the default.
A probe at `(289,94)` captured the original terminal-18 path. The collision A probe at `(289,94)` captured the original terminal-18 path. The collision
suspended the ball while frames advanced from 10 through 18 at the configured suspended the ball while frames advanced from 10 through 18 at the configured
+6 -1
View File
@@ -56,6 +56,11 @@ def parse_args() -> argparse.Namespace:
choices=range(1, 6), choices=range(1, 6),
help="temporarily force the original physics substep count", help="temporarily force the original physics substep count",
) )
parser.add_argument(
"--stop-process",
action="store_true",
help="stop all Wine threads during writes; unsafe for repeated Win16 mutex probes",
)
return parser.parse_args() return parser.parse_args()
@@ -91,7 +96,7 @@ def main() -> None:
args = parse_args() args = parse_args()
verify_original() verify_original()
pid = args.pid if args.pid is not None else find_winevdm_pid() pid = args.pid if args.pid is not None else find_winevdm_pid()
resume_afterward = stop_process(pid) resume_afterward = stop_process(pid) if args.stop_process else False
try: try:
with ProcessMemory(pid, writable=True) as memory: with ProcessMemory(pid, writable=True) as memory:
data_base = locate_data_segment(memory) data_base = locate_data_segment(memory)