Skip to content

Unify watcher as sole execution backend#306

Open
ZnPdCo wants to merge 32 commits into
Project-LemonLime:masterfrom
ZnPdCo:phase1-watcher-refactor
Open

Unify watcher as sole execution backend#306
ZnPdCo wants to merge 32 commits into
Project-LemonLime:masterfrom
ZnPdCo:phase1-watcher-refactor

Conversation

@ZnPdCo

@ZnPdCo ZnPdCo commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

这个 pr 做了什么

正如 #302 中提到的,本 pr 将 watcher 统一为唯一的执行后端,移动 processrunner 中的部分逻辑到 watcher 中。

在执行 watcher 前,如果是 linux,会先进行一次 bwrap self-exec,并在执行 fork 前会设定一个定时器,以监控 wall time。其余部分大致相同。

  • 为什么不在执行程序时用 bwrap 包裹:因为获取不到 usage,同时 status 返回状态也不对
  • 为什么不在 qt 层面采用 bwrap 包裹:因为这次重构的目的是将 watcher 作为一个独立的执行后端,watcher 应该拥有较高权限,也可以自由选择其他沙箱。

同时添加对子进程数量的限制。

ZnPdCo and others added 7 commits July 5, 2026 13:36
- watcher_unix.cpp: add argv[12]=workdir, argv[13]=extraTimeMs;
  parent uses SIGALRM + wait4 EINTR for wall clock timeout;
  child dispatches to execTarget
- watcher_linux.cpp: add execTarget (bubblewrap sandbox)
- watcher_macos.mm: add execTarget (direct bash execution)
- processrunner_unix.cpp: unify Linux/macOS paths, remove bwrap
  construction and polling loop, add 2 new args
- test scripts: update to pass D:\Project_LemonLime and 0 for new args;
  tle/redirect replaced manual kill with wait
When bwrap wraps the user program, RLIMIT signals go to the inner
process (bash → user_prog), not to bwrap itself. bwrap/bash then
exit with a non-zero exit code that encoded the signal termination.
The parent previously checked exit code FIRST and returned RS_RE,
masking the actual TLE/MLE. Swap the order: check limits first.
…it4 rusage

bwrap calls wait4(child, &status, 0, NULL) with NULL rusage,
so the user program's CPU time is NOT accumulated into bwrap's
rusage. timeUsedMs from wait4(bwrap_pid) is just bwrap's own
time (~0ms), making limit-vs-exit-code reordering insufficient.

When bash's child is killed by a signal, bash exits with
128+signal. bwrap propagates this exit code to the watcher.
Decode the exit code to detect which signal terminated the
process, then report TLE (SIGXCPU) or MLE (SIGKILL/SIGABRT)
accordingly. This works for both bwrap and direct execution.
bwrap 内部还有一层 fork,会导致无法正确获取 usage,为了减少麻烦,在执行 watcher 之前先进行一次 bwrap 自己。

为什么不在 qt 层面直接 bwrap:这次重构的一个目标是将主动权交由 watcher,watcher 应当拥有高权限。
@ZnPdCo
ZnPdCo marked this pull request as draft July 13, 2026 09:42
Comment thread unix/watcher_unix.cpp Outdated
Comment thread unix/watcher_unix.cpp Outdated
Comment thread unix/watcher_unix.cpp Outdated
Comment thread unix/watcher_unix.cpp Outdated
Comment thread unix/watcher_unix.cpp Outdated
Comment thread unix/watcher_unix.cpp Outdated
Comment thread unix/watcher_unix.cpp
Comment thread unix/watcher_unix.cpp
@ZnPdCo
ZnPdCo marked this pull request as ready for review July 16, 2026 08:40

@alphagocc alphagocc left a comment

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.

lgtm

Comment thread unix/watcher_unix.cpp Outdated
Comment thread unix/watcher_unix.cpp Outdated
@ZnPdCo

ZnPdCo commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

引入这个更改后是不是不再支持ubuntu18.04了

@ZnPdCo

ZnPdCo commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Linux Mint 19.3、Deepin 15.11、Debian 10.3.0、openSUSE 15.1 似乎 linux 内核版本都没达到(AI 说的),都不支持 pidfd,是要放弃他们还是写一个 fallback?

@alphagocc

Copy link
Copy Markdown
Member

不要紧,支持 NOI Linux 2 就可以。比 NOI Linux 2 低的都可以扔掉。

@ZnPdCo

ZnPdCo commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

ptal, thx

@ZnPdCo
ZnPdCo requested a review from CoelacanthusHex July 25, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants