8.3.2 Debugging a CGI Program
8.3.2 Debugging a CGI Program
A CGI program is usually difficult to debug because errors printed on the browser are frequently cryptic. A CGI program can produce an error in many ways. Some situations are discussed below. The books Perl Debugged [SW01] and Writing CGI Applications with Perl [MM01] have more suggestions regarding how to effectively debug a Perl CGI program.
The Web browser complains if the CGI program cannot be found in the place where is is supposed to be (see Figure 8.4). The Web browser complains if the CGI program does not have the location of the Perl interpreter as the first line. In such a case, the Web server can find the CGI program, but does not know how to execute it. The Web browser complains if the first thing the Perl script writes to standard output is not one or more HTTP headers. In addition, the Web browser complains if the headers are not followed by an empty line. The Web browser also complains if there is any syntactic or run-time error in the Perl program.
Let us go through some usual steps in debugging an errant CGI program. A working CGI program must be syntactically correct. Therefore, it makes sense to check the Perl program for syntactic correctness in a terminal window before calling it from a browser. One can simply use the -c flag to do so as shown below.
%perl -c countdown.pl
countdown.pl syntax OK
In additon to the c option, one can use the w flag as well to get more detailed warnings about errors and possible errors of all kinds.
%perl -cw countdown.pl
If the syntax of the CGI program is incorrect, it produces an Internal Server Error when called from a Web browser (see Figure 8.5). A working CGI program must produce no run-time error. We can run the program from the command-line to make sure there are no run-time errors. This CGI program requires no input, and hence can be run easily from the command-line. When we run the current program from the command-line, it produces the following output. We can examine this output to determine if it is the expected output to be displayed on a Web browser.
%countdown.pl
Content-type: text/html
<HTML>
<HEAD><TITLE>Simply counting...</TITLE></HEAD>
<BODY><H1>Simply counting...</H1><P>
10...
<BR>
9...
<BR>
8...
<BR>
7...
<BR>
6...
<BR>
5...
<BR>
4...
<BR>
3...
<BR>
2...
<BR>
1...
<BR>
</BODY></HTML>
In this case, the HTML produced seems acceptable. Also, there is the required HTTP header line(s) on top followed by a blank line. If a CGI program produces a run-time error, the browser reports an Internal Server Error (see Figure 8.5).
Suppose our CGI program is syntactically correct and produces no run-time error, but we still get an error message when we run it from a browser. Obviously, there are other problems with the CGI program in such a case. The HTTP server’s logs are very helpful in such a situation. If an error of any kind is reported on the browser, a corresponding error which is usually more informative, is logged on the server. The errors are logged in the directory specified in the ServerRoot directive in the configuration file discussed in Section 8.2. In the case of the Apache Web server on a Red Hat Linux machine, the logs are in the directory
/etc/httpd. One should go to this directory and then look at the logs/ sub-directory in a Red Hat Linux machine. This directory may have a different name if we are using a Web server other than Apache. Usually there are one or more error log files. In the case of the Apache Web server, the files are named with the substring error_log somewhere in the name. One should look at the end of the latest error log file if there are several error log files. Usually, the error log files are huge. Therefore, bringing up an error log file in an editor or looking at this file in the terminal may be
tedious. In Unix, one can use the tail command to look at the last few lines of the file. If one checks the error log on the server machine immediately after finding an error in a CGI program being tested on a Web browser, it is most likely to that the error is at the bottom of the log file. Note that the browser can be anywhere on the Internet. The errors are always logged on the server.
Figure 8.4: Not Found Error in a CGI Program
Suppose we intend to look at the URL
http://pikespeak.uccs.edu/cgi-bin/kalita/perlbook/countdown.pl, but type
http://pikespeak.uccs.edu/cgi-bin/kalita/perlbook/mycountdown.pl
by mistake on the browser’s Location box. Therefore, we get an error on the browser screen. The error on the screen looks like that in Figure 8.4. In addition, as mentioned earlier, the Perl script must be in one of the acceptable places on the server. Otherwise, the browser gets an error message saying the CGI program cannot be found. Now, if we look at the bottom of the HTTP error log file on the Web server pikespeak.uccs.edu more or less immediately after the occurrence of the error, we see the following entry. The line has been broken into two since it is very long.
[Tue Jun 19 09:04:40 2001] [error] [client 128.198.162.231]
script not found or unable to stat: /var/www/cgi-bin/kalita/perlbook/mycountdown.pl
It gives us the time at which the error occurred, the machine on which the browser is running, and a brief description of the error. It says that the CGI script could not be found or crucial system-level details about the file could not obtained by the server. The stat command in Unix gives information on a file.
To simulate another error, let us rewrite the same CGI program, but leave out the line that prints the HTTP header. The revised program is given below.
Program 8.2
#!/usr/bin/perl #countdownError1.pl print "", "\n"; print "Simply counting... ", "\n"; print "Simply counting...
"; print "", "\n"; $countdown = 10; while ($countdown != 0) { print "$countdown...\n"; print "
", "\n";
", "\n"; --$countdown; } print "
The modified CGI program is stored in the file in the same directory as the original countdown.pl file. It is called cuntdownError1.pl. Now, if we type
http://pikespeak.uccs.edu/cgi-bin/kalita/perlbook/countdownError1.pl on the
Location box on a browser, we see an error as shown in Figure 8.5. When we look toward the end of the error log file on the server, we see the following. It has been broken into several lines because it is long.
[Tue Jun 19 09:12:15 2001] [error] [client 128.198.162.231]
malformed header from script. Bad header=<HTML>:
/var/www/cgi-bin/kalita/perlbook/countdownError1.pl
It says that the string <HTML> is not a valid HTTP header. The browser does not get an acceptable HTTP header and therefore chokes. As noted earlier, the first thing the CGI program must write to the standard output is one or more HTTP header lines followed by a blank line. This requirement is not satisfied by the modified CGI program.
Figure 8.5: Internal Server Error in a CGI Program
If we change the permission on the CGI file countdown.pl so that it is not readable by everyone, we see the error as shown in Figure 8.6 on the browser. The Perl CGI script must have read and executable permission by everyone, and any directories it is contained in must be accessible to everyone. In a Unix system, this means that the directories must be readable and executable by everyone. Note that if a CGI program is in a user’s directory, accessible by a soft link, the user’s home directory must be readable and executable by everyone. The Web browser complains if this is not the case. The
Forbidden Error is caused by insufficient permission. On a PC or a Macintosh (pre-OS X), permissions are usually not a major source of problem. In a Unix machine, we can change the permission by using the chmod command. An entry is written in the log file as well.
Figure 8.6: Forbidden Error in a CGI Program
It is possible that there are two, even more, entries in the error log for a single Perl error, as shown below.
syntax error at /users/server/students/www/cgi-bin/smarndt/register.pl line 18, near "'email';"
Execution of /users/server/students/www/cgi-bin/smarndt/register.pl aborted
due to compilation errors.
[Sat Mar 16 15:11:51 2002] [error] [client 128.198.60.23] Premature end of script headers:
/users/server/students/www/cgi-bin/smarndt/register.pl
Here, there is a syntax error in the program register.pl. The error causes the program to be aborted due to compilation errors. This error string is sent out to the browser before the CGI program can send out an HTTP header. This results in a complaint by the server about premature end of script headers.
