0

I have developed my little module for Drupal 7 and it has been working fine. But suddenly it started to cause a memory crush. Now I can't even enable it (drush en ModuleName) with the error message of:

Error: Allowed memory size of 536870912 bytes exhausted [...] in /MY/DRUPAL/ROOT/includes/module.inc, line 596

The line number, where it fails, varies sometimes. I clear the cache (drush cc all) frequently or practically at every step, so I don't think it is cache-related. The allowed memory for PHP and SQL are both 512MB, and the website is mini-scale with no load-hungry module. The memory should be a way more than enough.

The module is just a little language switcher with only a *.module file (and *.info), and has no major loop — One time loop for an enabled couple of languages is all it has. No recursive call whatsoever. So, I have no idea where to look for to pin down the problem… Only the potential thing I could think of is I had deleted a (unnecessary) path-alias directly via SQL (a row in Table url_alias), immediately before this trouble started. It being the language-switcher, it accesses to drupal_get_path_alias(), but does it matter?

In case you are interested, my little module is available in GitHub:
https://github.com/masasakano/lang_switcher_advanced

[Edit]
It seems the problem was tracked down and I posted it as the answer. Everything one'd need is written in it, but just to note, the example codes before and after it was solved are tagged as 0.1.1 and 0.1.2 in the above GitHub repository.

15
  • 3
    I think you meant crash? Crush means romantic feelings, and while I can believe some devs love their machines, I'm sure it is not exactly what you wanted to say ;)
    – Mołot
    Oct 21, 2014 at 13:16
  • This question appears to be off-topic because it is about code you wrote, for which you want to write better code, or you want to understand why it doesn't work, but you didn't show the code you are using, or the part of the code that is relevant for the question. See Help Center.
    – Mołot
    Oct 21, 2014 at 13:17
  • Thank you for the comment. The entire code is available in the URI I cited, as I mentioned! It is not a large code, but I am afraid is large enough to copy and paste here. I would love to show a relevant part here, but again as I mentioned I don't have a clue which part is causing a problem... So I am wondering if there is a point to start for to investigate this type of memory trouble in general... Oct 21, 2014 at 13:26
  • 1
    Links to external resources are not considered valid content here. Can you guarantee that this server will always be online when your question is? That content licence will stay compatible with Stack Exchange's one? And so on. Also, we are not a free debug service, so you should at least try to identify the relevant part of code yourself. If you can't, +-10 lines from the points it fails would be good. If it usually happens in loop, post that loop. Small things like that.
    – Mołot
    Oct 21, 2014 at 13:29
  • 1
    @MasaSakano I know this isn't what you're question is about, but looking at the code, I can't help but notice that you have a couple of weird constructs in there. I think you could cut down significantly on the code base (and fix some issues) by using the appropriate drupal functions. Start with a look at l. I'm in the Drupal Answers Chat if you want to discuss further.
    – Letharion
    Oct 21, 2014 at 15:07

2 Answers 2

3

A short answer for the question is to check the function names defined in the module. If there is any conflict with the existing function names, that can give a trouble when enabling the module. Also, it may be advisable to disable and enable the module, whenever you add a function to the module, maybe, to detect a potential trouble at the earliest opportunity.
--The following appended--
Another preventive ways: (1) Keep only hook_ functions in a *.module file, (2) for D7, name always your private functions with a little convention, for example, add the prefix of _: e.g., function _myfunction_theme().
--Appended up to here--

It turned out the function name My_Module_Name_theme() conflicts with hook_theme() in Drupal. I was not using it as my intention, but the code of the function was left for the future development - that caused a trouble, as it was regarded as a valid hook by Drupal, whatever the programmer's intention was. The arguments given to a call of another Drupal function in that function were not compatible with the Drupal function. That may have lead to the memory exhaustion.

My guess is, since it is the name of the function (or maybe because it is a hook?), that caused a memory exhaustion while enabling the module rather than during run-time. I added the function in the module when the module had been already enabled. At that time (I mean, after I added the function), the module caused no trouble and kept functioning as I intended. It is possibly because the function names were not registered to Drupal? I don't know, but whichever, it would make (and indeed did make in my case) a programmer's job to track down the cause of the memory exhaustion difficult, as the error message might not help much to pin down which module, let alone which function, is causing a trouble.

Note even after I had added the "hook" function, I have once successfully disabled and enabled the module (after Drupal experienced a memory exhaustion), and the module worked fine for some time, before it eventually started to cause a memory exhaustion and then it became impossible to re-enable it. I do not know why it was enabled successfully once and worked OK for some time.

The moral of this case is summarised at the beginning. Added to that, to chop off all the unnecessary parts like debugging may help (as @rooby suggested in the comment of the question), because something in those unnecessary parts, or those that you think are unused, may be causing a trouble. Frequent disabling/enabling cycles, as well as clearing the cache, can also help to identify the problem at the earliest opportunity.

1
  • 1
    put another way: Only hook_ functions belong in a .module file. So if you make any mymodule_FOO() functions they should be hook implementations. Or, for D7 call your private functions with a simple naming convention like function _myfunction_theme() for instance and the leading underscore doesn't confuse Drupal at all.
    – tenken
    Oct 22, 2014 at 17:41
1

Tracking down memory problems is treacherous business. There are many different ways that will help you, but not one single strategy. When I got myself stuck in situations that made me suspect my code was eating up memory, the most help I got was from tools like Callgrind and Valgrind. Which one to use depends on the platform you are running on. They will collect a full record of your call stack along with execution times and memory usage. Then you can use a visualization tool to go through the output file (don't try manually). I've used MacCallGrind, but there are plenty others.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.