Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

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

Fermée
#2,745 0 commentaires 1 réaction 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@mstegmeyer y travaille déjà.

Depuis le 22/10/2026.

  • #2746 par @mstegmeyer — ouverte

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
25/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
À l'abandon
Stack technique
c, go, php

Piste de recherche

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.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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
Langage dominant
Go
Étoiles
11.4k
Forks
499
Merge moyen
2 j 9 h
PR mergées (30 j)
40

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de php/frankenphp

Toutes les issues de php/frankenphp

Issues similaires

Plus d'issues Go

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.