Debuggers

If you are programming in a high-level language and want to run a debugger, it is usually impossible to do so directly. However, it is possible to simulate the environment in which an Apache script runs. The first thing to do is to become the user that Apache runs as. Then, remember that Apache always runs a script in the script’s own directory, so go to that directory. Next, Apache passes most of the information a script needs in environment variables. Determine what those environment variables should be (either by thinking about it or, more reliably, by temporarily replacing your CGI with one that executes env, as illustrated earlier), and write a little script that sets them then runs your CGI (possibly under a debugger). Since Apache sets a vast number of environment variables, it is worth knowing that most CGI scripts use relatively few of them — usually only QUERY_STRING (or PATH_INFO, less often). Of course, if you wrote the script and all its libraries, you’ll know what it used, but that isn’t always the case. So, to give a concrete example, suppose we wanted to debug some script written in C. We’d go into .../cgi-bin and write a script called, say, debug.cgi, that looked something like this:

#!/bin/sh
QUERY_STRING='2315_order=20&2316_order=10&card_type=Amex'
export QUERY_STRING
gdb mycgi

We’d run it by typing:

chmod +x debug.cgi
./debug.cgi

Once gdb came up, we’d hit r<CR>, and the script would run.[5]

A couple of things may trip you up here. The first is that if the script expects the POST method — that is, if REQUEST_METHOD is set to POST — the script will (if it is working correctly) expect the QUERY_STRING to be supplied on its standard input rather than in the environment. Most scripts use a library to process the query string, so the simple solution is to not set REQUEST_METHOD for debugging, or to set it to GET instead. If you really must use POST, then the script would become:

#!/bin/sh
REQUEST_METHOD=POST
export REQUEST_METHOD
mycgi << EOF 
2315_order=20&2316_order=10&card_type=Amex
EOF

Note that this time we didn’t run the debugger, for the simple reason that the debugger also wants input from standard input. To accommodate that, put the query string in some file, and tell the debugger to use that file for standard input (in gdb ’s case, that means type r < yourfile).

The second tricky thing occurs if you are using Perl and the standard Perl module CGI.pm. In this case, CGI helpfully detects that you aren’t running under Apache and prompts for the query string. It also wants the individual items separated by newlines instead of ampersands. The simple solution is to do something very similar to the solution to the POST problem we just discussed, except with newlines.



[5] Obviously, if we really wanted to debug it, we’d set some breakpoints first.