Error when clearing cache and on update.php

Mike_Waters - October 25, 2008 - 05:01
Project:Cache Router
Version:6.x-1.x-dev
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:closed
Description

When I clear the cache my cache, I recv the following error (several instances of it):

Invalid argument supplied for foreach() in /var/www/drupal-6/sites/all/modules/cacherouter/engines/apc.php on line 121

That line resides in the delete() function (which makes sense).
  function delete($key) {
    // Remove from static array cache.
    parent::delete($key);
   
    if (substr($key, -1, 1) == '*') {
      $key = substr($key, 0, strlen($key) - 1);
      $lookup = apc_fetch($this->lookup);
      foreach ($lookup as $k => $v) {  <--- line 121
        if (substr($k, 0, strlen($key) - 1)) {
          apc_delete($k);
          unset($lookup[$k]); 
        }
      }

(IIRC)I also had this problem with xcache installed (obviously it would say xcache.php, but I removed xcache for other reasons so I cannot say for sure).

I haven't done any real debugging, but with some print_r()'s to syslog it looks like apc_fetch is sometimes returning an empty array ('Array()'). In my case, the original $key/s passed to that function that caused apc_fetch to return an empty array were 'links:devel:*', 'links:navigation:*', and '*'.
I do not know how to go any further w/o a debugger (like, who is the caller, did those $keys ever get apc_store'd, etc..).

I am using Drupal 6.6/debian lenny kernel 2.6.24-19-xen x86_64/apache2/php5+suhoisin patch/APC-3.0.19 on a VPS, and am using the latest cacherouter files from CVS.

Thanks,
Mike Waters

#1

Mike_Waters - October 30, 2008 - 00:25

SOLUTION: (?)
The code doesn't check for a FALSE return value of apc_fetch(), so $lookup is sometimes FALSE/0. When php tries to parse 0 into an associative array, the error handler is invoked.
I don't know how to create a patch, but you want to replace

      $lookup = apc_fetch($this->lookup);

        foreach ($lookup as $k => $v) {
         
          if (substr($k, 0, strlen($key) - 1)) {
            apc_delete($k);
            unset($lookup[$k]); 
          }
        }

with
      $lookup = apc_fetch($this->lookup);
      if ($lookup != FALSE) {

        foreach ($lookup as $k => $v) {
         
          if (substr($k, 0, strlen($key) - 1)) {
            apc_delete($k);
            unset($lookup[$k]); 
          }
        }
      }

at line 120 of engines/apc.php.

I don't know much about the apc engine, so I can't say whether or not it is correct for apc_fetch() to ever return FALSE, and so can't say that this is a valid solution.
Wish I could help more, but I am debugging a remote server (across the country) so I only have what source code xdebug sends to my IDE over the wire (there's no 'step backward', and if I 'step into'd through the entire drupal bootstrap my F11 key would have blood on it ;).

Thanks for the great module.
-Mike Waters

#2

slantview - October 31, 2008 - 01:06
Status:active» postponed (maintainer needs more info)

Can you tell me what version you are using? In the latest version, before I run over the lookup table, I check if it is "empty" with the php empty() function. Per the documentation on php.net:

Return Values

Returns FALSE if var has a non-empty and non-zero value.

The following things are considered to be empty:

    * "" (an empty string)
    * 0 (0 as an integer)
    * "0" (0 as a string)
    * NULL
    * FALSE
    * array() (an empty array)
    * var $var; (a variable declared, but without a value in a class)

You can see that in apc.php on line 158.

<?php
 
function flush() {
   
$this->lock();

   
// Get lookup table to be able to keep track of bins
   
$lookup = apc_fetch('lookup_' . $this->name);

   
// If the lookup table is empty, remove lock and return
   
if (empty($lookup)) {
     
$this->unlock();
      return
TRUE;
    }

   
// Cycle through keys and remove each entry from the cache
   
foreach ($lookup as $k => $v) {
      if (
apc_delete($k)) {
        unset(
$lookup[$k]);
      }
    }

   
// Resave the lookup table (even on failure)
   
apc_store('lookup_' . $this->name, $lookup);

   
// Remove lock
   
$this->unlock();

    return
TRUE;
  }
?>

#3

Mike_Waters - November 8, 2008 - 23:25

I am using the version from CVS as of 10/25/08. My copy of apc.php is identical to what you've posted.

Why would cache clearing even hit the delete() function? It looks like flush() calls apc_delete() directly.
Something I probably should have noted is that this error was the result of using the Devel modules 'Clear cache' function. It did not occur to me that Devel might use a separate cache clearing implementation; does it?.
(Note that I am not saying that Site Configuration->Performance->Clear Cache *didn't* cause the error, because I don't use it and so don't know.)

EDIT: migrating to the cvs version caused the apc_fix_lock patch to revert. Could this have anything to do with it?

Thanks,
Mike Waters

#4

michtoen - February 27, 2009 - 15:32

i got the same error using apc with current release version and d6.10

i had cache browser and cache_path installed too

#5

aaronshaf - April 14, 2009 - 05:42

Same problem here

#6

kenorb - April 24, 2009 - 20:40

same problem

#7

Flying Drupalist - April 30, 2009 - 01:54

And here too!

Edit: Not getting this anymore when updated to latest dev.

#8

michtoen - April 30, 2009 - 02:13

It seems to me it happens when the cache table is clear or fresh.

I don't get that when i clear the cache here and there but when i install modules or remove and
then i clear the cache by hand 1 or 2 times, then it happens.

Because the error msg is in a forearch() it smells a bit like an empty var run.

#9

sidharth_k - June 7, 2009 - 06:46

subscribing

#10

a_c_m - June 8, 2009 - 09:53

same problem

#11

kenorb - July 14, 2009 - 18:52
Status:postponed (maintainer needs more info)» active

Marking #494878: repeatin, growing list of "Invalid argument supplied for foreach()" warnings when using APC backend as duplicate.

#12

kenorb - July 14, 2009 - 18:53
Title:Error when clearing cache» Error when clearing cache and on update.php

The same error on update.php
Is this module is abandoned?

#13

slantview - September 3, 2009 - 10:31
Status:active» fixed

This is fixed now.

#14

System Message - September 17, 2009 - 10:40
Status:fixed» closed

Automatically closed -- issue fixed for 2 weeks with no activity.

 
 

Drupal is a registered trademark of Dries Buytaert.