mtusbabu has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monkers, I want to debug the CGI file with step by step execution. Is there any module to test the CGI file and the form inputs? Thanks Babu kannan

2006-08-25 Retitled by holli, as per Monastery guidelines
Original title: 'CGI problem Help me...'

Replies are listed 'Best First'.
Re: How to debug CGI scripts?
by marto (Cardinal) on Aug 25, 2006 at 13:16 UTC
Re: How to debug CGI scripts?
by davorg (Chancellor) on Aug 25, 2006 at 13:25 UTC

    There is nothing complex about debugging a CGI program. It takes input either from the environment (in the case of a GET request) or from stdin (in the case of a POST) and writes output to stdout. So you just need to set up the correct environment variables and then you can step through your program debugging it with the standard Perl debugger.


    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: How to debug CGI scripts?
by zentara (Archbishop) on Aug 25, 2006 at 13:44 UTC
    You can use the graphical ptkdb debugger to debug cgi scripts. Google for "ptkdb debug cgi" and read the links. There a quite a few step-by-step tutorials.

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: How to debug CGI scripts?
by derby (Abbot) on Aug 25, 2006 at 13:51 UTC
Re: How to debug CGI scripts?
by perlfan (Vicar) on Aug 25, 2006 at 14:22 UTC
    If it is not too reliant on user interaction at this point, you can run it at the command line. I use this method often early on in the coding process to figure out why I get a blank screen but no crazy webserver error that tells me nothing about what went wrong.
Re: How to debug CGI scripts?
by Anonymous Monk on Aug 25, 2006 at 13:49 UTC
Re: How to debug CGI scripts?
by eXile (Priest) on Aug 26, 2006 at 17:27 UTC
    I second (or third ..) the commandline debugging. You can add parameters to a script using CGI like this:
    # arg1=value1 arg2=value2 arg3=value3

    A nice trick I've learned is that you can use the -t test operator (tests if stdin is a terminal) to do command line debugging that won't show up if your script is ran on a webserver, something like:

    #!/usr/bin/env perl use strict; use warnings; use CGI qw(param header); $|=1; my $cgi = new CGI; my @params = $cgi->param(); if (-t) { print "cmdline mode!\n"; } else { print $cgi->header(); } my $fmt; if (-t) { $fmt = "%s:%s\n"; } else { $fmt = "%s:%s<br/>\n"; } foreach my $p (@params) { # normally you'd make sure stuff is untainted here # but this is for demo purposes so I left it out printf($fmt, $p, $cgi->param($p)); }
Re: How to debug CGI scripts?
by sfink (Deacon) on Aug 26, 2006 at 17:37 UTC
    Here's a trick I've been using for a while for this very purpose:

    On the client side, send over an extra parameter 'CHECKPOINT=1' with the rest of the data. In my case, the client is a command-line script that GETs or POSTs to the server with a bunch of data. If you're just using an HTML page with a form on it, add a hidden field named 'CHECKPOINT' with value '1'.

    On the server side (in your CGI script), check for the CHECKPOINT parameter. If it is given, write out the current parameters. In my case, I am using and have a query object stored in $cgi, so I use:

    if ($cgi->param('CHECKPOINT')) { local *STATE; open(STATE, ">/tmp/CGI-CHECKPOINT-".basename($0)) || open(STATE, ">/tmp/CGI-CHECKPOINT"); $cgi->save(*STATE); close STATE; }
    I forget why I used a fallback filename. Might be related to mod_perl. The effect of the above code is to write out all query parameters to a file in /tmp when a request is received with CHECKPOINT set.

    Now, to replay the request, run your CGI script from the command line with the environment variable CHECKPOINT set to 1. (So 'CHECKPOINT' is actually used for two completely different purposes: saving the state and replaying it. You could use different names if you like.) For replaying, you have to construct your query object differently. This code will come before the preceding code (because it's for setting up the query object):

    my $cgi; if ($ENV{'CHECKPOINT'}) { local *STATE; open(STATE, "/tmp/CGI-CHECKPOINT-".basename($0)) || open(STATE, "/tmp/CGI-CHECKPOINT"); $cgi = CGI->new(*STATE); close STATE; $cgi->delete('CHECKPOINT'); } else { $cgi = CGI->new(); }
    Now you can repeatedly run the CGI script from the command line, under the debugger, or whatever:
    CHECKPOINT=1 perl -d MyScript.cgi
    The reason why I named the checkpoint file after the CGI script is because I'm using scripts to make the HTTP requests on the client side, and many times they kick off a series of requests. I may want to debug an earlier one rather than the last one that happened (which is typically a little stub reporting success or failure to the server).

    One problem to watch out for: your CGI might easily behave differently if run as a different user than the one used when running under the control of the web server.

    The above logic is all wrapped up in a pair of modules that I use for all my CGI scripts and client-side scripts. As a result, whenever I have a problem with any of my scripts, I can run it with CHECKPOINT=1 and be stepping through the debugger in seconds; no need to modify the script in order to enable this replay mode. Also, this means that the functionality is available in the production scripts, so when a problem arises I have a straightforward way to capture a trace and debug it. (Depending on what your CGIs are doing, you might want to just use the checkpoint capture half on the production servers, then copy the resulting /tmp/CGI-CHECKPOINT* file over to your test server. Much less likely to screw up the production server by hanging onto a lock file or creating a file as the wrong user and thereby breaking every subsequent request.) (Not that I'm saying that has ever happened to me.) (But you'll notice I didn't say that it hadn't.)