Page MenuHomePhabricator

Divide by zero in PRSquare
Closed, ResolvedPublic

Description

Spotted in wmf.20:

Warning: Division by zero in /srv/mediawiki/php-1.31.0-wmf.20/vendor/wikimedia/running-stat/src/Wikimedia/PSquare.php on line 159

Also reports from line 158. The math in computeParabolic() needs looking at. Sadly no stacktrace, so I'm kinda blind as to what's passing bad info to this (throw an exception?)

Event Timeline

demon triaged this task as Normal priority.Feb 9 2018, 12:38 AM
demon created this task.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptFeb 9 2018, 12:38 AM
demon added a subscriber: Anomie.

I lied! I do have a stacktrace:

#0 /srv/mediawiki/php-1.31.0-wmf.20/vendor/wikimedia/running-stat/src/Wikimedia/PSquare.php(159): MWExceptionHandler::handleError(integer, string, string, integer, array, array)
#1 /srv/mediawiki/php-1.31.0-wmf.20/vendor/wikimedia/running-stat/src/Wikimedia/PSquare.php(123): Wikimedia\PSquare->computeParabolic(integer, integer)
#2 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/common/Hooks.php(218): Wikimedia\PSquare->addObservation(integer)
#3 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/common/Hooks.php(135): ScribuntoHooks::reportTiming(string, string, integer)
#4 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3407): ScribuntoHooks::invokeHook(Parser, PPFrame_Hash, array)
#5 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3108): Parser->callParserFunction(PPFrame_Hash, string, array)
#6 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPFrame_Hash)
#7 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(2923): PPFrame_Hash->expand(PPNode_Hash_Tree, integer)
#8 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(696): Parser->replaceVariables(string, PPFrame_Hash)
#9 /srv/mediawiki/php-1.31.0-wmf.20/includes/api/ApiExpandTemplates.php(124): Parser->preprocess(string, Title, ParserOptions, NULL, PPFrame_Hash)
#10 /srv/mediawiki/php-1.31.0-wmf.20/includes/api/ApiMain.php(1580): ApiExpandTemplates->execute()
#11 /srv/mediawiki/php-1.31.0-wmf.20/includes/api/ApiMain.php(542): ApiMain->executeAction()
#12 /srv/mediawiki/php-1.31.0-wmf.20/includes/api/ApiMain.php(513): ApiMain->executeActionWithErrorHandling()
#13 /srv/mediawiki/php-1.31.0-wmf.20/api.php(94): ApiMain->execute()
#14 /srv/mediawiki/w/api.php(3): include(string)
#15 {main}

All of them seem to involve ApiExpandTemplates, so there narrowed it a tad already :)

Wait, I lied. Here's one from Parsoid's API:

#0 /srv/mediawiki/php-1.31.0-wmf.20/vendor/wikimedia/running-stat/src/Wikimedia/PSquare.php(159): MWExceptionHandler::handleError(integer, string, string, integer, array, array)
#1 /srv/mediawiki/php-1.31.0-wmf.20/vendor/wikimedia/running-stat/src/Wikimedia/PSquare.php(123): Wikimedia\PSquare->computeParabolic(integer, integer)
#2 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/common/Hooks.php(218): Wikimedia\PSquare->addObservation(integer)
#3 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/common/Hooks.php(135): ScribuntoHooks::reportTiming(string, string, integer)
#4 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3407): ScribuntoHooks::invokeHook(Parser, PPTemplateFrame_Hash, array)
#5 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3108): Parser->callParserFunction(PPTemplateFrame_Hash, string, array)
#6 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPTemplateFrame_Hash)
#7 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3286): PPFrame_Hash->expand(PPNode_Hash_Tree)
#8 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPTemplateFrame_Hash)
#9 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3286): PPFrame_Hash->expand(PPNode_Hash_Tree)
#10 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPFrame_Hash)
#11 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1614): PPFrame_Hash->expand(PPNode_Hash_Tree, integer)
#12 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1626): PPTemplateFrame_Hash->getNamedArgument(string)
#13 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3782): PPTemplateFrame_Hash->getArgument(string)
#14 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1119): Parser->argSubstitution(array, PPTemplateFrame_Hash)
#15 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1614): PPFrame_Hash->expand(PPNode_Hash_Tree, integer)
#16 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1626): PPTemplateFrame_Hash->getNamedArgument(string)
#17 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3782): PPTemplateFrame_Hash->getArgument(string)
#18 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1119): Parser->argSubstitution(array, PPTemplateFrame_Hash)
#19 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3026): PPFrame_Hash->expand(PPNode_Hash_Tree)
#20 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPTemplateFrame_Hash)
#21 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3286): PPFrame_Hash->expand(PPNode_Hash_Tree)
#22 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPTemplateFrame_Hash)
#23 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3286): PPFrame_Hash->expand(PPNode_Hash_Tree)
#24 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPFrame_Hash)
#25 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(2923): PPFrame_Hash->expand(PPNode_Hash_Tree, integer)
#26 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(696): Parser->replaceVariables(string, PPFrame_Hash)
#27 /srv/mediawiki/php-1.31.0-wmf.20/extensions/ParsoidBatchAPI/includes/ApiParsoidBatch.php(273): Parser->preprocess(string, Title, ParserOptions, integer)
#28 /srv/mediawiki/php-1.31.0-wmf.20/extensions/ParsoidBatchAPI/includes/ApiParsoidBatch.php(150): ApiParsoidBatch->preprocess(string, Title, integer)
#29 /srv/mediawiki/php-1.31.0-wmf.20/includes/api/ApiMain.php(1580): ApiParsoidBatch->execute()
#30 /srv/mediawiki/php-1.31.0-wmf.20/includes/api/ApiMain.php(542): ApiMain->executeAction()
#31 /srv/mediawiki/php-1.31.0-wmf.20/includes/api/ApiMain.php(513): ApiMain->executeActionWithErrorHandling()
#32 /srv/mediawiki/php-1.31.0-wmf.20/api.php(94): ApiMain->execute()
#33 /srv/mediawiki/w/api.php(3): include(string)
#34 {main}

Both seem to go through Scribunto though. cc @Anomie for API/Scribunto

This seems to have nothing to do with the API, here's one that's not via the API at all:

#0 /srv/mediawiki/php-1.31.0-wmf.20/vendor/wikimedia/running-stat/src/Wikimedia/PSquare.php(159): MWExceptionHandler::handleError(integer, string, string, integer, array, array)
#1 /srv/mediawiki/php-1.31.0-wmf.20/vendor/wikimedia/running-stat/src/Wikimedia/PSquare.php(123): Wikimedia\PSquare->computeParabolic(integer, integer)
#2 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/common/Hooks.php(218): Wikimedia\PSquare->addObservation(integer)
#3 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/common/Hooks.php(135): ScribuntoHooks::reportTiming(string, string, integer)
#4 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3407): ScribuntoHooks::invokeHook(Parser, PPTemplateFrame_Hash, array)
#5 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3108): Parser->callParserFunction(PPTemplateFrame_Hash, string, array)
#6 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPTemplateFrame_Hash)
#7 /srv/mediawiki/php-1.31.0-wmf.20/extensions/ParserFunctions/ParserFunctions_body.php(123): PPFrame_Hash->expand(PPNode_Hash_Tree)
#8 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3407): ExtParserFunctions::ifeqObj(Parser, PPTemplateFrame_Hash, array)
#9 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3108): Parser->callParserFunction(PPTemplateFrame_Hash, string, array)
#10 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPTemplateFrame_Hash)
#11 /srv/mediawiki/php-1.31.0-wmf.20/extensions/ParserFunctions/ParserFunctions_body.php(125): PPFrame_Hash->expand(PPNode_Hash_Tree)
#12 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3407): ExtParserFunctions::ifeqObj(Parser, PPTemplateFrame_Hash, array)
#13 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3108): Parser->callParserFunction(PPTemplateFrame_Hash, string, array)
#14 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPTemplateFrame_Hash)
#15 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/engines/LuaCommon/LuaCommon.php(889): PPFrame_Hash->expand(PPNode_Hash_Tree)
#16 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/engines/LuaCommon/LuaCommon.php(724): Scribunto_LuaEngine->doCachedExpansion(PPTemplateFrame_Hash, PPNode_Hash_Tree, array)
#17 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/engines/LuaSandbox/Engine.php(385): Scribunto_LuaEngine->expandTemplate(string, string, array)
#18 [internal function]: Scribunto_LuaSandboxCallback->__call(string, array)
#19 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/engines/LuaSandbox/Engine.php(313): LuaSandboxFunction->call(LuaSandboxFunction)
#20 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/engines/LuaCommon/LuaCommon.php(296): Scribunto_LuaSandboxInterpreter->callFunction(LuaSandboxFunction, LuaSandboxFunction)
#21 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/engines/LuaCommon/LuaCommon.php(963): Scribunto_LuaEngine->executeFunctionChunk(LuaSandboxFunction, PPTemplateFrame_Hash)
#22 /srv/mediawiki/php-1.31.0-wmf.20/extensions/Scribunto/common/Hooks.php(127): Scribunto_LuaModule->invoke(string, PPTemplateFrame_Hash)
#23 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3407): ScribuntoHooks::invokeHook(Parser, PPTemplateFrame_Hash, array)
#24 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3108): Parser->callParserFunction(PPTemplateFrame_Hash, string, array)
#25 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPTemplateFrame_Hash)
#26 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(3286): PPFrame_Hash->expand(PPNode_Hash_Tree)
#27 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Preprocessor_Hash.php(1102): Parser->braceSubstitution(array, PPFrame_Hash)
#28 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(2923): PPFrame_Hash->expand(PPNode_Hash_Tree, integer)
#29 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(1282): Parser->replaceVariables(string)
#30 /srv/mediawiki/php-1.31.0-wmf.20/includes/parser/Parser.php(443): Parser->internalParse(string)
#31 /srv/mediawiki/php-1.31.0-wmf.20/includes/content/WikitextContent.php(329): Parser->parse(string, Title, ParserOptions, boolean, boolean, integer)
#32 /srv/mediawiki/php-1.31.0-wmf.20/includes/content/AbstractContent.php(516): WikitextContent->fillParserOutput(Title, integer, ParserOptions, boolean, ParserOutput)
#33 /srv/mediawiki/php-1.31.0-wmf.20/includes/poolcounter/PoolWorkArticleView.php(145): AbstractContent->getParserOutput(Title, integer, ParserOptions)
#34 /srv/mediawiki/php-1.31.0-wmf.20/includes/poolcounter/PoolCounterWork.php(123): PoolWorkArticleView->doWork()
#35 /srv/mediawiki/php-1.31.0-wmf.20/includes/page/Article.php(597): PoolCounterWork->execute()
#36 /srv/mediawiki/php-1.31.0-wmf.20/includes/actions/ViewAction.php(68): Article->view()
#37 /srv/mediawiki/php-1.31.0-wmf.20/includes/MediaWiki.php(500): ViewAction->show()
#38 /srv/mediawiki/php-1.31.0-wmf.20/includes/MediaWiki.php(294): MediaWiki->performAction(Article, Title)
#39 /srv/mediawiki/php-1.31.0-wmf.20/includes/MediaWiki.php(858): MediaWiki->performRequest()
#40 /srv/mediawiki/php-1.31.0-wmf.20/includes/MediaWiki.php(524): MediaWiki->main()
#41 /srv/mediawiki/php-1.31.0-wmf.20/index.php(42): MediaWiki->run()
#42 /srv/mediawiki/w/index.php(3): include(string)
#43 {main}

And it doesn't really have anything to do with Scribunto either, as far as I can tell, beyond that someone added a use of PSquare into Scribunto at some point to try to measure some timing statistics. The relevant code (trimmed for readability) in Scribunto is:

$cache = ObjectCache::getLocalServerInstance( CACHE_NONE );
$key = $cache->makeGlobalKey( __METHOD__, $threshold );
$ps = $cache->get( $key ) ?: new PSquare( $threshold );
$ps->addObservation( $timing );
$cache->set( $key, $ps, 60 );

I suspect this error is fallout from the "undefined index" messages coming from PSquare. It seems that somehow or other it's getting an instance of PSquare that's missing its positions array, which thanks to PHP type-munging winds up being treated as [ 0, 0, 0, 0, 0 ]. Some of those zeros get incremented at various points. If it gets to line 159 and the array still has multiple indexes with the same value, it winds up dividing by 0.

PHP serializes private fields with the defining class name included, and rMWVDd0f42c24ced2: Update wikimedia dependancies (merged in wmf.20) changed the class name from "RunningStat\PSquare" to "Wikimedia\PSquare" with a subclass under the old name as a fallback. So the "somehow or other" would be that unserialization of "RunningStat\PSquare" instances cached in wmf.17 isn't setting the private variables that are now defined in "Wikimedia\PSquare".

Anomie added a comment.Feb 9 2018, 3:15 PM

TL;DR: Changes to wikimedia/running-stat between the version included in wmf.17 and the version included in wmf.20 broke PHP serialization compatibility in a non-obvious way, and this error message is part of the fallout.

Change 409411 had a related patch set uploaded (by Legoktm; owner: Legoktm):
[mediawiki/extensions/Scribunto@master] Invalidate slow function call cache to avoid warnings

https://gerrit.wikimedia.org/r/409411

Change 409411 merged by jenkins-bot:
[mediawiki/extensions/Scribunto@master] Invalidate slow function call cache to avoid warnings

https://gerrit.wikimedia.org/r/409411

Change 409415 had a related patch set uploaded (by Chad; owner: Legoktm):
[mediawiki/extensions/Scribunto@wmf/1.31.0-wmf.20] Invalidate slow function call cache to avoid warnings

https://gerrit.wikimedia.org/r/409415

Change 409415 merged by Chad:
[mediawiki/extensions/Scribunto@wmf/1.31.0-wmf.20] Invalidate slow function call cache to avoid warnings

https://gerrit.wikimedia.org/r/409415

demon closed this task as Resolved.Feb 9 2018, 7:51 PM