(Answer) (Category) LON-CAPA User Help : (Category) Software Developer Tips :
Debugging Apache children
To start up Apache as a single child:

/etc/init.d/httpd stop
/usr/sbin/httpd -X

This makes some debugging easier since you don't have to worry if you
are always getting the same child.

You can use the perl debugger against a
server running this way.

You need to add the below to a .conf file that Apache reads _BEFORE_
any other mod_perl directives (which in the new setup means in
httpd.conf right before the Include conf/loncapa_apache.conf)

PerlModule Apache::DB

<<Perl>>
  Apache::DB->init;
<</Perl>>
<Location />
  PerlFixupHandler Apache::DB
<</Location>>

You might want to surround this with a
<IfDefine PERLDEBUG>
<</IfDefine>>

and then use
/usr/sbin/httpd -X -DPERLDEBUG

In order to get the more-useful graphical debugger working with Apache, you'll need to do the following:

  • Download and install the perl modules Apache::DB (necessary for first part of this answer), Tk, and Devel::ptkdb.
    perl -MCPAN -e shell
    
    cpan shell -- CPAN exploration and modules installation (v1.62)
    
    cpan> install Apache::DB
    ...
    cpan> install Tk
    ...
    cpan> install Devel::ptkdb
    ^D
    

    Tk will take a little while to install, and requires Tk development libraries on your system.
     
  • You must now modify two files:
    1. In /usr/lib/perl5/site_perl/5.6.1/i386-linux/Apache/DB.pm, change the line that says require "Apache/perl5db.pl" to require "Devel/ptkdb.pm". (You may need to tweak the path depending on the version of Perl that Apache is using.)
       
    2. In /usr/lib/perl5/5.6.1/Devel/ptkdb.pm, change the line that says return if ( $0 ne $filename ); (line 4002 in my version) to return unless ($filename =~ /lon/);.
       
  • You do not need to change the Apache configuration created for Apache::DB, but let me re-emphasize the usefulness of wrapping it in an IfDefine so you can invoke this selectively. Be sure the debugger is invoked as the first Perl module, as it only affects modules compiled after the debugger is declared for use.
     
  • Finally, before using this, the webserver must be able to open windows on your xdisplay. The easy way to do that is xhost + localhost every time restart your XServer, but you should be aware of the security implications of that.
     

Once you do all this, you should get a graphical debugger to use whenever you load a page with a LON-CAPA handler, instead of the text-mode Perl debugger interface. Unfortunately, there are still some quirks in using ptkdb this way:

  • All modules have a "true" value at the end of them to confirm that they loaded correctly. You may need to "step into" this in order to get to the actual handler. I've not been able to predict exactly where the debugger will start debugging at (i.e., the compilation phase, the handler calling phase, etc.) Another thing that often works is to hit "return" as soon as the debugger comes up if the "use" lines are highlighted, which skips the step where Perl loads all the modules.
  • For reasons unknown, whatever the context it starts in (often the handler function), it is unable to recognize breakpoints within that context. So if it starts in the handler function itself, you can set breakpoints in functions the handler calls, but not in the handler itself. For debugging purposes, it can be useful to write a handler like this: sub handler { real_handler(shift); }, and rename the handler itself to "real_handler". Again, stupid... but what are you going to do?
  • Each time you use ptkdb, it doesn't seem to unregister correctly, so you usually have to kill and restart the server to do another debugging session. Sometimes you have to give an external kill command, ^C doesn't cut it. I usually bindle the relevant cp command and apache invocation ("/usr/sbin/httpd") onto one command line and use the shell to invoke that all at once.
  • Don't miss the data viewer on the right-hand pane, it's very useful, esp. for looking into hashes. You can also evaluate code in that window that actually changes the values of variables while debugging, which can be very useful for simulating things that might be hard to set up as input directly. In fact, be aware that everything you put on the side is invoked on every line you stop on, which is every single line if you're stepping through a function. Some things may cause problems if you do that.

    (Neat trick while debugging a web handler is to put $r->rflush() in the expression list, so it dumps the results immediately to the browser. However, Mozilla seems to be offended by that sometimes, and parses the HTML strangely, even though "View Source" shows it was all correct.)

Despite the quirks, I still find it very, very useful.


An alternative I've found for "xhost + localhost" is "xhost + local:" (include the colon), which allows all local network connections only. The practical differences are minimal, but it seems there may be some circumstances where this matters; I haven't been able to fully nail this down yet.
[Append to This Answer]
Next: (Answer) Profiling Apache Processes
This document is: http://help.loncapa.org/cgi-bin/fom?file=166
[Search] [Appearance] [Show This Answer As Text]
This is a Faq-O-Matic 2.719.
This FAQ administered by the LON-CAPA team at MSU. Submit a help request ticket to contact us.