Segfault on recursive injection services definition

[197499.952163] php5-fpm[87799]: segfault at 71 ip 00000000006ddcd4 sp 00007ffef4af1680 error 4 in php5-fpm[400000+800000]

While trying to define services recursive injection I end up with segmentation fault. PHP-FPM mode. Why there is no fatal error or Phalcon exception?

It might be odd to even try such thing at runtime, but it should not cause segfault (crashing the app server).

How to reproduce:

$di->setShared('service1', function () use ($di, $config){
 $s2 = $di->getShared('service2'); //resolve service2

$di->setShared('service2', function () use ($di, $config){
 $s1 = $di->getShared('service1');  //resolve service1

Normally, both services are created at runtime.

What OS you are using and phalcon version ? Anything in logs ? You can try running this code in cli version. If someone will reproduce a problem, and want whole stack what causing is problem try gdb:

edited Feb '16

Ubuntu LTS, latest 2.0.10 Phalcon, compiled just few days ago. Logs are empty, only got core dump from the system.

The thing is, this happens only with Session objects, or more precise in my use case Libmemcached session adapter and Libmemcached as backend cache.

So I have circular dependency between two objects (services):

+---------+      +---------+
|    A    |<-----|    B    |
|         |      |         |
|         |----->|         |
+---------+      +---------+

The issue is on that side of things I guess - Libmemcached implementation since both components / services depend on that lib. I can reference other services / objects with circular dependency. The question is - can we use DI to resolve circular dependencies. or not.

edited Feb '16

To be honest - you shouldnt have circular depndency. Just think about it. How this code is suppose to work ? You just have here loop which never ends. On vagrant box with phalcon i just got Fatal error: Maximum function nesting level of &#039;100&#039; reached, aborting!

Circular dependency is mostly a mistake in code.

edited Feb '16

Well it depends. Circular dependencies do exist in all major programming environments today, even in a highly decoupled apps. Real world problems cannot be always interpreted by a computer definitions...

So I ended up with this scenario:

+---------+              |         |
|         |<-------------|         |
|         |              |    B    |
|    A    |    +---+     |         |
|         |--->| C |<----|         |
|         |    +---+     +---------+

If we have circular dependencies between two objects, it means that we need a third (intermediate) object, on which the two objects will depend on, so they won't depend on each other.

And you are absolutely right that since I defined a loop in a bootstrap services definition, that caused core issue. The only thing I don't agree is - how the stack did not raised some fatal error or exception, but instead crashed the entire stack.

This should be posted in Github as a bug.

edited Feb '16

But its not a bug i got fatal error. On php7 it would be throwable exception i guess.

A segfault should never happen - and it happens at a lower level than PHP code. While it may be triggerable with PHP code, the root cause is Phalcon.

edited Feb '16

No its not, i wrote the same code with phalcon and:

Fatal error: Maximum function nesting level of &#039;100&#039; reached, aborting!

So its some php related configuration that he didnt had error.

edited Feb '16

I locked down the issue. It seems that only if I override some service with syntax like:

class RouterGroup extends \Phalcon\Mvc\Router\Group ....

It causes segfault! So the issue here is not with cirular dependency as we have thought at first place!

This is apport log:

ERROR: apport (pid 57588) Wed Feb 17 01:00:20 2016: called for pid 56932, signal 11, core limit 0
ERROR: apport (pid 57588) Wed Feb 17 01:00:20 2016: executable: /usr/sbin/php5-fpm (command line "php-fpm:\ pool\ backend")
ERROR: apport (pid 57588) Wed Feb 17 01:00:20 2016: is_closing_session(): no DBUS_SESSION_BUS_ADDRESS in environment
ERROR: apport (pid 57588) Wed Feb 17 01:00:20 2016: apport: report /var/crash/_usr_sbin_php5-fpm.33.crash already exists and unseen, doing nothing to avoid disk usage DoS


and reading Coredump with gdb shows only this line:

Core was generated by `php-fpm: pool backend                                                   '.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000000006ddcd4 in _zval_ptr_dtor ()
edited Feb '16

It seems that the source of this issue could be a known bug in PHP.

any usage of zval_dtor with recursive array may trigger this segfault.

I tested many services circular dependency and guess what, only a few does segfault, which is more confusing.

Just on one occasion/setup I managed to raise this error:

Fatal error: Maximum recursion depth exceeded in /usr/share/nginx/dev/site/app/services/services.php on line 188
Fatal error: Maximum recursion depth exceeded in Unknown on line 0

Backtrace from core dump:

#0  0x00000000006ddcd4 in _zval_ptr_dtor ()
#1  0x000000000070fdd7 in zend_object_std_dtor ()
#2  0x000000000070fe09 in zend_objects_free_object_storage ()
#3  0x0000000000715c9c in zend_objects_store_del_ref_by_handle_ex ()
#4  0x0000000000715cc3 in zend_objects_store_del_ref ()
#5  0x00000000006ddd20 in _zval_ptr_dtor ()
#6  0x000000000070fdd7 in zend_object_std_dtor ()
#7  0x000000000070fe09 in zend_objects_free_object_storage ()
#8  0x0000000000715807 in zend_objects_store_free_object_storage ()
#9  0x00000000006de433 in shutdown_executor ()
#10 0x00000000006edc02 in zend_deactivate ()
#11 0x000000000068df9d in php_request_shutdown ()
#12 0x00000000004634d4 in main ()

I ecnountered this issue on other use cases too, not only on services definition. So whenever there is recurisve loop between two objects, Phalcon will simply crash entire app server (PHP-FPM in my case). This should not be default nor desired behaviour. User space "programming errors" should never cause segfault.

edited Feb '16

What php version you use ? On windows/ubuntu with php 5.6 i have Fatal Error when recursive access to services. As you can see in this stacktrace there dont exist any phalcon framework calls, write this problem on some php related forum or on php github.

edited Mar '16

PHP 5.5.9 on Ubuntu 14.04 LTS. You might be correct that Phalcon is not root cause for these crashes, but it is intermediate cause for sure, since it's IoC container generates dependencies at runtime. When I grab some more time I'll try to test it out more on this.

Don't get me wrong, I don't blame Phalcon for anything, I'm here to support the project that's why I try hard to report each 'bug', if any.

You just need to understand that you can cause such a problem in any language and in any framework.