Problem/Motivation
Currently there are quite a few failures in simpletest. This is an issue to organize and fix them.
Failing tests
Passing Locally
Drupal\config\Tests\ConfigOtherModuleTest
Drupal\config\Tests\ConfigSingleImportExportTest
Drupal\language\Tests\LanguageConfigOverrideImportTest
Drupal\locale\Tests\LocaleJavascriptTranslationTest
Drupal\menu_link_content\Tests\MenuLinkContentFormTest
Drupal\system\Tests\Render\HtmlResponseAttachmentsTest
Drupal\content_translation\Tests\ContentTranslationStandardFieldsTest
Drupal\block_content\Tests\BlockContentCreationTest
Drupal\taxonomy\Tests\TermTranslationUITest
Drupal\shortcut\Tests\ShortcutSetsTest
Drupal\shortcut\Tests\ShortcutLinksTest
Drupal\user\Tests\UserPasswordResetTest
Segmentation Faults
Drupal\basic_auth\Tests\Authentication\BasicAuthTest
Drupal\block\Tests\BlockAdminThemeTest
Drupal\block\Tests\BlockFormInBlockTest
Drupal\system\Tests\Common\UrlTest
Drupal\config\Tests\ConfigEntityListTest
Drupal\field\Tests\FormTest
Drupal\field_ui\Tests\ManageDisplayTest
Drupal\system\Tests\Form\ArbitraryRebuildTest
Drupal\system\Tests\Form\FormTest
Drupal\system\Tests\Form\RedirectTest
Drupal\locale\Tests\LocaleLocaleLookupTest
Drupal\locale\Tests\LocalePluralFormatTest
Drupal\locale\Tests\LocaleTranslationUiTest
Drupal\locale\Tests\LocaleUpdateTest
Drupal\system\Tests\Module\InstallTest
Drupal\system\Tests\Module\UninstallTest
Drupal\page_cache\Tests\PageCacheTest
Drupal\system\Tests\Routing\RouterTest
Drupal\simpletest\Tests\BrowserTest
Drupal\system\Tests\System\DefaultMobileMetaTagsTest
Drupal\system\Tests\System\TrustedHostsTest
Drupal\taxonomy\Tests\TermTest
Drupal\system\Tests\Theme\EngineTwigTest
Drupal\system\Tests\Theme\ThemeTest
Drupal\system\Tests\Theme\TwigExtensionTest
Drupal\system\Tests\Theme\TwigSettingsTest
Drupal\update\Tests\UpdateContribTest
Drupal\update\Tests\UpdateUploadTest
Drupal\user\Tests\UserEditTest
Drupal\user\Tests\UserRegistrationTest
Drupal\views\Tests\Handler\AreaTest
Drupal\views\Tests\Plugin\StyleTableTest
Drupal\views\Tests\ViewElementTest
Drupal\views_ui\Tests\DisplayPathTest
Created https://bugs.php.net/bug.php?id=70805 to look at the segfaults.
Comment | File | Size | Author |
---|---|---|---|
#34 | 2603152-gc-only.34.patch | 901 bytes | alexpott |
#33 | 2603152-33.patch | 1.73 KB | alexpott |
#13 | workaround-php7-gc-bug-13.diff | 890 bytes | Fabianx |
#8 | workaround-php7-gc-bug.diff | 691 bytes | Fabianx |
Comments
Comment #2
alexpottDrupal\shortcut\Tests\ShortcutSetsTest
passes locally for me (on RC6)Comment #3
alexpottSo running
Drupal\basic_auth\Tests\Authentication\BasicAuthTest
With a backtrace of
So what's interesting is that we're crashing in the test runner parent and not in the site under test. Going to try reporting this to bugs.php.net and see what happens. If I took another test from the segfault list (
Drupal\taxonomy\Tests\TermTest
) - it crashes at exactly the same spot with the same backtrace - which leads me to hope we have one thing fix here.Comment #4
Fabianx CreditAttribution: Fabianx at Tag1 Consulting commentedRan it 5 times and Drupal\page_cache\Tests\PageCacheTest passes locally for me.
Comment #5
alexpottCreated https://bugs.php.net/bug.php?id=70805
Comment #6
Fabianx CreditAttribution: Fabianx at Tag1 Consulting commentedDrupal\basic_auth\Tests\Authentication\BasicAuthTest passed locally for me with RC6, --class and --repeat 5.
Comment #7
neclimdulGah, all those failures where a file system permission. So _most_ of these pass locally. Additionally fabian has some passing that don't pass for me. That's pretty interesting. Might be a good place to start debuging.
Comment #8
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Drupal Association commentedI found the bug with the graph edge, it is GC related, which also explains why it happens later, because we leak memory elsewhere / or in this graph.
So by disabling the GC during compilation we can easily work-around that and also probably gain some speed.
Recommended reading how this has impacted composer (on another graph operation):
- http://blog.blackfire.io/performance-impact-of-the-php-garbage-collector...
- http://blog.ircmaxell.com/2014/12/what-about-garbage.html
Attached patch disables gc during container compilation.
Comment #10
chx CreditAttribution: chx commentedThere's so much wrong it makes my head hurt. We have a graph implementation which to the best of my knowedge doesn't crash PHP 7.
More importantly, if this is critical, does it mean we are blocked on releasing D8.0.0 until PHP7 bugs are fxed / worked around?
Comment #11
neclimdulThis is critical because the parent is critical. Cloned the metadata.
Comment #12
catchNo if we're blocked on issues in PHP 7 itself, we'll have to do #2576745: Add a hook_requirements() warning when running on PHP7 then require 7.0.4 or whatever version allows us to work. But it's worth trying to not do that if we can.
Comment #13
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Drupal Association commentedOkay, we need to collect the cycles else PHP 5.5 runs out of memory.
Lets try that.
Comment #14
chx CreditAttribution: chx commented> // The service graph implementation is prone to corruption during GC.
Once more: can we switch to the graph implementation?
Comment #15
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Drupal Association commented#14: We could do that, but we would need to write a proxy for the ServiceReferenceGraph* classes, which is possible.
Another option might be to explicitly GC the graph. It is a very simple implementation, which should not fail in the way it does ...
---
For the 1 remaining test failure I filed:
https://bugs.php.net/bug.php?id=70808
TL;DR is:
Under certain circumstances if you have an array and you do an unset() for an item at the end and then an array_merge_recursive(), then array_merge_recursive() will append to the end and the old unset items will in many cases (but not all) corrupt the memory.
e.g.
PHP5 always re-indexes the array on array_merge_recursive(), so this bug cannot occur - or maybe it just does see better what is unset and what is not.
Anyway an important bug for PHP to resolve before their release ...
Comment #16
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Drupal Association commentedPHP7 fixed the bug in #15 already after just 5 hours (took 3 hours to resolve it seems)! - My bug report must have been good :p
(https://bugs.php.net/bug.php?id=70808)
Comment #17
Wim LeersWow, nice :)
Comment #18
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Drupal Association commentedAnd just to confirm #16, it is fixed locally now, too when running the test suite.
So once Drupal-CI has build new, this will be fixed.
One caveat though:
- The new branch that has the fix is PHP-7.0, not PHP-7.0.0. I think someone mixed that up, upstream in PHP team.
Or it means this really simple bug fix is just considered for 7.0.1 at this point, which would be sad.
@neclimdul: Maybe you can ask your contacts about that?
Comment #19
alexpottSo I've tried to abuse Symfony's AnalyzeServiceReferencesPassTest to cause the segfault in a simpler way than running Drupal 8 tests - unfortunately no luck yet.
Comment #20
alexpottSo lol... in the PHPUnit bootstrap.inc for the dependency injection component in Symfony there is the following line of code...
Comment #21
alexpottFunnily enough though running the tests with PHP 7, 5.6 and 5.5 does not produce any segfaults unfortunately.
Comment #22
dawehnerAlright, let's all not stop shaking our head for a while.
Comment #23
alexpottSo there is a trade-off to do this - we will end using more memory. I guess the questions are (a) will we get a fix in PHP7 before we launch. (b) what is the memory cost of doing this.
If we don't get a fix in PHP7 - scheduled to be release on Nov 12th and the memory cost of doing #13 is acceptable then I think this is a better workaround than making PHP7 support experimental.
Comment #24
catchIf we have to we can do a version check before the gc change.
Also we should get that simpletest memory patch in now that pifr is off.
Comment #25
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Drupal Association commented#23: Please see #13, where we do collect the cycles before disabling the GC.
So we have all memory freed before rebuilding the container, which makes sense and should not take long.
And yes we can add a version check.
Comment #26
alexpottre #25 so even with
gc_disable()
it still stores roots - see https://secure.php.net/manual/en/features.gc.collecting-cycles.phpComment #27
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Drupal Association commentedI think we don't even need to disable the GC, just collecting cycles before compiling the container should be enough to not trigger the GC during the graph operation.
I added tracing to zend_gc_collect_cycles() and it is pretty much always called. Of notice is that also the crash happens after zend_gc_collect_cycles().
The GC is called during container compilation anyway and the reason is that the GC buffer can only hold 10'000 potential roots, so if lots of objects are created and destroyed, then this easily gets over this limit, so PHP7 must call the GC.
Comment #28
Wim LeersInteresting!
Comment #29
Wim Leers#18:
@rasmus tweeted about this fix (https://twitter.com/rasmus/status/659953498293858304) and so I took a bit of a deeper look at PHP's git repo. It seems they periodically merge the 7.0 branch into 7.0.0 (http://git.php.net/?p=php-src.git;a=commit;h=40142c084a28a6266b7b781778c...). OTOH, the 7.0 branch got a commit saying "7.0.1 is next". So I'm not at all certain. Hence I simply asked Rasmus on Twitter: https://twitter.com/wimleers/status/660008466925428736.
Comment #30
Wim LeersRasmus answered: https://twitter.com/rasmus/status/660092777523314688
So, we're good :)
Comment #31
alexpottBased on the fact that the last fails are all related to https://bugs.php.net/bug.php?id=70805 and we still have #2454439: [META] Support PHP 7 to track any issues I'm downgrading this to major and postponing - since we'll only need to do something here if PHP fail to fix that bug before release - given the attention that seems unlikely. If we do need to do something this will be an rc target so mark as such.
Comment #32
alexpottWho knows which tag to use :)
Comment #33
alexpott@catch said that we should have a green PHP7 green and commit a patch doing PHP7 only fixes to make regressions easier to spot. Seems like a good idea. The patch attached is green on PHP7 RC6 for me.
Comment #34
alexpottHere's the gc only patch - so we can have separate commits for each fix.
Comment #35
neclimdulWorks for me too! We're working to get something easy for the PHP devs to recreate the GC bug so it won't really get fixed until we can do that. This will allow us to ensure no regressions in the interim.
I'm not picky about how things get committed but both patches look good for what they do and the first came back green so RTBC.
Comment #37
catchCommitted/pushed to 8.0.x, thanks! (As two separate commits so we can do a clean revert individually).
Marking this issue fixed since we're at 100% pass.
We can now post revert patches on #2454439: [META] Support PHP 7 for retesting as PHP 7 builds include the fixes - that can stay critical and maybe postponed to have a fully green PHP 7 test run with no hacks.
Comment #38
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Drupal Association commentedD8 Accelerate sponsored neclimdul and me for 10 hours (5 each), so re-adding tag for that.
Comment #42
neclimdulmegh, testbot
Comment #43
dawehnerNice work!!!