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

Endless recursion when destructing DataTable after flattening Keywords report #3191

Closed
timo-bes opened this issue Jun 4, 2012 · 8 comments
Closed
Labels
Bug For errors / faults / flaws / inconsistencies etc. Major Indicates the severity or impact or benefit of an issue is much higher than normal but not critical. worksforme The issue cannot be reproduced and things work as intended.
Milestone

Comments

@timo-bes
Copy link
Member

timo-bes commented Jun 4, 2012

I just noticed a bug on the demo.

  1. Go here: http://demo.piwik.org/index.php?module=CoreHome&action=index&idSite=7&period=day&date=2012-06-03#module=Referers&action=getSearchEnginesAndKeywords&idSite=7&period=day&date=2012-06-03
  2. Flatten the keywords report

It works fine, but you get this error beneath the table:

Fatal error: Maximum function nesting level of '100' reached, aborting! in /home/www/dev5.piwik.org/core/Common.php on line 1884
Call Stack
#   Time    Memory  Function    Location
1   3.5278  116336488   Piwik_DataTable->__destruct( )  ../DataTable.php:0
2   3.5279  116320216   destroy( )  ../DataTable.php:274
3   3.5279  116320216   Piwik_DataTable_Row->__destruct( )  ../Common.php:1884
4   3.5279  116320216   Piwik_DataTable_Manager->deleteTable( ) ../Row.php:98
5   3.5280  116320216   Piwik_DataTable_Manager->setTableDeleted( ) ../Manager.php:105
6   3.5280  116320216   Piwik_DataTable->__destruct( )  ../DataTable.php:0
7   3.5280  116320416   destroy( )  ../DataTable.php:274
8   3.5280  116320416   Piwik_DataTable_Row->__destruct( )  ../Common.php:1884
9   3.5280  116320416   Piwik_DataTable_Manager->deleteTable( ) ../Row.php:98
10  3.5280  116320416   Piwik_DataTable_Manager->setTableDeleted( ) ../Manager.php:105
11  3.5280  116320528   Piwik_DataTable->__destruct( )  ../DataTable.php:0
12  3.5281  116321384   destroy( )  ../DataTable.php:274
.....
.....

The report is built correctly but an endless (?) recursion occurs when the tables should be destructed and the program crashes.

My guess: The Flattener loads DataTables directly from the archive. I think they have the IDs from the archive, not the ones from the DataTableManager. There is no way to discern the two cases when you have a DataTable instance. The __desctruct() method of DataTable_Row asks the manager to destroy its associated table by passing the ID. Maybe it's because of the ambiguous meaning of the DataTable IDs that a cicle starts.

Unfortunately, I cannot reproduce the problem to debug the DataTable IDs that are passed around. Can anybody reproduce? If you can, please debug $this->currentId in Piwik_DataTable::__destruct() (or something similar). If nobody can reproduce the problem, can you debug on the demo, Matt?

@julienmoumne
Copy link
Member

We also experience endless recursions when generating PDF/HTML reports. See http://forum.piwik.org/read.php?2,90170,page=1#msg-90670 and #3207

It doesn't seem to be the same case though, see stack trace : http://pastebin.com/Kdrkb7V9

@julienmoumne
Copy link
Member

I have been able to confirm Timo's assumptions with real data.

The cause of this endless recursion is the same as in #3207.

[EDIT] I don't think it's the case anymore. See comments bellow.

@julienmoumne
Copy link
Member

Also, I have a strong suspicion that on demo.piwik.org, those two lines (https://github.com/piwik/piwik/blob/master/core/DataTable/Manager.php#L105) are reversed :

105             $this->setTableDeleted($id);
106             destroy($this->tables[$id]);

Otherwise the recursion would not happen.

[EDIT] Well actually, from the log it seems those two lines are in sync with trunk. This has also been confirmed by Matt.

How can the table be destroyed ?

$this->tables[$id] returns null because of $this->setTableDeleted($id).

destroy(null) should therefore not trigger destruct().

The following log entry

Piwik_DataTable->__destruct( )  ../DataTable.php:0

is actually triggered by the garbage collector, right?

@julienmoumne
Copy link
Member

I also don't understand how we can ever have a loop considering there is a mechanism to limit the depth in https://github.com/piwik/piwik/blob/master/core/DataTable.php#L269

265     public function __destruct()
266     {
267         static $depth = 0;
268         // destruct can be called several times
269         if($depth < self::$maximumDepthLevelAllowed
270             && isset($this->rows))
271         {
272             $depth++;

maximumDepthLevelAllowed is set to 15 or to 'action_category_level_limit' (10).

Does this mean that every call to destruct is made an a fresh object with depth reseted to 0 ?

[The stack trace in the ticket description is misleading. If you go and trigger http://demo.piwik.org/index.php?filter_column=label&filter_column_recursive=label&idGoal=-1&filter_sort_order=desc&filter_offset=0&keep_summary_row=0&module=Referers&action=getKeywords&idSite=7&period=day&date=2012-06-03&enable_sort=1&filter_sort_column=nb_visits&filter_limit=25&viewDataTable=table&controllerActionCalledWhenRequestSubTable=getSearchEnginesFromKeywordId&totalRows=168&flat=1 the stack trace on demo.piwik.org

you'll see that it doesn't end with the lines quoted in this ticket description :

85  3.4397  115326504   Piwik_DataTable_Row->__destruct( )  ../Row.php:0
86  3.4397  115326504   Piwik_DataTable_Manager->deleteTable( ) ../Row.php:98
87  3.4397  115326632   Piwik_DataTable_Manager->setTableDeleted( ) ../Manager.php:105
88  3.4402  115161360   Piwik_DataTable_Row->__destruct( )  ../Row.php:0
89  3.4402  115161360   Piwik_DataTable_Manager->deleteTable( ) ../Row.php:98
90  3.4402  115161488   Piwik_DataTable_Manager->setTableDeleted( ) ../Manager.php:105
91  3.4407  114986760   Piwik_DataTable_Row->__destruct( )  ../Row.php:0

If there is a loop, it is not in Piwik_DataTable. This is why the depth limiting mechanism is not in action.

@julienmoumne
Copy link
Member

I am reverting the name of this ticket to the one Timo originally gave because I don't think anymore that it is related to the issue we are having with Truncate filter in #3207. Sorry for the confusion.

@julienmoumne
Copy link
Member

Here is the complete stack trace : http://pastebin.com/bPt5pt2U

If you look closely at the end, there does not seem to be a loop going on.

I am waiting for Matt to set xdebug.max_nesting_level to 500

@julienmoumne
Copy link
Member

As expected, after increasing xdebug.max_nesting_level to 500 the fatal error does not occur any-more. There was no infinite recursion.

@julienmoumne
Copy link
Member

There was no infinite recursion but Timo did find a core problem in the way Piwik_DataTable identifiers are handled by Piwik_DataTable_Manager. See follow up ticket #3263.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug For errors / faults / flaws / inconsistencies etc. Major Indicates the severity or impact or benefit of an issue is much higher than normal but not critical. worksforme The issue cannot be reproduced and things work as intended.
Projects
None yet
Development

No branches or pull requests

3 participants