Hello, again.

Yesterday I started getting these problems:

  • I can no longer attach images to nodes using image_attach
  • If I try to use img_assist, I get this: Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 12000 bytes) in [drupal_path]/includes/image.gd.inc on line 190
  • Every now and again, I get the message that an image's derivative images are being rebuilt (it's always the same image)

The last item was the clue...

I had tried to upload an image yesterday, but accidentally chose the print-ready version (which was very large, say 3000x3000). If I remember correctly, it either got an out-of-memory error, or I stopped uploading midway through. So, I hit "back" on the browser, chose the correct file, and uploaded that one instead.

Well, apparently the large file still uploaded - I can see both when I administer the content. But if I try to delete the wrong one, I get the out-of-memory error described above.

For some reason, it's calling image.gd.inc even when the node is being deleted. So I have no way of getting rid of the problem, hence no way of using image.module or image.gd.inc ever again. (I'm using a webhost, I can't set the memory limit any higher.)

I have MySQL access via phpMyAdmin. Is there a way to delete the node by hand?

Comments

Karlheinz’s picture

More information:

Searching the database, I know that the fid's for the original, thumbnail, and preview are 251, 252, and 253 respectively; the nid is 73.

If I simply delete these entries from the files, image, and node tables, would this do it?

EDIT: Yes, apparently it would.

It would still be nice if you could delete the node without going through GD, however.

joachim’s picture

Did you try deleting the node through the node admin page?

> For some reason, it's calling image.gd.inc even when the node is being deleted.
This sounds a bit rubbish but it may be there is no way round this if node deletion calls a node_load first.

Karlheinz’s picture

Did you try deleting the node through the node admin page?

If you mean going to Administer > Content, that's the first thing I tried. I got to the page that asked "Are you sure you want to delete these items?" and if I hit Delete All, I got the out-of-memory error.

This sounds a bit rubbish but it may be there is no way round this if node deletion calls a node_load first.

It does:

function node_delete($nid) {

  $node = node_load($nid);

  if (node_access('delete', $node)) {
    db_query('DELETE FROM {node} WHERE nid = %d', $node->nid);
    db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid);

    // Call the node-specific callback (if any):
    node_invoke($node, 'delete');
    node_invoke_nodeapi($node, 'delete');

    // Clear the page and block caches.
    cache_clear_all();

    // Remove this node from the search index if needed.
    if (function_exists('search_wipe')) {
      search_wipe($node->nid, 'node');
    }
    watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title));
    drupal_set_message(t('@type %title has been deleted.', array('@type' => node_get_types('name', $node), '%title' => $node->title)));
  }
}

So I'm guessing that there is no way to fix this?

joachim’s picture

Status: Active » Closed (works as designed)

Looks like.
Marking as 'by design' even though the design has a flaw... :/

Filed this on core: #516922: node_delete calls node_load -- means problem nodes can't be deleted

joachim’s picture

Category: support » bug
Status: Closed (works as designed) » Active

It's been suggested on that core issue that the derivative regenerating should take place in hook_view. Reopening to discuss this.

Karlheinz’s picture

I am no API expert by any means. But wouldn't hook_insert() and hook_update() be a more logical place for image resizing?

On the other hand, if moving the code to hook_view() resolves the issue, then I see no reason not to do it.

My two cents.

joachim’s picture

No, because the admin may have changed derivative sizes in the meantime -- in other words, the node could be stale even if it hasn't been edited directly.
Of course image_cache doesn't bother with this case at all -- it just gives you the flush mechanism to redo all of a size if you DO change it. Perhaps we're doing too much for the user here!

joachim’s picture

Status: Active » Closed (duplicate)

Marking this as a duplicate of #226121: don't manipulate images on hook_load.
Different problem, same cause.

TallFurryMan’s picture

Quick and dirty workaround when this happens:

- Download "includes/image.gd.inc" from your host server and edit it.
- In function "image_gd_open()", change "$open_func($file)" to "imagecreatetruecolor(512,512)".
- Upload "image.gd.inc" back to your host server.
- Access your website's main page.

There you should see a log of all problematic images regenerating their derivatives (or at least that log will include the problematic ones). Those thumbnails will then all render as black pictures, and you may then delete the corresponding nodes in the administration screen.

Of course you should roll the modifications in "image.gd.inc" back afterwards, else future image imports will turn black too.

Hope this helps.

Karlheinz’s picture

Yikes. Deliberately breaking a core Drupal include seems a bit drastic to me. Seems more logical just to delete the database entries.

In any case, I believe this issue is fixed.

pjkwis’s picture

But how do you prevent that error from happening again? My memory limit is already 32.

joachim’s picture

If you're using images your PHP memory limit should be 64 at least, and more like 96.

stephenrobinson’s picture

Change your php limit in your php.ini file to 128 or 256, avaids white screening (WSOD).

Karlheinz’s picture

From the other (duplicate) issue, I believe the resizing function was moved to hook_view, yes?

If so, then you should be able to delete the problem node at least.

If you run out of memory, the only thing you can really do is upload smaller files.