Magento – How to debug: “HEADER ALREADY SENT” and GD2

debuggd2headerimage

I have an annoying HEADER ALREADY SENT error in system.log.

It is not easy to debug it, what I could do was to improve the logging to isolate the source of the issue (has described here):

Cannot send headers; headers already sent in lib/Varien/Image/Adapter/Gd2.php, line 133

Line 133 of Gd2.php:

call_user_func($this->_getCallback('output'), $this->_imageHandler);

And it is part of the method display:

public function display()
    {
        header("Content-type: ".$this->getMimeType());
        call_user_func($this->_getCallback('output'), $this->_imageHandler);
    }

How to go on ?

Best Answer

This is a tough one. I had an errant whitespace character at the beginning of a core class definition which screwing with me for a couple months till I realized what was going on.

Someone will write an extension one day to fix this, but till they do, one way to troubleshoot in Magento would be to start output buffering manually in index.php, then try to catch the output culprit in Varien_Autoload:

index.php:

ob_start();

lib/Varien/Autoload.php: (see note below)

public function autoload($class)
{
    if (max(array_column(ob_get_status(true),'buffer_used'))) {
        header('Content-Type: text/plain');
        ob_end_clean();
        debug_print_backtrace(2);
        die;
    }
    //... rest of method as normal ...
}

If you for example place a space at the beginning of Mage/Page/Block/Html/Footer.php then you would see the following:

#0  Varien_Autoload->autoload()
#1  spl_autoload_call() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Page/Block/Html/Footer.php:43]
#2  Mage_Page_Block_Html_Footer->_construct() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/lib/Varien/Object.php:112]
#3  Varien_Object->__construct() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Model/Layout.php:491]
#4  Mage_Core_Model_Layout->_getBlockInstance() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Model/Layout.php:437]
#5  Mage_Core_Model_Layout->createBlock() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Model/Layout.php:472]
#6  Mage_Core_Model_Layout->addBlock() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Model/Layout.php:239]
#7  Mage_Core_Model_Layout->_generateBlock() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Model/Layout.php:205]
#8  Mage_Core_Model_Layout->generateBlocks() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Model/Layout.php:206]
#9  Mage_Core_Model_Layout->generateBlocks() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Controller/Varien/Action.php:344]
#10 Mage_Core_Controller_Varien_Action->generateLayoutBlocks() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Cms/Helper/Page.php:113]
#11 Mage_Cms_Helper_Page->_renderPage() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Cms/Helper/Page.php:52]
#12 Mage_Cms_Helper_Page->renderPage() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Cms/controllers/IndexController.php:45]
#13 Mage_Cms_IndexController->indexAction() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Controller/Varien/Action.php:419]
#14 Mage_Core_Controller_Varien_Action->dispatch() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php:250]
#15 Mage_Core_Controller_Varien_Router_Standard->match() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Controller/Varien/Front.php:176]
#16 Mage_Core_Controller_Varien_Front->dispatch() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/code/core/Mage/Core/Model/App.php:354]
#17 Mage_Core_Model_App->run() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/app/Mage.php:683]
#18 Mage::run() called at [/Volumes/dev-cs/sites-enabled/optimizely/optimizely.dev/index.php:87]

This won't catch everything, so the offending file won't always be line #1, but it can get you very close to the offending context.

Note: I'm using array_column() here, a GREAT new function from Ben Ramsey in php 5.5. Without php 5.5 you can define it using his code, which is available on Github.