---
title: "Quick-and-Dirty Debugging"
url: "/articles/quickanddirty-debugging"
type: article
date: 2007-04-27
updated: 2016-04-07
---

# Quick-and-Dirty Debugging

#  Quick-and-Dirty Debugging 

 Printing errors and backtraces to your page

 By

 [  Angie Byron   ](/about/angie-byron) 

 April 27, 2007

  

So you're coding along, developing your site, minding your own business, when you load a page you see some totally vague, obscure error message such as:

  ```php

warning: Invalid argument supplied for foreach() in /modules/node/node.module on line 504.
  
```

Where do you even start debugging something like that?

Well, you could start with looking at line 504 of node.module...

  ```php

    foreach ($param as $key => $value) {
  
```

Uh, yeah. *That's* helpful.

If you were astute, you might also observe that line 504 is inside of the node\_load() function. So that narrows it down to... only one of the 80,000 places node\_load() might be called from one of your core or contributed modules or themes. Ugh...

You could decide to get all fancy, and install an IDE like Komodo, Eclipse, or Zend, and use their real-time debugging features to step through the code one line at a time to figure out what's happening. It's pretty time-consuming, and it takes up lots of resources on your machine, but it'll probably help you nail it down if you are observing carefully.

**Or!** You can debug the quick and dirty way! Read on to find out how! In bootstrap.inc, find the function definition for **drupal\_set\_message** and place the following code at the top:

  ```php

function drupal_set_message($message = NULL, $type = 'status') {
  // DEBUG: Go track down that stinkin' error...
  if ($type == 'error') {
    $message .= '
```

```php
'. print_r(debug_backtrace(), 1) .'
```

`'; } // END DEBUG if ($message) { ... `

What will this do? It'll make that error above become something like this instead:

  ```php

warning: Invalid argument supplied for foreach() in /modules/node/node.module on line 504.
Array
(
    [0] => Array
        (
            [file] => /includes/common.inc
            [line] => 552
            [function] => drupal_set_message
            [args] => Array
                (
                    [0] => warning: Invalid argument supplied for foreach() in /modules/node/node.module on line 504.
                    [1] => error
                )

        )

    [1] => Array
        (
            [file] => /modules/node/node.module
            [line] => 504
            [function] => error_handler
            [args] => Array
                (
                    [0] => 2
                    [1] => Invalid argument supplied for foreach()
                    [2] => /modules/node/node.module
                    [3] => 504
                    [4] => Array
                        (
                            [param] => 
                            [revision] => 
                            [reset] => 
                            ...
                        )

                )

        )

    [2] => Array
        (
            [file] => /sites/all/modules/custom/custom_module/custom_module.module
            [line] => 10
            [function] => node_load
            [args] => Array
                (
                    [0] => 
                )

        )

    [3] => Array
        (
            [file] => /includes/form.inc
            [line] => 365
            [function] => custom_module_form_alter
            [args] => Array
                (
                ...
  
```

Note: If you have many errors on a page, this will probably crash your browser. ;) That's why we call it "Quick and Dirty." ;)

Uh. So what the heck *is* all of that crap? It's called a **backtrace**... it's showing you in reverse order the functions that were called, and the arguments that were passed into each, in order to get to the current spot in the code.

Let's take just chunk #0 and dissect it:

  
`    [0] => Array<br></br><br></br>        (<br></br><br></br>            [file] => /includes/common.inc<br></br><br></br>            [line] => 552<br></br><br></br>            [function] => drupal_set_message<br></br><br></br>            [args] => Array<br></br><br></br>                (<br></br><br></br>                    [0] => warning: Invalid argument supplied for foreach() in /modules/node/node.module on line 504.<br></br><br></br>                    [1] => error<br></br><br></br>                )`

 )  
  
?&gt;

This tells me that in /includes/common.inc on line 552, the function drupal\_set\_message was called, and was passed in two arguments. If I check the API documentation for [drupal\_set\_message](http://api.drupal.org/api/5/function/drupal_set_message), I can see that the first argument is the message to display, and the second is the type of message.

If I follow down the list, #1 tells me that drupal\_set\_message was called by error\_handler because of something that happened on line 504 in node.module. (Duh, I knew that one already.)

\#2 says that this was triggered by a call to node\_load from custom\_module.module on line 10. Great! Now I know that custom\_module.module has something to do with the problem. That helps narrow the problem down significantly.

But, as an added bonus, I *also* know that node\_load was passed an empty value into it as an argument, where normally this would be a node ID like 56. That's not going to go over well... unless I tell it what to load, how is Drupal not going to puke all over itself?

\#3 helps me narrow it down even further.. I know now that this was caused by a call to the custom\_module\_hook\_form\_alter function.

I can keep reading; the backtrace will detail all of the function calls that happened, all the way as far as index.php. But I have enough information now to start hunting for the bug.

If I look at my hook\_form\_alter in custom\_module.module, around line 10, I might see something like this:

```php

if (arg(0) == 'node') {
  $node = node_load(arg(1));
}

```

Note: I didn't actually write such code, but needed an easy example. ;) After a bit of head-slapping, I realize that I'm on the path ?q=node, so there is no arg(1), therefore it's passing a NULL value into node\_load(). Further, my code blindly assumes that I'm on a path like node/34, but doesn't check to make sure I'm not on a path like node/add/blog. Eek. Let's try this again:

```php

if (arg(0) == 'node' && is_numeric(arg(1)) {
  $node = node_load(arg(1));
}

```

Voila! No more errors. For trickier bits, and doing something like debugging form.inc ;) you probably want to step up and make a real-time debugger part of your developer arsenal. But to help you nail down the cause of an error quickly and easily, this can be a useful tip.

 Published in:

- [  Drupal Site Building   ](/topics/drupal-site-building)

 

   You must have JavaScript enabled to use this form.

## Get in touch with us

### Tell us about your project. We'd love to hear from you!

 First Name  

 Last Name  

 Your email address  

 Your organization  

 How you heard about us  

 Tell us more 

     Leave this field blank