Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fann_set_callback segfault of apache/php #33

Open
usernametakenaaaa opened this issue Oct 11, 2017 · 4 comments
Open

fann_set_callback segfault of apache/php #33

usernametakenaaaa opened this issue Oct 11, 2017 · 4 comments

Comments

@usernametakenaaaa
Copy link

usernametakenaaaa commented Oct 11, 2017

Hi Bukka,
first of all: great job on the binder!
I'm sadly not familiar with PHP extensions so I can't fix this without much effort.

fann_set_callback() is working but the PHP function will cause a segmentation fault when it returns a positive integer.
However, it is required for the callback to return an integer, that's why your test is failing.

https://github.com/bukka/php-fann/blob/master/tests/fann_set_callback_basic.phpt
Your test example for fann_set_callback() is not returning an integer, this causes the training to be interrupted.
That's why you only get one callback and it stops, that's an error in your test script.

Look here please: http://libfann.github.io/fann/docs/files/fann_data-h.html#fann_callback_type

The callback function is supposed to be called during training (each epoch as configured).

  • When -1 integer is returned the function is causing the training to abort!
    Another integer is supposed to keep running.

With PHP however it's not working at all.
When you return 0 it will abort just like a -1 will abort.
when you return a positive number it will cause a segfault (apache process crashes or php cli crashes)

Now later looking at your implementation it's obvious you actually had the right behaviour in mind but forgot testing the second case.

PHP doc should say that return of false means an abort and return of true causes the training to continue.

You can test it in your own example, just "return 1" at the end of the callback and it will segfault.

Tested with libfann 2.2 and your latest extension

@usernametakenaaaa
Copy link
Author

usernametakenaaaa commented Oct 11, 2017

To add a bit of insight:

write(1, "double(0.0010000000474975)\n", 27double(0.0010000000474975)
)     = 27
fflush(0x7f8607f292a0)                           = 0
__ctype_b_loc()                                  = 0x7f860b0cf6c8
strlen("")                                       = 0
__ctype_b_loc()                                  = 0x7f860b0cf6c8
strlen("")                                       = 0
__ctype_b_loc()                                  = 0x7f860b0cf6c8
strlen("")                                       = 0
__ctype_b_loc()                                  = 0x7f860b0cf6c8
strlen("")                                       = 0
__ctype_b_loc()                                  = 0x7f860b0cf6c8
__ctype_b_loc()                                  = 0x7f860b0cf6c8
strlen("")                                       = 0
__ctype_b_loc()                                  = 0x7f860b0cf6c8
strlen("")                                       = 0
__ctype_b_loc()                                  = 0x7f860b0cf6c8
strlen("")                                       = 0
__ctype_b_loc()                                  = 0x7f860b0cf6c8
strlen("")                                       = 0
__ctype_b_loc()                                  = 0x7f860b0cf6c8
__ctype_b_loc()                                  = 0x7f860b0cf6c8
strlen("")                                       = 0
write(1, "int(1000)\n", 10int(1000)
)                      = 10
fflush(0x7f8607f292a0)                           = 0
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++

I've added flush() to your test callback, then you can see the issue closer:

--TEST--
Test function fann_set_callback() by calling it with its expected arguments
--FILE--
resource(4) of type (FANN)
resource(7) of type (FANN Train Data)
int(50000)
int(1000)
double(0.0010000000474975)
int(1)
resource(4) of type (FANN)
resource(7) of type (FANN Train Data)
int(50000)
int(1000)
double(0.0010000000474975)
int(1000)
Segmentation fault

You can see it is called a second time as supposed by the positive integer.
However it causes a segfault at
The 1000 means that 1000 epochs have been trained, so it worked until here.

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff382cbda in fann_run () from /usr/lib/x86_64-linux-gnu/libfann.so.2 (gdb) bt #0 0x00007ffff382cbda in fann_run () from /usr/lib/x86_64-linux-gnu/libfann.so.2 #1 0x00007ffff383202f in fann_train_epoch_irpropm () from /usr/lib/x86_64-linux-gnu/libfann.so.2 #2 0x00007ffff3832e53 in fann_train_on_data () from /usr/lib/x86_64-linux-gnu/libfann.so.2 #3 0x00007ffff3a4a364 in zif_fann_train_on_data (ht=<optimized out>, return_value=0x7ffff7fd4308, return_value_ptr=<optimized out>, this_ptr=<optimized out>, return_value_used=<optimized out>) at /www/scraping.services/web_framework/external/fann/libraries/php-fann/fann.c:2053 #4 0x00000000006e812a in dtrace_execute_internal () #5 0x00007ffff3c68d75 in xdebug_execute_internal (current_execute_data=0x7ffff7fa1450, fci=0x0, return_value_used=1) at /tmp/buildd/xdebug-2.2.5/xdebug-2.2.5/xdebug.c:1551 #6 0x00000000007a8b10 in ?? () #7 0x0000000000736e60 in execute_ex () #8 0x00000000006e7fc8 in dtrace_execute_ex () #9 0x00007ffff3c68274 in xdebug_execute_ex (execute_data=0x7ffff7fa1450) at /tmp/buildd/xdebug-2.2.5/xdebug-2.2.5/xdebug.c:1437 #10 0x00000000006fabb0 in zend_execute_scripts () #11 0x0000000000695dd0 in php_execute_script () #12 0x00000000007aaacb in ?? () #13 0x0000000000462c6d in main ()

@usernametakenaaaa
Copy link
Author

I've located the issue(s):

if (user_data->z_train_data) {         
                PHPC_VAL_ASSIGN(PHPC_FCALL_PARAM_VAL(callback, 1), user_data->z_train_data);
        } else {
                PHPC_VAL_MAKE(PHPC_FCALL_PARAM_VAL(callback, 1));
                ZVAL_NULL(PHPC_FCALL_PARAM_PZVAL(callback, 1));
        }

This one here causes a segfault.
something is wrong with the z_train_data, probably an unset pointer ?

This is the first segfault location.

A second one is below:
zval_ptr_dtor(&PHPC_FCALL_PARAM_VAL(callback, 0));

This one also causes a segfault.

I've documented both out in my fann.c and it now works properly.

@bukka
Copy link
Owner

bukka commented Oct 15, 2017

Hi, thanks for the report but I'm not able to recreate it. It should be actually either true or false so the return value is converted into it. (See the docs http://php.net/manual/en/function.fann-set-callback.php ). It means if you set -1 or 1 it's like true and the function is called during the training. If you don't return anything (it mean null) or false, then the execution stops immediately.

For me the fann_set_callback_basic.phpt prints 51 times the info about execution and doesn't segfault if I change return value to true. I tried just quickly in debug built so there might be possibly still some issue.

Can you provide more info about your platform, PHP version and so on and I will try to recreate once I get more time.

@usernametakenaaaa
Copy link
Author

That's unexpected.

I am using your latest version from github.

From PHP Info:
fann
FANN support => enabled
FANN version => 1.1.1
FANN library version => 2.2

Kernel:
Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1 (2015-05-24) x86_64 GNU/Linux
Debian
PHP 5.6.30-0+deb8u1

Library:
/usr/lib/x86_64-linux-gnu/libfann.so.2.2.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=e9ec5730e8236705c744454d92019f73b84b334e, stripped

Are you sure the two parts I changed are without any fault ?
(The z_train_data caused the segfault as well as the zval_ptr_dtor of variable 0)

If you have no segfault it might still be a bug but due to different debugging information or some other compilation differences it's just not "triggered".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants