Skip to content

Segfault when num_threads is set on certain CPU #2114

@tamcy

Description

@tamcy

What happened?

The following segfault error emits when the FrankenPHP powered Docker image is up:

php-1  | {"level":"info","ts":1767878883.108642,"msg":"maxprocs: Leaving GOMAXPROCS=24: CPU quota undefined"}
php-1  | {"level":"info","ts":1767878883.108994,"msg":"GOMEMLIMIT is updated","package":"github.com/KimMachineGun/automemlimit/memlimit","GOMEMLIMIT":60257824358,"previous":9223372036854775807}
php-1  | {"level":"info","ts":1767878883.1102464,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
php-1  | {"level":"error","ts":1767878883.110694,"msg":"Setting the \"transport_url\" directive is not available anymore, use the \"transport\" directive instead"}
php-1  | {"level":"info","ts":1767878883.111232,"msg":"adapted config to JSON","adapter":"caddyfile"}
php-1  | {"level":"warn","ts":1767878883.1112518,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":21}
php-1  | {"level":"info","ts":1767878883.1220682,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
php-1  | {"level":"info","ts":1767878883.1222134,"logger":"http.auto_https","msg":"automatic HTTPS is completely disabled for server","server_name":"srv0"}
php-1  | {"level":"info","ts":1767878883.1224532,"logger":"http.auto_https","msg":"automatic HTTPS is completely disabled for server","server_name":"srv1"}
php-1  | {"level":"info","ts":1767878883.122822,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000466c00"}
php-1  | {"level":"debug","ts":1767878883.1230936,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{}]}},"http":{"servers":{"srv0":{"listen":[":2020"],"routes":[{"handle":[{"handler":"metrics"}]}],"automatic_https":{"disable":true}},"srv1":{"listen":[":80"],"routes":[{"handle":[{"handler":"vars","root":"/app/public"},{"handler":"headers","response":{"require":{"headers":{"Permissions-Policy":null}},"set":{"Permissions-Policy":["browsing-topics=()"]}}},{"encodings":{"gzip":{},"zstd":{}},"handler":"encode","prefer":["zstd","gzip"]},{"anonymous":true,"dispatch_timeout":10000000000,"handler":"mercure","publisher_jwt":{"alg":"{env.MERCURE_PUBLISHER_JWT_ALG}","key":"{env.MERCURE_PUBLISHER_JWT_KEY}"},"subscriber_jwt":{"alg":"{env.MERCURE_SUBSCRIBER_JWT_ALG}","key":"{env.MERCURE_SUBSCRIBER_JWT_KEY}"},"subscriptions":true,"write_timeout":0},{"handler":"vulcain"}]},{"handle":[{"handler":"static_response","headers":{"Location":["{http.request.orig_uri.path}/"]},"status_code":308}]},{"handle":[{"handler":"rewrite","uri":"{http.matchers.file.relative}"}]},{"handle":[{"handler":"php","split_path":[".php"]}]},{"handle":[{"handler":"file_server"}]}],"automatic_https":{"disable":true},"logs":{"default_logger_name":"log0"}}},"metrics":{}}}
php-1  | {"level":"debug","ts":1767878883.1265736,"logger":"frankenphp","msg":"shutting down autoscaling","autoScaledThreads":0}
php-1  | {"level":"info","ts":1767878883.1266198,"msg":"maxprocs: No GOMAXPROCS change to reset"}
php-1  | panic: runtime error: invalid memory address or nil pointer dereference
php-1  | [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x17cf876]
php-1  |
php-1  | goroutine 1 [running]:
php-1  | github.com/dunglas/frankenphp.drainPHPThreads()
php-1  |        /go/src/app/phpmainthread.go:84 +0x36
php-1  | github.com/dunglas/frankenphp.Shutdown()
php-1  |        /go/src/app/frankenphp.go:368 +0x75
php-1  | github.com/dunglas/frankenphp.Init({0xc0001572d0, 0x8, 0x12?})
php-1  |        /go/src/app/frankenphp.go:281 +0x4cd
php-1  | github.com/dunglas/frankenphp/caddy.(*FrankenPHPApp).Start(0xc000964600)
php-1  |        /go/src/app/caddy/app.go:168 +0xbe7
php-1  | github.com/caddyserver/caddy/v2.run.func2(...)
php-1  |        /root/go/pkg/mod/github.com/caddyserver/caddy/v2@v2.10.2/caddy.go:438
php-1  | github.com/caddyserver/caddy/v2.run(0xc00045d5d8?, 0x1)
php-1  |        /root/go/pkg/mod/github.com/caddyserver/caddy/v2@v2.10.2/caddy.go:454 +0x434
php-1  | github.com/caddyserver/caddy/v2.unsyncedDecodeAndRun({0xc000435800, 0x7a3, 0x800}, 0x1)
php-1  |        /root/go/pkg/mod/github.com/caddyserver/caddy/v2@v2.10.2/caddy.go:347 +0x145
php-1  | github.com/caddyserver/caddy/v2.changeConfig({0x1e851ad, 0x4}, {0x1e8b062, 0x7}, {0xc000435000, 0x7a3, 0x800}, {0x0, 0x0}, 0x1)
php-1  |        /root/go/pkg/mod/github.com/caddyserver/caddy/v2@v2.10.2/caddy.go:238 +0x6a5
php-1  | github.com/caddyserver/caddy/v2.Load({0xc000435000, 0x7a3, 0x800}, 0x1)
php-1  |        /root/go/pkg/mod/github.com/caddyserver/caddy/v2@v2.10.2/caddy.go:137 +0x22d
php-1  | github.com/caddyserver/caddy/v2/cmd.cmdRun({0x0?})
php-1  |        /root/go/pkg/mod/github.com/caddyserver/caddy/v2@v2.10.2/cmd/commandfuncs.go:240 +0x80d
php-1  | github.com/caddyserver/caddy/v2/cmd.init.1.func2.WrapCommandFuncForCobra.1(0xc00096a308, {0x1e85229?, 0x4?, 0x1e851e1?})
php-1  |        /root/go/pkg/mod/github.com/caddyserver/caddy/v2@v2.10.2/cmd/cobra.go:141 +0x2f
php-1  | github.com/spf13/cobra.(*Command).execute(0xc00096a308, {0xc000126fc0, 0x2, 0x2})
php-1  |        /root/go/pkg/mod/github.com/spf13/cobra@v1.10.2/command.go:1015 +0xb02
php-1  | github.com/spf13/cobra.(*Command).ExecuteC(0xc0001f5b08)
php-1  |        /root/go/pkg/mod/github.com/spf13/cobra@v1.10.2/command.go:1148 +0x465
php-1  | github.com/spf13/cobra.(*Command).Execute(...)
php-1  |        /root/go/pkg/mod/github.com/spf13/cobra@v1.10.2/command.go:1071
php-1  | github.com/caddyserver/caddy/v2/cmd.Main()
php-1  |        /root/go/pkg/mod/github.com/caddyserver/caddy/v2@v2.10.2/cmd/main.go:72 +0x65
php-1  | main.main()
php-1  |        /go/src/app/caddy/frankenphp/main.go:15 +0xf

This only happens when I run the production image on my dev machine, but not on the production server, so it took me some time to figure out why. Turns out this is caused by a Caddy configuration I added earlier:

	frankenphp {
		num_threads 32
	}

Which, for some unknown reason, doesn't play well on my dev machine. I am running Docker Desktop on Windows, but here is the lscpu output on WSL anyway:

Architecture:            x86_64
  CPU op-mode(s):        32-bit, 64-bit
  Address sizes:         48 bits physical, 48 bits virtual
  Byte Order:            Little Endian
CPU(s):                  24
  On-line CPU(s) list:   0-23
Vendor ID:               AuthenticAMD
  Model name:            AMD Ryzen 9 7900 12-Core Processor
    CPU family:          25
    Model:               97
    Thread(s) per core:  2
    Core(s) per socket:  12
    Socket(s):           1
    Stepping:            2
    BogoMIPS:            7399.83
    Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good
                         nopl tsc_reliable nonstop_tsc cpuid extd_apicid pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm cmp_legacy svm cr8_
                         legacy abm sse4a misalignsse 3dnowprefetch osvw topoext perfctr_core ssbd ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid avx512f avx512dq rdseed adx
                         smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves avx512_bf16 clzero xsaveerptr arat npt nrip_save tsc_scale vmcb_clean f
                         lushbyasid decodeassists pausefilter pfthreshold v_vmsave_vmload avx512vbmi umip avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid fsrm

I tried setting num_threads to 16, 24, 32, 48, but all failed. I have to remove the num_threads statement in order to have FrankenPHP running.

Build Type

Docker (Debian Trixie)

Worker Mode

No

Operating System

GNU/Linux

CPU Architecture

x86_64

PHP configuration

N/A

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions