Get the call backtrace from where the error was generated.
Supported with PHP 4.3.0 or newer.

@param int $frame (optional) what frame to fetch
@return array Backtrace, or NULL if not available.
@access public
556321
function getBacktrace($frame = null)
    {
        if (defined('PEAR_IGNORE_BACKTRACE')) {
            return null;
        }
        if ($frame === null) {
            return $this->backtrace;
        }
        return $this->backtrace[$frame];
    }
109414
private function formatStackFrame($frame)
    {
        return [
            'file'      => isset($frame['file']) ? $frame['file'] : 'unknown',
            'line'      => isset($frame['line']) ? $frame['line'] : 'unknown',
            'function'  => (isset($frame['class']) ? $frame['class'] . $frame['type'] : '') . $frame['function'],
            'arguments' => $this->formatArguments($frame['args'])
        ];
    }
207439
private function _getPearTrace(PEAR_Error $error)
    {
        $pear_error = '';
        $backtrace = $error->getBacktrace();
        if (!empty($backtrace)) {
            $pear_error .= 'PEAR backtrace:' . "\n\n";
            foreach ($backtrace as $frame) {
                $pear_error .=
                      (isset($frame['class']) ? $frame['class'] : '')
                    . (isset($frame['type']) ? $frame['type'] : '')
                    . (isset($frame['function']) ? $frame['function'] : 'unkown') . ' '
                    . (isset($frame['file']) ? $frame['file'] : 'unkown') . ':'
                    . (isset($frame['line']) ? $frame['line'] : 'unkown') . "\n";
            }
        }
        $userinfo = $error->getUserInfo();
        if (!empty($userinfo)) {
            $pear_error .= "\n" . 'PEAR user info:' . "\n\n";
            if (is_string($userinfo)) {
                $pear_error .= $userinfo;
            } else {
                $pear_error .= print_r($userinfo, true);
            }
        }
        return $pear_error;
    }
1158030
private static function getDebugFile()
    {
        $trace = \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

        foreach (\array_reverse($trace) as $stackFrame) {
            if (!self::isDebugCall($stackFrame)) {
                continue;
            }

            if (\preg_match('/eval\(/', $stackFrame['file'])) {
                \preg_match_all('/([^\(]+)\((\d+)/', $stackFrame['file'], $matches);

                return $matches[1][0];
            }

            return $stackFrame['file'];
        }
    }
21630
function check_page_break(Frame $frame)
    {
        //FIXME: should not need to do this since we're tracking table status in `$this->_in_table`
        $p = $frame;
        $in_table = false;
        while ($p) {
            if ($p->is_table()) { $in_table = true; break; }
            $p = $p->get_parent();
        }
        // Do not split if we have already or if the frame was already
        // pushed to the next page (prevents infinite loops)
        if ($in_table) {
            if ($this->_page_full && $frame->_already_pushed) {
                return false;
            }
        } elseif ($this->_page_full || $frame->_already_pushed) {
            return false;
        }

        //FIXME: work-around for infinite loop due to tables 
        if ($in_table && $frame->_already_pushed) {
            return false;
        }
        $p = $frame;
        do {
            $display = $p->get_style()->display;
            if ($display == "table-row") {
                if ($p->_already_pushed) { return false; }
            }
        } while ($p = $p->get_parent());

        // If the frame is absolute of fixed it shouldn't break
        $p = $frame;
        do {
            if ($p->is_absolute()) {
                return false;
            }

            // FIXME If the row is taller than the page and
            // if it the first of the page, we don't break
            $display = $p->get_style()->display;
            if ($display === "table-row"
                && !$p->get_prev_sibling()
                && $p->get_margin_height() > $this->get_margin_height()
            ) {
                return false;
            }
        } while ($p = $p->get_parent());

        $margin_height = $frame->get_margin_height();

        // Determine the frame's maximum y value
        $max_y = (float)$frame->get_position("y") + $margin_height;

        // If a split is to occur here, then the bottom margins & paddings of all
        // parents of $frame must fit on the page as well:
        $p = $frame->get_parent();
        while ($p) {
            $max_y += $p->get_style()->computed_bottom_spacing();
            $p = $p->get_parent();
        }


        // Check if $frame flows off the page
        if ($max_y <= $this->_bottom_page_margin) {
            // no: do nothing
            return false;
        }

        Helpers::dompdf_debug("page-break", "check_page_break");
        Helpers::dompdf_debug("page-break", "in_table: " . $this->_in_table);

        // yes: determine page break location
        $iter = $frame;
        $flg = false;

        $in_table = $this->_in_table;

        Helpers::dompdf_debug("page-break", "Starting search");
        while ($iter) {
            // echo "\nbacktrack: " .$iter->get_node()->nodeName ." ".spl_object_hash($iter->get_node()). "";
            if ($iter === $this) {
                Helpers::dompdf_debug("page-break", "reached root.");
                // We've reached the root in our search.  Just split at $frame.
                break;
            }

            if ($this->_page_break_allowed($iter)) {
                Helpers::dompdf_debug("page-break", "break allowed, splitting.");
                $iter->split(null, true);
                $this->_page_full = true;
                $this->_in_table = $in_table;
                $frame->_already_pushed = true;

                return true;
            }

            if (!$flg && $next = $iter->get_last_child()) {
                Helpers::dompdf_debug("page-break", "following last child.");

                if ($next->is_table()) {
                    $this->_in_table++;
                }

                $iter = $next;
                continue;
            }

            if ($next = $iter->get_prev_sibling()) {
                Helpers::dompdf_debug("page-break", "following prev sibling.");

                if ($next->is_table() && !$iter->is_table()) {
                    $this->_in_table++;
                } else if (!$next->is_table() && $iter->is_table()) {
                    $this->_in_table--;
                }

                $iter = $next;
                $flg = false;
                continue;
            }

            if ($next = $iter->get_parent()) {
                Helpers::dompdf_debug("page-break", "following parent.");

                if ($iter->is_table()) {
                    $this->_in_table--;
                }

                $iter = $next;
                $flg = true;
                continue;
            }

            break;
        }

        $this->_in_table = $in_table;

        // No valid page break found.  Just break at $frame.
        Helpers::dompdf_debug("page-break", "no valid break found, just splitting.");

        // If we are in a table, backtrack to the nearest top-level table row
        if ($this->_in_table) {
            $iter = $frame;
            while ($iter && $iter->get_style()->display !== "table-row" && $iter->get_style()->display !== 'table-row-group' && $iter->_already_pushed === false) {
                $iter = $iter->get_parent();
            }

            if ($iter) {
                $iter->split(null, true);
            } else {
                return false;
            }
        } else {
            $frame->split(null, true);
        }

        $this->_page_full = true;
        $frame->_already_pushed = true;

        return true;
    }
817557
protected function getFrames() : array
    {
        $frames = $this->throwable->getTrace();

        if (!$this->throwable instanceof \ErrorException) {

            // Make sure the first frame in the trace actually points to the Throwable we're inspecting.
            array_unshift($frames, diagnostics\Debug::throwableToArray($this->throwable));

            return $frames;
        }

        // We're going to determine if the exception in fact stems from an irrecoverable fatal error.
        $fatal = false;

        // Note: E_RECOVERABLE_ERROR and E_PARSE should as of PHP7 be entirely converted to Throwables
        // so they should be caught by an Exception Handler directly instead of first going through an Error Handler
        // and being converted to an Error Exception, let alone a FatalError Exception. We still keep
        // them here for edge cases, however.
        switch ($this->throwable->getSeverity()) {
            case E_ERROR:
            case E_CORE_ERROR:
            case E_COMPILE_ERROR:
            case E_USER_ERROR:
            case E_RECOVERABLE_ERROR:
            case E_PARSE:
                $fatal = true;
            break;
        }

        // Without XDebug we don't actually have any means to determine the stacktrace of a fatal error.
        if (!$fatal || !extension_loaded('xdebug') || !xdebug_is_enabled()) {
            // Our error handler will be the first frame in the trace since it's the one which converted
            // the error to an exception. We're gonna copy over the context and remove
            // Remove our (error) handler from the stack trace (it's otherwise always going to occlude
            // the actual exception).
            // $frames[1]['args'] = $frames[0]['args'];
            array_shift($frames);

            return $frames;
        }

        // Remove our internal handling logic from the stack trace so it doesn't occlude the actual trace.
        $frames = array_diff_key(array_reverse(xdebug_get_function_stack()), debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));

        // Handle some potential inconsistencies between XDebug and the way we want to handle things.
        foreach ($frames as &$frame) {

            if ('dynamic' === $frame['type']) {
                $frame['type'] = '->';
            } elseif ('static' === $frame['type']) {
                $frame['type'] = '::';
            }

            // XDebug uses a different key for the args array.
            if (isset($frame['params']) && !isset($frame['args'])) {
                $frame['args'] = $frame['params'];
                unset($frame['params']);
            }
        }

        return $frames;
    }
715977
protected function getExceptionFrames()
    {
        $frames = $this->getInspector()->getFrames();

        if ($this->getApplicationPaths()) {
            foreach ($frames as $frame) {
                foreach ($this->getApplicationPaths() as $path) {
                    if (strpos($frame->getFile(), $path) === 0) {
                        $frame->setApplication(true);
                        break;
                    }
                }
            }
        }

        return $frames;
    }
653986
public function getSubscription(Frame $frame)
    {
        foreach ($this->subscriptions as $subscription) {
            if ($subscription->belongsTo($frame)) {
                return $subscription;
            }
        }
        return false;
    }
30716
function(callback) {
    // capture current error location
    var trace_error = new Error();
    trace_error.id = ERROR_ID++;
    trace_error.__previous__ = current_trace_error;
    trace_error.__trace_count__ = current_trace_error ? current_trace_error.__trace_count__ + 1 : 1;
    limit_frames(trace_error);
    var new_callback = function() {
        current_trace_error = trace_error;
        trace_error = null;
        var res = callback.apply(this, arguments);
        current_trace_error = null;
        return res;
    };
    new_callback.__original_callback__ = callback;
    return new_callback;
}
48605
protected function isValidNextFrame(array $frame)
    {
        if (empty($frame['file'])) {
            return false;
        }

        if (empty($frame['line'])) {
            return false;
        }

        if (empty($frame['function']) || !stristr($frame['function'], 'call_user_func')) {
            return false;
        }

        return true;
    }
763008
private function getTrace()
    {
        $trace = array();

        if (PHP_VERSION_ID >= 50400) {
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
        } else if (PHP_VERSION_ID >= 50306) {
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
        } else {
            $trace = debug_backtrace();
        }
        if (empty($trace)) {
            return '';
        }
        array_shift($trace); // ignore $this->getTrace();
        array_shift($trace); // ignore $this->process()
        $i = 0;
        $returnArray = array();
        while (isset($trace[$i]['class']) && false === strpos($trace[$i]['class'], 'Zend\\Log')
            && false === strpos($trace[$i]['class'], 'DhErrorLogging')) {
            $i++;
            $returnArray[] = array(
                'file'     => isset($trace[$i]['file'])   ? $trace[$i]['file']   : null,
                'line'     => isset($trace[$i]['line'])   ? $trace[$i]['line']   : null,
                'class'    => isset($trace[$i]['class'])    ? $trace[$i]['class']    : null,
                'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null,
            );
        }

        return $returnArray;
    }
276647
private static function generateStackTrace(array &$context) {
        if (!key_exists('trace', $context)) {
            $trace = DebugHelper::fixTrace(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), __FILE__, __LINE__);

            foreach ($trace as $i => $frame) {
                if (!isset($frame['class']) || $frame['class']!=__CLASS__)      // remove non-logger frames
                    break;
                unset($trace[$i]);
            }
            $context['trace'] = \array_values($trace);
        }
    }
283501
public static function backtrace($return = false, $html = true, $withArgs = true)
        {
            $trace  = debug_backtrace();
            return static::trace($trace, $return, $html, $withArgs);
        }
385499
public function logBackTrace($backTrace = null) {
        if (is_null($backTrace)) {
            $backTrace = debug_backtrace();
            array_shift($backTrace);
        }
        $btuuid = Mage::helper('turpentine/data')->generateUuid();
        $this->log('TRACEBACK: START ** %s **', $btuuid);
        $this->log('TRACEBACK: URL: %s', $_SERVER['REQUEST_URI']);
        for ($i = 0; $i < count($backTrace); $i++) {
            $line = $backTrace[$i];
            $this->log('TRACEBACK: #%02d: %s:%d',
                $i, $line['file'], $line['line']);
            $this->log('TRACEBACK: ==> %s%s%s(%s)',
                (is_object(@$line['object']) ?
                    get_class($line['object']) : @$line['class']),
                @$line['type'],
                $line['function'],
                $this->_backtrace_formatArgs($line['args']));
        }
        $this->log('TRACEBACK: END ** %s **', $btuuid);
    }
1005610
public static function formatMethod($frame)
    {
        if (!empty($frame['class']) && !empty($frame['type']) && !empty($frame['function'])) {
            return sprintf('%s%s%s()', $frame['class'], $frame['type'], $frame['function']);
        } else {
            return sprintf('%s()', !empty($frame['function']) ? $frame['function'] : '<unknown>');
        }
    }
82509
public static function getCLIBacktrace($backtrace=null) {
		if(!$backtrace)
			$backtrace = debug_backtrace();

		$r = '';
		$c = count($backtrace);
		for($i=0; $i<$c; $i++) {
			$trace = $backtrace[$i];

			if(isset($trace['file']))
				$r .= $trace['file'].':'.$trace['line']."\n";
		}

		return $r;
	}
106209
public static function trace(array $stack) {
		$result = [];

		foreach ($stack as $frame) {
			if (isset($frame['function'])) {
				if (isset($frame['class'])) {
					$result[] = trim($frame['class'], '\\') . '::' . $frame['function'];
				} else {
					$result[] = $frame['function'];
				}
			}
		}
		return $result;
	}