Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Re-apply SA_ONSTACK to every extension signal handler, not only SIGSEGV/SIGBUS/SIGFPE

已关闭
#2,745 0 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@mstegmeyer 已经在做这个了。

开始于 2026年10月22日。

  • #2746 来自 @mstegmeyer —— 未关闭

评估

难度
4/5
预计耗时
3-5 天
新手友好度
25/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
c, go, php

调研方向

Start at frankenphp_startup() and inspect the signal-handler setup added after php_module_startup(), along with the existing handling for SIGSEGV, SIGBUS and SIGFPE. Check how signal flags are read and reapplied, then run the reproduction with dd-trace-php under HTTP load while sending SIGVTALRM. Done means extension handlers receive SA_ONSTACK and the reproduction no longer crashes; pull request #2746 is already open for this issue.

由索引模型根据 Issue 内容生成。

描述

What happened?

frankenphp_startup() adds SA_ONSTACK to extension-installed handlers after php_module_startup(), but only for SIGSEGV, SIGBUS and SIGFPE (#2650). Asynchronous signals have the same problem, with a quieter failure. When such a handler runs on a Go thread, it runs on the interrupted goroutine's stack, and the kernel's signal frame overflows into the neighbouring goroutine's stack. Nothing fails at delivery; the process dies later in GC with traceback did not unwind completely, unknown caller pc, fatal error: fault or SIGSEGV.

A real case is dd-trace-php (DataDog/dd-trace-php#4354). It installs SIGINT/SIGTERM handlers (fixed in 1.26.1) and a SIGVTALRM handler (still unfixed) without SA_ONSTACK, and its sidecar kill()s the process with SIGVTALRM on every remote-config change. In production this crashed FrankenPHP 1.12.7 and 1.13.2 in classic mode roughly once a day per service, on x86_64.

To reproduce: FrankenPHP 1.13.2 Docker image with dd-trace-php 1.25.1, a trivial PHP script under HTTP load, and kill -VTALRM <frankenphp pid> in a loop. The process dies with exit code 2 within about a second (5/5 runs). With SA_ONSTACK re-applied to every handler after module startup, it survives 90 s and about 3M signals (3/3 runs).

Would you take a change that loops over every signal instead of the three fault signals?

for (int sig = 1; sig < NSIG; sig++) {
  struct sigaction sa;
  if (sigaction(sig, NULL, &sa) == 0 && sa.sa_handler != SIG_DFL &&
      sa.sa_handler != SIG_IGN && !(sa.sa_flags & SA_ONSTACK)) {
    sa.sa_flags |= SA_ONSTACK;
    sigaction(sig, &sa, NULL);
  }
}

Go's own handlers already carry the flag, so only extension handlers would change. Handlers installed after startup, such as pcntl_signal(), stay out of reach, as they are today.

Build Type

Docker (Debian Trixie)

Worker Mode

No

Operating System

GNU/Linux

CPU Architecture

aarch64

PHP configuration
phpinfo() output
PHP 8.5.12 (ZTS), FrankenPHP v1.13.2 (Go 1.27.3), dunglas/frankenphp:1.13.2-php8.5.12
dd-trace-php 1.25.1: datadog-setup.php --php-bin=all --enable-appsec --enable-profiling
Extensions: Core ctype curl datadog-profiling date ddappsec ddtrace dom fileinfo filter hash iconv intl json lexbor libxml mbstring mysqlnd openssl pcntl pcre PDO pdo_sqlite Phar posix random readline redis Reflection session SimpleXML sockets sodium SPL sqlite3 standard tokenizer uri xml xmlreader xmlwriter Zend OPcache zip zlib
Relevant log output
Relevant log output
runtime: g33: frame.sp=0x3c1e0fa67610 top=0x3c1e0fa677d0
fatal error: traceback did not unwind completely

unexpected fault address 0xb5e216432b0fbb01
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb5e216432b0fbb01 pc=0x45ab10]
runtime: g 857: unexpected return pc for runtime.netpollblock called from 0x5550000055550000
主要语言
Go
星标
11.4k
派生
499
平均合并
2 天 6 小时
30 天内合并 PR
42

环境准备

  • 提供 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

php/frankenphp 的其他 Issue

查看 php/frankenphp 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。