Utilizing debug_backtrace() function for Magento debugging

Introduction

As promised, back with the 2nd utility function for Magento (printDebugBacktrace).
This function will help you to print the backtrace. As you know that Magento has so many classes and flow/interlinking of those classes’ methods are really vague. So this function will help you to debug/trace in such cases.
printDebugBacktrace function looks like:

public static function printDebugBacktrace($title = 'Debug Backtrace:') {
	$output		= "";
	$output .= "<hr /><div>" . $title . '<br /><table border="1" cellpadding="2" cellspacing="2">';

	$stacks		= debug_backtrace();

	$output .= "<thead><tr><th><strong>File</strong></th><th><strong>Line</strong></th><th><strong>Function</strong></th>".
		"</tr></thead>";
	foreach($stacks as $_stack)
	{
		if (!isset($_stack['file'])) $_stack['file'] = '[PHP Kernel]';
		if (!isset($_stack['line'])) $_stack['line'] = '';

		$output .=  "<tr><td>{$_stack["file"]}</td><td>{$_stack["line"]}</td>".
			"<td>{$_stack["function"]}</td></tr>";
	}
	$output .=  "</table></div><hr /></p>";
	return $output;
}

You need to put the above method in app/Mage.php.
Note: As you see that above method utilizes the PHP’s debug_backtrace() method. But manually calling that function will give you very large string due to large no of complex properties & nested objects in Magento classes, and will be very difficult in tracing. So it’s recommended to use the above-mentioned utility function instead.

Usage

Suppose say you are trying to figure out the flow of

Mage_Sales_Model_Quote_Address_Total_Shipping::collect()

method.
Go to that class method and put the following line

public function collect(Mage_Sales_Model_Quote_Address $address)
{
	echo Mage::printDebugBacktrace(); exit; //add this line just after the opening
	//Mage::log(Mage::printDebugBacktrace(), null, 'backtrace.log'); //or you can even log the backtrace

And when you load the page (my cart) in frontend then you will get the following output:

Output: printDebugBacktrace
Output: printDebugBacktrace

Isn’t that very helpful to know the flow and debug accordingly?
Good Luck with Magento Debugging.

EDIT:

After this article was written, found that we can do the very same thing using the following inbuilt method:

Varien_Debug::backtrace()

Whose arguments are as:

	
/**
* Prints or return a backtrace
*
* @param bool $return      return or print
* @param bool $html        output in HTML format
* @param bool $withArgs    add short argumets of methods
* @return string|bool
*/
public static function backtrace($return = false, $html = true, $withArgs = true)

So now you can simply call as

echo Varien_Debug::backtrace(true, true); exit;
//or
Mage::log(Varien_Debug::backtrace(true, true), null, 'backtrace.log');

6 thoughts on “Utilizing debug_backtrace() function for Magento debugging”

  1. There also is mageDebugBacktrace($return=false, $html=true, $showFirst=false) in app/code/core/Mage/Core/functions.php (required by Mage.php)

  2. What do you think is it ok to use something like this?


    class Domore_Matrix_Model_Option extends Mage_Catalog_Model_Product_Option
    {
    public function getPrice($flag=false)
    {
    if ($this->getTitle()=='Size') {
    // dirty simple hack :) to get first attribute of caller function getOptionPrice($optionValue, $basePrice)
    // it is usefull to not rewrite Mage_Catalog_Model_Product_Option_Type_Default by placing it to local folder
    // it's not possible to rewrite Mage_Catalog_Model_Product_Option_Type_Default by config.xml
    // it is another way - by rewriting autoloader (like Aitoc) but I think it's even more confusing
    // so future magento versions will be supported
    // questions? Alexandr Martynov (joyview@gmail.com)
    $caller = debug_backtrace();
    $optionValue = current($caller[1]['args']);
    // check if optionValue contains Width & Height
    if (strpos($optionValue,'Width=')!==false AND strpos($optionValue,'Height=')!==false) {
    // calculate price with price matrix
    return 100;
    }
    }
    return parent::getPrice($flag);
    }
    }

  3. Logging should be enabled at the back-end for Mage::log to function
    SYSTEM/DEVELOPER/LOG SETTINGS

    However, the below did not output anything to the screen
    echo Varien_Debug::backtrace(true, true); exit;

  4. I’ve been getting a lot of messages that I can’t identify in my logs, including debug messages that some extension developer left in the code. So I wanted to have a backtrace in every message in the log. I found the ‘log’ function in Mage.php and added the following lines before the ‘$loggers[$file]->log($message, $level);’ line at the end of the function:

    /**
    * Mod to print callback trace: START
    */
    $stacks = debug_backtrace();
    foreach($stacks as $_stack)
    {
    $loggers[$file]->log(“Backtrace:”, #level);
    if (!isset($_stack[‘file’])) $_stack[‘file’] = ‘[PHP Kernel]’;
    if (!isset($_stack[‘line’])) $_stack[‘line’] = ”;
    $output = “[{$_stack[“file”]}] [{$_stack[“line”]}] [{$_stack[“function”]}]”;
    $loggers[$file]->log($output, #level);
    }
    /**
    * Mod to print callback trace: END
    */

    If I need to turn off the backtrace I can just delete the ‘*/’ line after the ‘START’ comment.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.