libpcre segfault - is maximum stack size the issue?

[email protected] (William Edwards)
Newsgroups php.general
Message-ID <[email protected]>
Hi,

Some of my PHP processes are being terminated due to a segfault in 
libpcre. Although I am aware this is not a PHP issue, I am posting this 
issue to this list to see if anyone else has had similar symptoms. (I 
can't imagine that libpcre + PHP is an uncommon combination.)

     May 13 07:28:26 http-ppa01 php-fpm[21559]: [WARNING] [pool 
prod-crewplanner_com-8-1] child 26675 exited on signal 11 (SIGSEGV) 
after 31395.232062 seconds from start
     May 13 07:28:26 http-ppa01 kernel: [169698.538142] 
php-fpm8.1[26675]: segfault at 7ffc9e122f78 ip 00007f54305efb64 sp 
00007ffc9e122f40 error 6 in libpcre2-8.so.0.10.4[7f54305a6000+66000]

pcrestack(3) says:

> In Unix-like environments, there is not often a problem with the stack 
> unless very long strings are involved, though the default limit on 
> stack size varies from system to system. [...] Unfortunately, the 
> effect of running out of stack is often SIGSEGV [...]

This is confirmed by 
https://www.gnu.org/software/libc/manual/html_node/Limits-on-Resources.html, 
which describes RLIMIT_STACK as follows:

> The maximum stack size for the process. If the process tries to extend 
> its stack past this size, it gets a SIGSEGV signal.

The maximum stack size for this PHP-FPM process is set to unlimited:

     root@http-ppa01:~# cat /proc/21559/limits
     Limit Soft Limit Hard Limit Units
     Max cpu time unlimited unlimited seconds
     Max file size unlimited unlimited bytes
     Max data size unlimited unlimited bytes
     Max stack size 8388608 unlimited bytes
     Max core file size 0 unlimited bytes
     Max resident set unlimited unlimited bytes
     Max processes 31699 31699 processes
     Max open files 1024 524288 files
     Max locked memory 65536 65536 bytes
     Max address space unlimited unlimited bytes
     Max file locks unlimited unlimited locks
     Max pending signals 31699 31699 signals
     Max msgqueue size 819200 819200 bytes
     Max nice priority 0 0
     Max realtime priority 0 0
     Max realtime timeout unlimited unlimited us

I'm not sure why the limit is set to 8388608 (8 MiB). It is not set by 
me, and pthread_create(3) says that the default stack size for x86_64 is 
2 MB.

The PHP documentation at 
https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit 
describes the 'pcre.recursion_limit' setting with:

> PCRE's recursion limit. Please note that if you set this value to a 
> high number you may consume all the available process stack and 
> eventually crash PHP (due to reaching the stack size limit imposed by 
> the Operating System).

I decreased pcre.recursion_limit from the default value of 100000 to 524 
on May 11 11:55 GMT+2. I also attempted disabling pcre.jit. However, 
even with these customisations, some PHP processes are still being 
terminated with SIGSEGV:

- 142 on May 11 before 11:55 GMT+2
- 29 on May 11 after 11:55 GMT+2
- 84 on May 12 (24 * 60 = 1440 minutes)
- 22 today on May 13 so far until 13:16 GMT+2 ((13 * 60) + 16 = 796 
minutes). Relative to May 12, we should get ~65 today

As the stack size is already quite large, I'm wondering whether reaching 
the maximum stack size is actually the issue. After some searching, I 
found the following PHP bug report (which is not a PHP bug) by someone 
who determined that the cause of their segfault is using too many 
backslashes: https://bugs.php.net/bug.php?id=66059

Before I install debug symbols on my production system, I'm wondering if 
anyone else has seen a similar issue. I'm running kernel 
5.10.0-0.bpo.12-amd64 on Debian 10 with PHP-FPM 8.1.5.

Non-default settings:

     date.timezone = Europe/Amsterdam
     max_file_uploads = 100
     realpath_cache_size = 8M
     session.save_path = /var/www/vhosts/sessions
     opcache.memory_consumption = 192
     opcache.validate_timestamps = Off
     max_input_vars = 50000
     max_execution_time = 300
     memory_limit = 1024M
     post_max_size = 100M
     upload_max_filesize = 100M
     pcre.recursion_limit = 524

Enabled modules:

     root@http-ppa01:~# phpquery -v 8.1 -s fpm -M
     mysqli
     sockets
     ftp
     readline
     opcache
     simplexml
     gettext
     iconv
     fileinfo
     bcmath
     dom
     imap
     sqlite3
     calendar
     shmop
     gd
     mbstring
     soap
     zip
     redis
     sysvshm
     ffi
     posix
     xmlreader
     ctype
     mysqlnd
     pdo_sqlite
     curl
     pdo_mysql
     xml
     xmlwriter
     igbinary
     intl
     xsl
     sysvsem
     sysvmsg
     tokenizer
     pdo
     phar
     exif

PCRE2 version:

     root@http-ppa01:~# pcre2-config --version
     10.39

-- 
With kind regards,

William Edwards
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.