Skip to content

host: launch watchdog sampling without shell parsing - #829

Closed
thehobbit85 wants to merge 3 commits into
seedds:mainfrom
thehobbit85:codex/watchdog-sample-argv
Closed

thehobbit85 wants to merge 3 commits into
seedds:mainfrom
thehobbit85:codex/watchdog-sample-argv

Conversation

@thehobbit85

@thehobbit85 thehobbit85 commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Launch watchdog sampling with posix_spawn and literal arguments instead of interpolating DM_WATCH_SAMPLE into a shell command. Apostrophes and shell characters remain literal, long paths are preserved, interrupted waits resume, and sampling duration, redirection, diagnostics and final exit remain unchanged.

Addresses the watchdog-path finding in issue #313, not the whole roadmap. Main still uses the vulnerable shell interpolation. The fixture executes the real watchdog with a recorder, never samples user applications, rejects shell calls at compile time and covers an absent optional fault variable. The only lint-baseline removal is the stale production command-processor finding.

Current head b34377e014fcef9a826d6cf30462e24a70b8ffe1. python3 -m unittest dm.tools.tests.test_docs dm.tools.tests.test_usage passed on this revision (17 tests). The feature sources, tests and documentation match the previously validated revision 8fc694e5d8fa byte for byte.

This PR includes main 6136418bcd564f086cf57cb0a59e8f997d36445e. Main still passes watchdog sampling through a shell. The literal argument path and corresponding path-handling tests remain necessary.

Local validation on 8fc694e5d8fa. python3 -m unittest dm.tools.tests.test_docs dm.tools.tests.test_usage — 17 tests passed.

The watchdog fixture passed 150 assertions. The upstream filesystem fixture and Unreal virtual-span alignment/reallocation control also passed.

GitHub checks for this revision

Earlier local validation on 69a66e168048. python3 -m unittest dm.tools.tests.test_docs dm.tools.tests.test_usage. All 17 tests passed. make -C dm/host/tests GAME=010015100B514000 watch-sample passed all 150 assertions using a recorder. Earlier ASan/UBSan and analyzer checks were successful. An earlier full local host run failed an audio callback-restart assertion. This revision’s local tests covered the watchdog and documentation.

Game impact is confined to watchdog diagnostics, independent of title content. The synthetic fixture covers actual production spawning/waiting without attaching to a game. Prior regression availability checks lacked the required game builds/routes; no fresh game, gameplay, shader-chain, device or performance claim is made. General behavior remains in the threads reference; validation evidence is here. No agent plans, progress records or game data are included.

@thehobbit85
thehobbit85 force-pushed the codex/watchdog-sample-argv branch from a00be71 to 1ee28cf Compare November 1, 2026 03:29
@thehobbit85
thehobbit85 force-pushed the codex/watchdog-sample-argv branch 4 times, most recently from 4820ba5 to 568ae94 Compare November 1, 2026 12:33
@thehobbit85
thehobbit85 force-pushed the codex/watchdog-sample-argv branch 7 times, most recently from 20f55b3 to 182793c Compare November 2, 2026 17:43
@thehobbit85
thehobbit85 force-pushed the codex/watchdog-sample-argv branch 2 times, most recently from 8fc694e to b34377e Compare November 3, 2026 03:13
@github-actions github-actions Bot added host The Horizon host: SVCs, services, threads, memory (dm/host) tools Tools and scripts (dm/tools, scripts) docs Documentation labels Nov 3, 2026
seedds added a commit that referenced this pull request Nov 3, 2026
…syntax in DM_WATCH_SAMPLE stays part of the path (#829)

crash.c built "/usr/bin/sample <pid> 1 -f '<path>'" in a 1,200-byte buffer and ran it with
system(), so an apostrophe ended the quote and sampling failed, shell syntax in the path ran,
and a long path was cut. watch_sample() now posix_spawns /usr/bin/sample with the pid, 1, -f
and the path as separate arguments, sends stdout and stderr to /dev/null by file actions,
resumes an interrupted waitpid, and reports setup, spawn, wait, exit and signal failures as
before; the watchdog still exits with 128 + SIGALRM. The lint baseline drops crash.c's
bugprone-command-processor entry.

t_watch_sample runs the real watchdog_main with a recording sampler and injected failures
(150 checks; system is poisoned so a shell call does not compile). Run against the real
/usr/bin/sample, the spawn wrote a 117-line sample to a folder named "John's Mac". No game
run: the code runs only after the watchdog fires with DM_WATCH_SAMPLE set.

Co-authored-by: Eliran Zach <4012041+thehobbit85@users.noreply.github.com>
@seedds

seedds commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Landed unchanged as a05f800 on main, with you as co-author. Thanks! I checked it here: the fixture passes all 150 checks, the docs tests pass, and the spawn code run against the real /usr/bin/sample wrote stacks to a folder named John's Mac.

@seedds seedds closed this Nov 3, 2026
seedds added a commit that referenced this pull request Nov 3, 2026
…syntax in DM_WATCH_SAMPLE stays part of the path (#829)

crash.c built "/usr/bin/sample <pid> 1 -f '<path>'" in a 1,200-byte buffer and ran it with
system(), so an apostrophe ended the quote and sampling failed, shell syntax in the path ran,
and a long path was cut. watch_sample() now posix_spawns /usr/bin/sample with the pid, 1, -f
and the path as separate arguments, sends stdout and stderr to /dev/null by file actions,
resumes an interrupted waitpid, and reports setup, spawn, wait, exit and signal failures as
before; the watchdog still exits with 128 + SIGALRM. The lint baseline drops crash.c's
bugprone-command-processor entry.

t_watch_sample runs the real watchdog_main with a recording sampler and injected failures
(150 checks; system is poisoned so a shell call does not compile). Run against the real
/usr/bin/sample, the spawn wrote a 117-line sample to a folder named "John's Mac". No game
run: the code runs only after the watchdog fires with DM_WATCH_SAMPLE set.

Co-authored-by: Eliran Zach <4012041+thehobbit85@users.noreply.github.com>
@seedds

seedds commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Correction: the commit on main is now fa681f9, the same content with its message reformatted; a05f800 was replaced by a force-push.

@thehobbit85
thehobbit85 deleted the codex/watchdog-sample-argv branch November 4, 2026 02:42
Know-It-All-Brother pushed a commit to Know-It-All-Brother/nxnative that referenced this pull request Nov 9, 2026
…syntax in DM_WATCH_SAMPLE stays part of the path (seedds#829)

crash.c built "/usr/bin/sample <pid> 1 -f '<path>'" in a 1,200-byte buffer and ran it with
system(), so an apostrophe ended the quote and sampling failed, shell syntax in the path ran,
and a long path was cut. watch_sample() now posix_spawns /usr/bin/sample with the pid, 1, -f
and the path as separate arguments, sends stdout and stderr to /dev/null by file actions,
resumes an interrupted waitpid, and reports setup, spawn, wait, exit and signal failures as
before; the watchdog still exits with 128 + SIGALRM. The lint baseline drops crash.c's
bugprone-command-processor entry.

t_watch_sample runs the real watchdog_main with a recording sampler and injected failures
(150 checks; system is poisoned so a shell call does not compile). Run against the real
/usr/bin/sample, the spawn wrote a 117-line sample to a folder named "John's Mac". No game
run: the code runs only after the watchdog fires with DM_WATCH_SAMPLE set.

Co-authored-by: Eliran Zach <4012041+thehobbit85@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation host The Horizon host: SVCs, services, threads, memory (dm/host) tools Tools and scripts (dm/tools, scripts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants