arnaud-lb / php-memory-profiler

Memory profiler for PHP. Helps finding memory leaks in PHP scripts.
MIT License
858 stars 51 forks source link

Segmentation fault on centos #60

Open sonersivri opened 2 years ago

sonersivri commented 2 years ago
# php -v
PHP 7.3.32 (cli) (built: Oct 26 2021 15:07:00) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.32, Copyright (c) 1998-2018 Zend Technologies
    with the ionCube PHP Loader + ionCube24 v10.4.5, Copyright (c) 2002-2020, by ionCube Ltd.

# php -m
[PHP Modules]
bz2
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gettext
hash
iconv
igbinary
imap
intl
ionCube Loader
json
ldap
libxml
mailparse
mbstring
memprof
msgpack
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
rdkafka
readline
redis
Reflection
session
shmop
SimpleXML
sockets
SPL
sqlite3
standard
sysvmsg
sysvsem
sysvshm
tokenizer
wddx
xml
xmlreader
xmlwriter
xsl
zip
zlib

[Zend Modules]
the ionCube PHP Loader + ionCube24

# /usr/bin/php /opt/pusula/archive/scripts/archive-consumer.php
PHP Warning:  Calling memprof_enable() manually may not work as expected because of PHP optimizations. Prefer using MEMPROF_PROFILE=1 as environment variable, GET, or POST in /opt/pusula/archive/scripts/archive-consumer.php on line 10
Segmentation fault

# MEMPROF_PROFILE=1 /usr/bin/php /opt/pusula/archive/scripts/archive-consumer.php
Segmentation fault
arnaud-lb commented 2 years ago

Hello @sonersivri

What version of memprof are you using ? (you can find it with php -dextension=memprof.so -i | grep memprof)

Does it crash without the ion cube extension ?

mattrcampbell commented 2 years ago

@arnaud-lb I am seeing the same issue on another OS. I am seg faulting in both Apache 2 AND CLI. I am using the PHP 8.1 docker image.

PHP 8.1.1 (cli) (built: Dec 21 2021 19:41:31) (NTS)

memprof support => enabled memprof version => 3.0.2 memprof native malloc support => Yes memprof.output_dir => /tmp => /tmp

arnaud-lb commented 2 years ago

Hi @mattrcampbell

Is this happening when profiling a particular script, or on any script ? How are you enabling profiling ? Could you post the list of extensions loaded ? (php -m)

mattrcampbell commented 2 years ago

It is happening on a particular script when it hits the memory limit, but it relies on so much in-house code I can't post it here. When I run it on a simple script that does makes too big of a string, I don't get a core.

Modules: [PHP Modules] Core ctype curl date dom fileinfo filter ftp gd hash iconv json ldap libxml mbstring memprof mysqli mysqlnd oci8 openssl pcre PDO pdo_sqlite Phar posix readline Reflection session SimpleXML sodium SPL sqlite3 standard tokenizer xml xmlreader xmlwriter zlib

[Zend Modules]

arnaud-lb commented 2 years ago

Thank you. What is the output of var_dump(memprof_enabled_flags()); ?

mattrcampbell commented 2 years ago

array(3) { ["enabled"]=> bool(true) ["native"]=> bool(false) ["dump_on_limit"]=> bool(true) }

arnaud-lb commented 2 years ago

Would you be able to provide a backtrace of the segfault ?

You can get one with gdb:

MEMPROF_PROFILE=dump_on_limit gdb --args php script.php

Type run on prompt, and then type backtrace when you see a segfault

mattrcampbell commented 2 years ago

Looks like it might be stuck in some sort of loop, this repeats for a very long time

0 0x0000555555a19498 in ?? ()

1 0x0000555555a1a9de in ap_php_snprintf ()

2 0x00007ffff4a66629 in get_function_name (execute_data=execute_data@entry=0x7fffe75a2270, buf=buf@entry=0x7fffff7ff970 "H", buf_size=buf_size@entry=256) at /tmp/pear/temp/memprof/util.c:108

3 0x00007ffff4a64b89 in get_or_create_frame (current_execute_data=current_execute_data@entry=0x7fffe75a2270, prev=0x555558013470) at /tmp/pear/temp/memprof/memprof.c:456

4 0x00007ffff4a64de1 in memprof_zend_execute (execute_data=0x7fffe75a2270) at /tmp/pear/temp/memprof/memprof.c:740

5 0x0000555555ae6159 in execute_ex ()

6 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a20e0) at /tmp/pear/temp/memprof/memprof.c:746

7 0x0000555555ae6159 in execute_ex ()

8 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a1f50) at /tmp/pear/temp/memprof/memprof.c:746

9 0x0000555555ae6159 in execute_ex ()

10 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a1de0) at /tmp/pear/temp/memprof/memprof.c:746

11 0x0000555555aabe8a in ?? ()

12 0x0000555555adf213 in execute_ex ()

13 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a1de0) at /tmp/pear/temp/memprof/memprof.c:746

14 0x0000555555ae6159 in execute_ex ()

15 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a1c10) at /tmp/pear/temp/memprof/memprof.c:746

16 0x0000555555ae6159 in execute_ex ()

17 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a1a80) at /tmp/pear/temp/memprof/memprof.c:746

18 0x0000555555ae6159 in execute_ex ()

19 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a18f0) at /tmp/pear/temp/memprof/memprof.c:746

20 0x0000555555ae6159 in execute_ex ()

21 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a1780) at /tmp/pear/temp/memprof/memprof.c:746

22 0x0000555555aabe8a in ?? ()

23 0x0000555555adf213 in execute_ex ()

24 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a1780) at /tmp/pear/temp/memprof/memprof.c:746

25 0x0000555555ae6159 in execute_ex ()

26 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a15b0) at /tmp/pear/temp/memprof/memprof.c:746

27 0x0000555555ae6159 in execute_ex ()

28 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a1420) at /tmp/pear/temp/memprof/memprof.c:746

29 0x0000555555ae6159 in execute_ex ()

30 0x00007ffff4a64e07 in memprof_zend_execute (execute_data=0x7fffe75a1290) at /tmp/pear/temp/memprof/memprof.c:746

arnaud-lb commented 2 years ago

It's possible that there is a very deep recursion in your code, causing this stack overflow (each memprof_zend_execute and execute_ex call here is a PHP function call). Without memprof, this recursion would instead cause a memory exhaustion (this may be the cause of the memory exhaustion you are trying to debug).

If you download https://raw.githubusercontent.com/php/php-src/master/.gdbinit to you current folder and run gdb again, you can obtain a PHP-level backtrace by running zbacktrace (instead of backtrace). This might tell you which code is causing this.

If it's not that, then it could be a bug in get_function_name().

mattrcampbell commented 2 years ago

This is very strange, I can't quite figure out why but I am getting this error: No symbol "basic_functions_module" in current context.

mattrcampbell commented 2 years ago

Ok a quick edit of .gdbinit and I was able to get a backtrace.... did find a loop in our code.

arnaud-lb commented 2 years ago

Thank you for the details you provided @mattrcampbell, this helped a lot to understand the problem.

I've created a separate issue so that memprof handles this in a better way in the future.