Problem/Motivation
Running drush make-generate
on a site with a module that has a ".info" file without a corresponding ".module" file causes an infinite loop.
For example, on a site with the "fb" module installed:
$ drush make-generate z.make
strpos(): Empty delimiter pm.drush.inc:1060 [warning]
strpos(): Empty delimiter pm.drush.inc:1060 [warning]
strpos(): Empty delimiter pm.drush.inc:1060 [warning]
strpos(): Empty delimiter pm.drush.inc:1060 [warning]
[ad nauseam, until it runs out of memory]
Again, with the current master branch and debug mode:
$ git clone --branch master http://git.drupal.org/project/drush.git
$ ./drush/drush --debug make-generate z.make
Bootstrap to phase 0. [0.01 sec, 3.29 MB] [bootstrap]
Executing: which wget
/usr/bin/wget
Executing: wget -q --timeout=30 -O /tmp/download_fileoLCcKp http://download.pear.php.net/package/Console_Table-1.1.3.tgz
Calling is_readable(/tmp/download_fileoLCcKp) [0.66 sec, 3.3 MB] [debug]
Calling [debug]
is_writable(/var/www/site/drush/lib)
[0.66 sec, 3.3 MB]
Calling rename(/tmp/download_fileoLCcKp, [debug]
/var/www/site/drush/lib/drush-library-816492876.tar.gz)
[0.66 sec, 3.3 MB]
Calling [debug]
chdir(/var/www/site/drush/lib)
[0.66 sec, 3.31 MB]
Executing: tar -C /var/www/site/drush/lib -xzf drush-library-816492876.tar.gz
Calling chdir(/var/www/site) [debug]
[0.71 sec, 3.31 MB]
Calling [debug]
unlink(/var/www/site/drush/lib/package.xml)
[0.71 sec, 3.31 MB]
Drush bootstrap phase : _drush_bootstrap_drush() [0.71 sec, 3.5 MB] [bootstrap]
Cache MISS cid: 5.0-dev-commandfiles-0-03ee05e0335e54a4eb46a8147b71e36f [0.73 sec, 3.51 MB] [debug]
Cache SET cid: 5.0-dev-commandfiles-0-03ee05e0335e54a4eb46a8147b71e36f [0.73 sec, 3.52 MB] [debug]
Bootstrap to phase 0. [0.77 sec, 7.41 MB] [bootstrap]
Bootstrap to phase 5. [0.78 sec, 7.41 MB] [bootstrap]
Drush bootstrap phase : _drush_bootstrap_drupal_root() [0.78 sec, 7.42 MB] [bootstrap]
Initialized Drupal 6.14 root directory at /var/www/site [0.82 sec, 8.92 MB] [notice]
Drush bootstrap phase : _drush_bootstrap_drupal_site() [0.82 sec, 8.93 MB] [bootstrap]
Initialized Drupal site default at sites/default [0.82 sec, 8.93 MB] [notice]
Cache MISS cid: 5.0-dev-commandfiles-2-c32acd775c18a90c5b41d0fc9accf5ab [0.83 sec, 8.93 MB] [debug]
Cache SET cid: 5.0-dev-commandfiles-2-c32acd775c18a90c5b41d0fc9accf5ab [0.84 sec, 8.94 MB] [debug]
Drush bootstrap phase : _drush_bootstrap_drupal_configuration() [0.84 sec, 8.93 MB] [bootstrap]
Drush bootstrap phase : _drush_bootstrap_drupal_database() [0.87 sec, 9.01 MB] [bootstrap]
Successfully connected to the Drupal database. [0.87 sec, 9.01 MB] [bootstrap]
Drush bootstrap phase : _drush_bootstrap_drupal_full() [0.87 sec, 9.32 MB] [bootstrap]
session_start(): Cannot send session cookie - headers already sent by (output started at [warning]
/var/www/site/drush/includes/output.inc:37) bootstrap.inc:1037 [0.88 sec, 9.4 MB]
session_start(): Cannot send session cache limiter - headers already sent (output started at [warning]
/var/www/site/drush/includes/output.inc:37) bootstrap.inc:1037 [0.88 sec, 9.4 MB]
Cannot modify header information - headers already sent by (output started at [warning]
/var/www/site/drush/includes/output.inc:37) bootstrap.inc:636 [1.05 sec, 14.14
MB]
Cannot modify header information - headers already sent by (output started at [warning]
/var/www/site/drush/includes/output.inc:37) bootstrap.inc:637 [1.05 sec, 14.14
MB]
Cannot modify header information - headers already sent by (output started at [warning]
/var/www/site/drush/includes/output.inc:37) bootstrap.inc:638 [1.05 sec, 14.14
MB]
Cannot modify header information - headers already sent by (output started at [warning]
/var/www/site/drush/includes/output.inc:37) bootstrap.inc:639 [1.05 sec, 14.14
MB]
Cache MISS cid: 5.0-dev-commandfiles-5-9ab8c402bd5bac2e70bf5d8a22cb3329 [1.62 sec, 34.8 MB] [debug]
Cache SET cid: <em>5.0-dev-commandfiles-5-9ab8c402bd5bac2e70bf5d8a22cb3329</em> [1.83 sec, 35.87 MB] [debug]
Found command: make-generate (commandfile=make) [1.83 sec, 35.87 MB] [bootstrap]
Loading release_info engine. [1.86 sec, 35.9 MB] [notice]
Including /var/www/site/drush/commands/make/generate.make.inc [1.87 sec, 36.06 [bootstrap]
MB]
Downloading release history from http://updates.drupal.org/release-history/addtoany/6.x [2.61 sec, 38.23 MB] [notice]
Executing: wget -q --timeout=30 -O /tmp/download_fileALMCLP http://updates.drupal.org/release-history/addtoany/6.x
Calling drush_delete_dir(/tmp/addtoanyhutvKC, 1) [3.01 sec, 38.23 MB] [debug]
Calling is_readable(/tmp/download_fileALMCLP) [3.01 sec, 38.23 MB] [debug]
Calling is_writable(/tmp) [3.01 sec, 38.24 MB] [debug]
Calling rename(/tmp/download_fileALMCLP, /tmp/addtoanyhutvKC) [3.01 sec, 38.24 MB] [debug]
[... a few more modules ...]
Downloading release history from http://updates.drupal.org/release-history/fb/6.x [5.83 sec, 38.3 MB] [notice]
Executing: wget -q --timeout=30 -O /tmp/download_fileYSzzRK http://updates.drupal.org/release-history/fb/6.x
Calling drush_delete_dir(/tmp/fbHL3aPq, 1) [6.31 sec, 38.3 MB] [debug]
Calling is_readable(/tmp/download_fileYSzzRK) [6.31 sec, 38.3 MB] [debug]
Calling is_writable(/tmp) [6.31 sec, 38.3 MB] [debug]
Calling rename(/tmp/download_fileYSzzRK, /tmp/fbHL3aPq) [6.31 sec, 38.3 MB] [debug]
strpos(): Empty delimiter pm.drush.inc:1074 [6.32 sec, 38.31 MB] [warning]
strpos(): Empty delimiter pm.drush.inc:1088 [6.32 sec, 38.31 MB] [warning]
strpos(): Empty delimiter pm.drush.inc:1088 [6.32 sec, 38.31 MB] [warning]
strpos(): Empty delimiter pm.drush.inc:1088 [6.32 sec, 38.31 MB] [warning]
[ad nauseam, until it runs out of memory]
$ drush status
Drupal version : 6.14
Site URI : http://default
Database driver : mysqli
Database hostname : localhost
Database username : site
Database name : site
Database : Connected
Drupal bootstrap : Successful
Drupal user : Anonymous
Default theme : analytic
Administration theme : analytic
PHP configuration : /etc/php.ini
Drush version : 5.0-dev
Drush configuration :
Drush alias files :
Drupal root : /var/www/site
Site path : sites/default
File directory path : sites/default/files
Proposed resolution
After a bit of spelunking through the _pm_find_common_path()
implementation, the problem seems to be that the "fb" module has a theme inside it ("fb/themes/fb_fbml") — there's a ".info" file but no corresponding ".module" file. Therefore drupal_get_path('module', 'fb_fbml');
returns nothing, and the subsequent strpos()
calls are unsatisfied.
The attached patch continues popping off extensions until it find one that actually returns a path, which solves the above problem.
Remaining tasks
Review attached patch.
Comment | File | Size | Author |
---|---|---|---|
#8 | drush-fix-null-path-1451534-8.patch | 1.25 KB | dude4linux |
#5 | drush-1451534-fix-null-path-#5.patch | 1.25 KB | dude4linux |
drush-make-generate-get-project-path-00.diff | 770 bytes | smokris |
Comments
Comment #1
moshe weitzman CreditAttribution: moshe weitzman commentedSounds like quite the edge case.
Comment #2
jonhattanFor reference, this is fb-6.x-2.x.
_pm_find_common_path()
is a hack to workaround the project <-> extensions problem, and has been the source for epic fails (ej. removing sites/ folder) when projects doesn't follow the rules. So making it more fail proof is a win.Ideally the function should log a debug message (ej: "Finding base path for project X") and also log an error message when it finds an anomaly as the one in OP. Note that the fail in the first call to drupal_get_path is by chance. The other call inside the
while
may also fail.btw I wonder if generate-makefile may call this function for install profiles.
Comment #3
dude4linux CreditAttribution: dude4linux commentedI'm seeing a similar error when trying to run 'drush pm-update' on a site built with the OpenPublic 7.x-1.0-beta5 installation profile. I've also seen it with older versions of drush 5.0-dev and other profiles.
Results of 'drush pm-update --debug'
Drush version and status
Like the author suggests, it goes into an infinite loop, repeating until it runs out of memory. I checked and found that there were several .info files without accompanying .module files. Seems to be an assumption that is not always true.
Comment #4
dude4linux CreditAttribution: dude4linux commentedSince the first error occurs at line 1074 of pm.drush.inc, I inserted a printf statement followed by a break. Looks like the culprit is the phase2_profile. I have no idea why it returns a null path.
Comment #5
dude4linux CreditAttribution: dude4linux commentedThe attached patch adds a test for the edge case where path is null. It also tests for the case where path2 is null and corrects the final option where the path is reduced to '', not '.'. I've tried to run the phpunit tests but they are hanging on git.make. I don't believe the failure is related to this patch because the same failure happens when the patch is not present.
Comment #6
dude4linux CreditAttribution: dude4linux commentedResults of phpunit tests with those in git.make commented out.
I don't think any of the five failures is related to this patch. Perhaps someone can run the tests to crosscheck my results.
Comment #7
dude4linux CreditAttribution: dude4linux commentedRevised code for _pm_find_common_path()
Comment #8
dude4linux CreditAttribution: dude4linux commentedRenamed patch in #5 correctly (without the # sign). Sorry about that, I'm trying to learn.
Comment #9
dude4linux CreditAttribution: dude4linux commentedForgot to change status.
Comment #10
jonhattanI'm working on this.
Comment #11
jonhattan@dude4linux, the problem with openpublic was identified in #1303488: Drush fails on critical error with OpenPublic. See also #1300726: Openpublic Beta 3 throws a critical Drush error
I've refactored code that was relying in
_pm_find_common_path()
and added some checks as in the patch from @smokris, with logging. Those are the commits:http://drupalcode.org/project/drush.git/commit/1bda735
http://drupalcode.org/project/drush.git/commit/6a661cb
Now the output for a case such as openpublic's one is:
Comment #12
bcobin CreditAttribution: bcobin commentedI've applied the changes and I, indeed, get the "Unknown path" messages as listed.
But drush upc results in endless loop as described in http://drupal.org/node/1352102, which I assume is not related to this particular issue. I'm noting it here to document that the Drush 5.x branch as it currently stands will not work with OP. Thanks for the work here - it's good to see progress... thanks!
Comment #13
blitux CreditAttribution: blitux commentedI'm getting the same error when running 'drush up' command on OpenPublish 7.x-1.0-alpha6 as detailed here: Multiple strpos(): Empty delimiter pm.drush.inc:1088 errors on 'drush up' command
Aplied patch on #8 and it worked normally.
Comment #14
dude4linux CreditAttribution: dude4linux commentedI took a second look at my code in #7 and jonhattan's fix, git commit 6a661cb94ce4bf6e5b5d62a8458645112b7587d5. There are three edge cases that weren't properly handled by the original code.
My code in #7 and patch #8 work, but aren't entirely correct. The code for Option 2a & 2b should have been
jonhattan's fix handles the first two edge cases differently than mine, but correctly as well. The remaining difference is how the third case is handled. If there is no common path shared by the extensions, the final option will iteratively strip the rightmost part of $path.
The flaw here is that when there is no leading '.' in $path, the while is never satisfied and it loops until a memory fault occurs. I presume there may be cases in which the $path has a leading '.' but those I have encountered do not, so the while should test for both '.' and '' to prevent the infinite loop. It might be a good idea to add a warning or error message when no common path is found. I've been seeing cases where modules get installed in the site root and this might be the cause.