Drupal Debugging

Debugging Drupal is not that much different from any kind of debugging or problem-solving, and the topics we'll cover are the same regardless of your level of Drupal or PHP expertise.

Here we'll cover three topics:

  1. Strategy: How do we think about the problem? How do we gather basic information about the problem? How do we not get stuck debugging the wrong problem?
  2. Tools: What tools can be bring to bear on our problem? What should we have prepared in advance?
  3. Techniques: What specific techniques can we use?

Although you may be here for #3, the first two will probably have more of an impact on your success, so we're going to spend some good time on them first.

Debugging Strategies

Turn on your brain first

Before beginning a debugging effort, turn on your brain. Ask yourself some questions:

  • Have you looked at the Drupal log yet? Going to admin->reports->dblog has solved many a problem... after I've spent an hour trying to figure it out.
  • Have you looked at the Apache log yet? If you're debugging a WSOD (White Screen of Death) and haven't looked at the Apache log yet, you're wasting your time. If you don't yet know where the apache log is on sites you maintain, find out now.
  • Has anything changed on the site lately?
  • Is your internet connection working?
  • Are other sites on the same server working correctly?
  • Does the dev or staging version of your site still work?

Divide and Conquer: Binary Search

Almost any piece of software or any debugging problem is too large to understand all at once. So you have to figure out ways to divide the problem. If you can divide the problem in half a couple of times you'll rapidly have a more understandable problem.

There are many ways to divide up a problem:

  • Divide it into different sections of code
  • Divide it into different modules or different combinations of modules
  • Divide it into different versions (if it appears to be a version-related issue)

Best practices that will make problem-solving easier

Many of the items in this tutorial may require you to learn a new technique or two. Commit to breaking out of the stalemate. Don't let skills that you haven't yet mastered keep you from really resolving a problem. Learn them, even if it means investing in them in the midst of a crisis. Never let a mysterious site remain mysterious. Commit the resources you need to shine the light on your Drupal installation. It's worth it - it will pay off in no time.

  1. Keep a log of changes on the site. Note when a new module is installed, when a patch is applied, when an upgrade is done. You may want to consider using the journal module to help with this.  But a simple log like this one can make problemsolving easier.
  2. Keep your code under source control, and know how to use it.
  3. Keep multiple backups of your database. Use the Backup and Migrate module for small sites, or another backup technique for larger sites.
  4. Make sure you have an environment set up that is similar to your production environment where you can set up a clone of the production site at a moment's notice.
  5. Use a notebook to record changes as you make them when you're working through a lot of experiments, like enabling and disabling modules. Otherwise you may not be able to remember where you came from or how to get back there.

Debugging Tools: Preparation and Investment Ahead of Time

If you invest in your infrastructure ahead of time, life will be so much easier. If you know how to load and dump the database quickly and how to get a file copy of a production database in moments, and you know how to revert to an earlier version of the code, life will be so much better. Learn how to do these things, whether you do "code" or not:

  1. Have an environment where you can run a copy of any production website you're responsible for. This doesn't mean the exact same setup - it may not even need to be the same operating system. But you'll probably want to match PHP major versions and Mysql major versions. If you have PHP 5.2 and Mysql 5 on the production server, you'll probably need an environment that comes close to that. Yes, if your production site runs Linux, you'll probably want to be able to duplicate that. But many problems and issues can be demonstrated successfully on a Windows machine with Xampp or a Mac with Mamp. And most Drupal websites will run fine in many environments.
  2. Learn how to clone your production website in moments. When a crisis time comes for your production website, you need to be able to make a copy of it to work with it. Trying to debug on a live site has enormous disadvantages: Your own conservatism about making changes is one of those, the risk that you'll break something worse is another, and just the fact that it's far away and harder to work with is a third. Working on a cloned website is non-negotiable, in my opinion, and will pay off at least 90% of the time.
    Demonstration: Cloning a website in moments
  3. Keep your site under source control and know how to use it. If your site is under source control, you can roll back any part of it in moments and you can experiment easily with different versions of the code.
    Demonstration: Using source control to debug. (Delete a section. Delete modules. Revert to an earlier time. Move forward in time)
  4. Learn Drush. You'll be happy you did.
  5. Get Step-debugging going if you can work with PHP code. You really can't live without it.
    Demonstration: Step debugging with Eclipse.

Debugging Techniques

Now, for some nitty-gritty techniques.

  • Using Divide-And-Conquer
    • Example: Binary search (of modules) by disabling modules.  (demonstration)
    • Example: Binary search (of history) by going back in time in the code tree (demonstration)
    • Example: Binary search (of code execution) by step-debugging over significant sections of the site and then zeroing in on the section where the problem occurs.
  • Getting more information: Instrumentation: Many times, you just don't have enough information to understand what a problem consists of, not to mention what's causing it. In this situation you need to instrument the system to coax it to tell you what you need to know.
    • Devel module.
    • Trace module
    • Add your own on-the-fly instrumentation so you get the information you need. To do this sanely you have to be working on a clone of the site you're debugging, and to do it well, it should be under source control, so you can quickly and safely revert your hacks. Most of these are especially valuable in places like hooks, where the code executes thousands of times with no problems, but then displays a disaster on execution 1001. Step-debugging with conditional breakpoints can be used well, but sometimes you just want to find out quickly.  Some quick hacks:
      • Webchick's Quick and Dirty Debugging: Hack drupal_set_message() in bootstrap.inc to get a stack trace, so you can see where the problem comes from. For example, you just see a nasty error about a database issue, but no context: Show the stack trace and you'll suddenly understand.
        Add:
        if ($type == 'error') {
           $message .= '<pre>'. print_r(debug_backtrace(), TRUE) .'</pre>';
        }
        to the top of drupal_set_message() and you'll get a backtrace along with the message. The same exact technique works with watchdog - add to the message in watchdog() in includes/bootstrap.inc.
      • Debugging hook_cron: Hook_cron can be quite mischievous, because it's not intended to provide user output. A misbehaving module can cause it to croak without warning, and weeks later you find that cron hasn't been running and you don't know why. In this case we can add instrumentation right into module_invoke_all() in includes/module.inc:
        Add into the for loop just below $function =
        if ($hook == 'cron') { watchdog('debugging', "CRON: Calling $function"); }
        Every invocation of hook_cron then gets logged into watchdog(). The last one you see is the problem.
      • Debugging the infamous " Cannot use object of type stdClass as array" message:
        Right before the moment of disaster, insert something like:
          if (!is_array($x)) {     print '<pre>' . print_r(debug_backtrace(), TRUE) . '</pre>';  }
      • Debugging Drupal batch operations: This can be the very best technique for figuring out what's going on with batch operations. In fact, the only two ways I know of to get visibility into batch operations are to use a step debugger (Eclipse works wonderfully) or to add watchdog() calls to your code. In order to avoid being overwhelmed by the quantity, try making your watchdog calls conditional on the type of event you're working on.
  • Repetitive testing and refinement where the database is altered: There are a number of situations (mostly upgrade-related) where the activity you're debugging is actually changing the database, so to binary search and zero in on the problem, you have to start over again and again. If this means settings up an entire upgrade environment over and over it can make you tear your hair out. So try this:
    1. Get the test set up (prepare for an upgrade, for example). Get it set right to the point where if you pushed the button your error would be demonstrated.
    2. Dump the database at this point.
    3. Run the test. Use whatever technique you're using to zero in on the error.
    4. Load the dumped database. Rinse and repeat.

Debugging Links and Resources

  • Modules
    • devel module is all about instrumentation. It lets you see database queries and how long they're taking, tells you how long it took to render a page, and a thousand other indispensable things. Not recommended on a live site.
    • trace module will trace hooks and their execution. This is for people who understand what hooks are.
    • drush is not really a module. It allows you to rapidly and easily change the configuration of your system. Need to install devel? drush dl devel; drush enable devel. Sound pretty easy?
    • smtp is the way you test mail sending when you're not on the production site. Many people need it to do mail testing. Install it and point it at your gmail account and you can send mail all you want.  Also check out reroute_email.
  • IDE Debuggers

Where to find me

Email me, randy at randyfay.com, Find me on ddev.com, Drupal.org and Slack: rfay, Facebook: randyfay, Hobobiker.com: The story of our 2 1/2 year bike trip.

Updated 2025-12-03