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

I've created a "multi-form" .cgi script written in Perl (Program A). By "multi-form", I mean it repeatedly accepts user input and submits it to itself. To illustrate, Program A creates Form A; Form A's input gets processed by Program A; Program A creates Form B; Form B's input also gets processed by Program A; Program A now creates Form C, etc. etc. etc.

The program is processing user input in unexpected ways. So I fire up the program from the command line with the debugger running. I enter input for Form A from the command line. The problem is, after I enter this input, both the debugger and Program A execution halts. So I never get an opportunity to enter data for Form B and continue on with my troubleshooting.

I tried fiddling with the debugger's 'inhibit_exit' option but this didn't do any good. Can someone point me in the right direction? How do you debug multi-form .cgi scripts?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar;
$nysus = $PM . $MCF;

Replies are listed 'Best First'.
Re: Using Perl's Debugger on
by arturo (Vicar) on Apr 18, 2001 at 17:15 UTC

    It should be clear why you can't replicate the CGI behavior from the command-line; the normal way of getting to form B is to submit an HTML form to a webserver, but there's no webserving and no submitting going on from the command line. One way of getting to form B is to give the script input that looks like it came from form A, and this is possible because CGI.pm can process arguments from the command line.

    ./myscript.pl foo=bar baz=bletch
    will act just like
    http://www.foo.com/cgi-bin/myscript.pl?foo=bar&baz=bletch

    So you might look into that (I think you can even save a CGI object to a file, which would replicate the form variables; you could then read in those variables on the command line with ./myscript.pl < savefile. I'll admit to not knowing *much* about that, though.

    As an aside: you don't *need* the debugger to track down the errors. Just sprinkle some print statements into your CGI routines to help you track the changes to the variables over time, that will help you localize the errors.

    HTH

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

      Thank you, man. That did the trick! I did not know cgi.pm can process elements from the command line.

      I'm aware that one can use print to debug. However, since the root cause of this problem was my spaghetti code, "print" would have never worked in this particular case. Debug was the right tool for this job and I found the problem with it. Thanks again.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar;
      $nysus = $PM . $MCF;

        If the root cause of the problem was spaghetti code, then the root solution must be to learn to write better code...

        UPDATE
        The Monastery is full of good resources for improving. :-)

Re: Using Perl's Debugger on
by davorg (Chancellor) on Apr 18, 2001 at 17:22 UTC

    HTTP being a stateless protocol, this behaviour is to be expected. Each invocation of the form to process another phase of your form is completely separate from the previous one.

    To get round that, your script must be doing something to maintain state between invocations. This can be achieved in one of a number of ways - you might use cookies or some kind of session info in the PATH_INFO or it might be as simple as using hidden fields on the second (and subsequent) forms. You need to work out how you're doing that and simulate it in your other debugging sessions. If you're using hidden fields then it's easy enough to just send extra CGI parameters to the scripts.

    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

      If one is using CGI.pm an easy way to save state from Form Handler A to Form Handler B is
      1. In Form Handler A save the query object to a reference to a filehandle, e.g. $q->save(\*Q_NEW_USER);
      2. In Form Handler B retrieve the query object, e.g., $q_new_user = new CGI (\*Q_NEW_USER);

      Edit 2001-04-18 by tye to close list

(tye)Re: Using Perl's Debugger on
by tye (Sage) on Apr 18, 2001 at 18:00 UTC

    You can put your script at a web address where only you will find it and then tell the debugger to start and contact you at your terminal so you can debug the script in its full environment. The devil is in the details, but there are a lot of options on how to do this.

    Something like:

    BEGIN { if( @ARGV && "-d" eq $ARGV[0] ) { shift @ARGV; } else { my $tty= ( split ' ', (grep /^tye\b/, `who`)[0] )[1]; $ENV{PERL_DBOPTS}= "TTY=$tty"; exec $^X, "-d", $0, "-d", @ARGV; } }
    might work (you'll have to give the CGI user permission to read and write from/to your tty).

            - tye (but my friends call me "Tye")