Monday, 30 January 2012

Little debugging aid

I had been having a real problem tracking down a PHP error in Drupal which was passing an array to htmlspecialchars() in check_plain() instead of a string. I needed to use debug_backtrace() but the issue was related to Views which meant that the arguments being passed at higher levels were catastrophically huge.

It was a real problem, using krumo just resulted in out-of-memory errors. And the problem was also happening inside AJAX calls so any attempt to simply print the output was doomed.

I needed a way to get a function backtrace which was not too verbose, didn't crash the machine and would work in an AJAX call.

The solution is the following routine which takes a debug_backtrace() extracts only the information we need and outputs to a file. It's not Drupal-specific but you may need to set up the directory:

 * Backtrace to a file for when nothing else works
function debug_backtrace_file($fname = 'backtrace') {
  $file = fopen("c:\\tmp\\{$fname}.log", 'ab');
  if (!$file) {
  fputs($file, '=============== ' . date('Y-m-d H:i:s') . " ===============\n");
  $line = __LINE__;
  foreach (debug_backtrace() as $entry) {
    $function = $entry['function'];
    if ($function!=__FUNCTION__) {
      if (isset($entry['class']) && $entry['class']) {
        $function = "{$entry['class']}::$function";
      fputs($file, sprintf("function %s at line %d in file %s\n", $function, $line, isset($entry['file'])?$entry['file']:t('unknown')));
    $line = $entry['line'];

Happy bug hunting.

No comments: