php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69643 Segmentation fault in i_zval_ptr_dtor() (zend_variables.h:56)
Submitted: 2015-05-15 20:28 UTC Modified: 2015-05-29 11:58 UTC
Votes:4
Avg. Score:4.8 ± 0.4
Reproduced:3 of 4 (75.0%)
Same Version:2 (66.7%)
Same OS:2 (66.7%)
From: berdir@php.net Assigned: laruence (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: master-Git-2015-05-15 (Git) OS: Ubuntu
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: berdir@php.net
New email:
PHP Version: OS:

 

 [2015-05-15 20:28 UTC] berdir@php.net
Description:
------------
We're working on making Drupal 8 compatible with PHP7.

Around 4 of our test have a segfault and the end of the test, during shutdown. This is relatively new (1-2weeks), they passed before.

Program received signal SIGSEGV, Segmentation fault.
i_zval_ptr_dtor (zval_ptr=0x7fffed5ffa80) at /home/berdir/tools/php-src/Zend/zend_variables.h:56
56			if (!Z_DELREF_P(zval_ptr)) {
(gdb) bt
#0  i_zval_ptr_dtor (zval_ptr=0x7fffed5ffa80) at /home/berdir/tools/php-src/Zend/zend_variables.h:56
#1  destroy_zend_class (zv=<optimized out>) at /home/berdir/tools/php-src/Zend/zend_opcode.c:260
#2  0x00000000007cb74c in _zend_hash_del_el_ex (prev=<optimized out>, p=0x136d440, idx=710, ht=0x113ddd0) at /home/berdir/tools/php-src/Zend/zend_hash.c:938
#3  _zend_hash_del_el (p=0x136d440, idx=710, ht=0x113ddd0) at /home/berdir/tools/php-src/Zend/zend_hash.c:962
#4  zend_hash_reverse_apply (ht=0x113ddd0, apply_func=apply_func@entry=0x7a6ee0 <clean_non_persistent_class>) at /home/berdir/tools/php-src/Zend/zend_hash.c:1532
#5  0x00000000007a772b in shutdown_executor () at /home/berdir/tools/php-src/Zend/zend_execute_API.c:351
#6  0x00000000007b6e2b in zend_deactivate () at /home/berdir/tools/php-src/Zend/zend.c:964
#7  0x0000000000758c22 in php_request_shutdown (dummy=<optimized out>) at /home/berdir/tools/php-src/main/main.c:1818
#8  0x0000000000854532 in do_cli (argc=-18992, argv=0x0) at /home/berdir/tools/php-src/sapi/cli/php_cli.c:1135
#9  0x00000000004372a0 in main (argc=-18992, argv=0x0) at /home/berdir/tools/php-src/sapi/cli/php_cli.c:1334

One of the failing tests is Drupal\migrate_drupal\Tests\d6\MigrateUserPictureFileTest.

Instructions on how to run the test are in https://bugs.php.net/bug.php?id=69371, for example.



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-05-16 15:10 UTC] laruence@php.net
seems I can not reproduce it:

Drupal\migrate_drupal\Tests\d6\MigrateUserPictureFileTest     13 passes

Test run duration: 3 sec


thanks
 [2015-05-19 03:13 UTC] laruence@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: laruence
 [2015-05-21 21:56 UTC] berdir@php.net
Strange, now I also can't reproduce it with that test anymore.

Drupal\file\Tests\RemoteFileSaveUploadTest is still failing for me, however. But it seems to be a completely different problem, seems to be curl related again? 

gdb --args '/usr/local/bin/php7' './core/scripts/run-tests.sh' --url 'http://d8/' --php '/usr/local/bin/php7' --test-id 2123 --execute-test 'Drupal\file\Tests\RemoteFileSaveUploadTest'

(you might need a work

Program received signal SIGSEGV, Segmentation fault.
0x0000000000564861 in _php_curl_setopt (ch=ch@entry=0x7fffe4481780, option=<optimized out>, zvalue=zvalue@entry=0x7fffe405cae0) at /home/berdir/tools/php-src/ext/curl/interface.c:2563
2563						form_error = curl_formadd(&first, &last,
(gdb) bt
#0  0x0000000000564861 in _php_curl_setopt (ch=ch@entry=0x7fffe4481780, option=<optimized out>, zvalue=zvalue@entry=0x7fffe405cae0)
    at /home/berdir/tools/php-src/ext/curl/interface.c:2563
#1  0x000000000056552c in zif_curl_setopt_array (execute_data=<optimized out>, return_value=0x7fffed413920) at /home/berdir/tools/php-src/ext/curl/interface.c:2808
#2  0x0000000000850905 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER () at /home/berdir/tools/php-src/Zend/zend_vm_execute.h:692
#3  0x00000000007f8c0b in execute_ex (ex=<optimized out>) at /home/berdir/tools/php-src/Zend/zend_vm_execute.h:394
#4  0x0000000000853f97 in zend_execute (op_array=0x7fffed4931c0, return_value=<optimized out>) at /home/berdir/tools/php-src/Zend/zend_vm_execute.h:434
#5  0x00000000007b7cf5 in zend_execute_scripts (type=8, retval=0x7fffffffa2c3, retval@entry=0x0, file_count=3) at /home/berdir/tools/php-src/Zend/zend.c:1389
#6  0x000000000075a140 in php_execute_script (primary_file=0x7fffffffcad0) at /home/berdir/tools/php-src/main/main.c:2479
#7  0x00000000008558b9 in do_cli (argc=-479607560, argv=0x7fffffffa2c3) at /home/berdir/tools/php-src/sapi/cli/php_cli.c:967
#8  0x00000000004372a0 in main (argc=-479607560, argv=0x7fffffffa2c3) at /home/berdir/tools/php-src/sapi/cli/php_cli.c:1334
 [2015-05-26 23:24 UTC] berdir@php.net
I've tried to debug this a bit more and I think current is somehow messed up. Why and what it's supposed to be, I don't know:

(gdb) print current
$5 = (zval *) 0x7fffe3e7b4c0
(gdb) print *current
$6 = {value = {lval = 1, dval = 4.9406564584124654e-324, counted = 0x1, str = 0x1, arr = 0x1, obj = 0x1, res = 0x1, ref = 0x1, ast = 0x1, zv = 0x1, ptr = 0x1, ce = 0x1, func = 0x1, 
    ww = {w1 = 1, w2 = 0}}, u1 = {v = {type = 4 '\004', type_flags = 0 '\000', const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 4}, u2 = {var_flags = 4294967295, 
    next = 4294967295, cache_slot = 4294967295, lineno = 4294967295, num_args = 4294967295, fe_pos = 4294967295, fe_iter_idx = 4294967295}}
(gdb) print current->value
$7 = {lval = 1, dval = 4.9406564584124654e-324, counted = 0x1, str = 0x1, arr = 0x1, obj = 0x1, res = 0x1, ref = 0x1, ast = 0x1, zv = 0x1, ptr = 0x1, ce = 0x1, func = 0x1, ww = {
    w1 = 1, w2 = 0}}
(gdb) print *current->value->str
Cannot access memory at address 0x1

This is the array of postfields that are processed here:
array(9) {
  ["file_test_replace"]=>
  int(1)
  ["file_subdir"]=>
  string(0) ""
  ["extensions"]=>
  string(0) ""
  ["is_image_file"]=>
  string(1) "1"
  ["op"]=>
  string(6) "Submit"
  ["form_build_id"]=>
  string(48) "form-8Jctuh1GUx5Te_wooBYvPLbOJhXOSUOgsQ-emHSKW8g"
  ["form_token"]=>
  string(43) "XcSxNC5I2nYo2-zg29Mo7rsmImYJWq7JNbK3WlwVZzc"
  ["form_id"]=>
  string(15) "_file_test_form"
  ["files[file_test_upload]"]=>
  object(CURLFile)#8517 (3) {
    ["name"]=>
    string(69) "/home/berdir/Projekte/d8/sites/simpletest/127071/files/image-test.png"
    ["mime"]=>
    string(0) ""
    ["postname"]=>
    string(0) ""
  }
}

I noticed that file_test_replace does seem to be an integer, which might be the cause for this. In fact, when I add an explicit string cast for the value, then it works!

So I guess current is optimized and in this case a zval for an int, not a string, but the code expects a string?

This means I can work around this in our tests, but this isn't supposed to break?
 [2015-05-28 16:05 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=50e08d60b66d7cdc47f61fbe73b7ebfea8da0acc
Log: Attempt to fix #69643
 [2015-05-28 16:05 UTC] laruence@php.net
-Status: Feedback +Status: Closed
 [2015-05-28 20:07 UTC] berdir@php.net
I can confirm that this fixed now!

No more segfaults with php7 in our test suite. Two new test fails thought, looking into those now.
 [2015-05-28 22:20 UTC] berdir@php.net
Ok, this is annoying.

i found a way to reproduce the origin segfault. It only happens when running the tests with concurrency.

I was able to generate a core file for a non-packaged executable on ubuntu by doing this:

as root:
# echo "/tmp/core.%e.%p.%h.%t" > /proc/sys/kernel/core_pattern

Then run:
php7 core/scripts/run-tests.sh --repeat 20 --concurrency 8 --url http://d8/ --class "Drupal\migrate_drupal\Tests\d6\MigrateFieldTest"

You should get an output like this:
...
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes                                      
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes                                      
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes                                      
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes                                      
Segmentation fault (core dumped)
FATAL Drupal\migrate_drupal\Tests\d6\MigrateFieldTest: test runner returned a non-zero error code (139).
- Found database prefix 'simpletest866096' for test ID 1804.
Segmentation fault (core dumped)
Segmentation fault (core dumped)
FATAL Drupal\migrate_drupal\Tests\d6\MigrateFieldTest: test runner returned a non-zero error code (139).
- Found database prefix 'simpletest667328' for test ID 1800.
FATAL Drupal\migrate_drupal\Tests\d6\MigrateFieldTest: test runner returned a non-zero error code (139).
- Found database prefix 'simpletest325478' for test ID 1806.
Segmentation fault (core dumped)
FATAL Drupal\migrate_drupal\Tests\d6\MigrateFieldTest: test runner returned a non-zero error code (139).
- Found database prefix 'simpletest901902' for test ID 1803.
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes    
...

And then find the core dumps in /tmp.

(gdb) print zval_ptr
$1 = (zval *) 0x7fa473d0d0d8
(gdb) print *zval_ptr
$2 = {value = {lval = 139638785192025, dval = 6.8990726590384926e-310, counted = 0x7f0030303059, str = 0x7f0030303059, arr = 0x7f0030303059, obj = 0x7f0030303059, res = 0x7f0030303059, 
    ref = 0x7f0030303059, ast = 0x7f0030303059, zv = 0x7f0030303059, ptr = 0x7f0030303059, ce = 0x7f0030303059, func = 0x7f0030303059, ww = {w1 = 808464473, w2 = 32512}}, u1 = {v = {
      type = 8 '\b', type_flags = 12 '\f', const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 3080}, u2 = {var_flags = 1953066601, next = 1953066601, cache_slot = 1953066601, 
    lineno = 1953066601, num_args = 1953066601, fe_pos = 1953066601, fe_iter_idx = 1953066601}}.
(gdb) print zval_ptr->value
$3 = {lval = 139638785192025, dval = 6.8990726590384926e-310, counted = 0x7f0030303059, str = 0x7f0030303059, arr = 0x7f0030303059, obj = 0x7f0030303059, res = 0x7f0030303059, 
  ref = 0x7f0030303059, ast = 0x7f0030303059, zv = 0x7f0030303059, ptr = 0x7f0030303059, ce = 0x7f0030303059, func = 0x7f0030303059, ww = {w1 = 808464473, w2 = 32512}}
(gdb) print zval_ptr->value->str
$4 = (zend_string *) 0x7f0030303059
(gdb) print *zval_ptr->value->str
Cannot access memory at address 0x7f0030303059
 [2015-05-29 03:05 UTC] laruence@php.net
What I got is:

$ php7 core/scripts/run-tests.sh --repeat 20 --concurrency 8  --sqlite '/tmp/test.sqlite'  --dburl 'sqlite://tmp/db.sqlite' --url http://d8/ --class "Drupal\migrate_drupal\Tests\d6\MigrateFieldTest"

Drupal test run
---------------

Tests to be run:
  - Drupal\migrate_drupal\Tests\d6\MigrateFieldTest

Test run started:
  Friday, May 29, 2015 - 03:01

Test summary
------------

Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest                1 passes             1 exceptions

Test run duration: 1 min
 [2015-05-29 06:15 UTC] berdir@php.net
If you get errors/exceptions, use --verbose --color instead of --concurrency to see what the problem is. My guess is that you're missing an extension or something like that.
 [2015-05-29 11:58 UTC] laruence@php.net
okey, now it runs as yours , but no segfault, I have tried both debug/no-debug version

$ php7 core/scripts/run-tests.sh --repeat 20 --concurrency 8 --sqlite /tmp/test.sqlite --dburl sqlite://tmp/db.sqlite  --url http://d8/ --class "Drupal\migrate_drupal\Tests\d6\MigrateFieldTest"

Drupal test run
---------------

Tests to be run:
  - Drupal\migrate_drupal\Tests\d6\MigrateFieldTest

Test run started:
  Friday, May 29, 2015 - 11:53

Test summary
------------

Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes
Drupal\migrate_drupal\Tests\d6\MigrateFieldTest               31 passes

Test run duration: 14 sec
 [2016-07-20 11:38 UTC] davey@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=50e08d60b66d7cdc47f61fbe73b7ebfea8da0acc
Log: Attempt to fix #69643
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 12 13:01:33 2025 UTC