|
Debugging FAQ
Here is where you will get help debugging Perl CGI scripts.
If you do not find your questions answered here, please contact us.
Installation/Set-up Problems
- It won't work.
- SUEXEC Error.
- Error 404 - File Not Found
- I run the program and get a blank screen.
- I run the program and it appears to work but
no data is being stored or it won't print out the data.
Most Common Installation/Set-up Mistakes
- Wrong path
- Relative Path vs. Absolute Path vs. Full URL
- Binary vs. ASCII
- Too many slashes.
- Require this! (a.k.a. @INC this!)
- Let the Tail wag the dog.
Debugging your masterpiece.
- It won't work.
- Run it through Perl to check it.
- Take a break or ask a friend.
- Print Statements. The Programmers Best Friend!!!
Back To FAQ List
- It won't work.
- Okay, I figured it didn't and that's why your here. The first thing we
must determine is did the error occur in the script itself or on the
server side of the program. How do we do this ? Easy!!!
- Check and make sure that the path to Perl at the top of the server is
correct. It should look like:
#!/usr/bin/perl
or
#!/usr/lib/bin/perl
To find the correct path to Perl, Telnet into the server and at the command
prompt, type: whereis perl...and the server
will show you the correct abs-path to Perl.
- If you ran the program and got an error message returned to your browser,
the problem is in the program itself (You made a typo...).
Try sections:
2,
3,
8,
9,
10
- If you ran the program and got back a blank screen, the problem is on
the server (File permissions or files can't be located).
Try sections
4,
5,
6,
7,
10,
11
- If you ran the program and got a result but it wasn't what you expected,
then were back to square one as it could either be a logic error in the
program or an error on the server. The server is the easiest problem to
eliminate so start there.
Try sections
4,
5,
6,
7,
10,
11,
12,
13,
14,
15,
16
Top
- SUEXEC Error.
- There are two common occurences that cause a SUEXEC error. The first is
that you forgot to CHMOD the .pl or .cgi file after you FTP'd it to the
server. If this is the case or your not sure, go back and CHMOD the files
and try running it again.
The second most likely cause of this is that you were a little trigger happy
and tried to call the script in the browser while it was still in transit
to the server via FTP. If this is the case, try running it again. If you
get the same error over again and the files are CHMODed correctly, you are
going to have to Telnet into the server and kill the process that is running
and occupying the script. You will have to check with your System Administrator
or ISP for the exact commands to do this on your server.
Top
- Error 404 - File Not Found
- You entered the wrong URL in the address line of the browser.
If you entered it correctly, check again and make sure that the spelling
of all the directories and the filename is correct. Finally make sure you
didn't swap .pl or .cgi for the other one on the file extension (Yes, I
learned that lesson the hard way).
Top
- I run the program and get a blank screen.
- This is a good sign. At least it's likely that the error will be on the server
but it could still be a logic error. Let's look at potential server causes:
- The first and most likely cause is that you have set one of the variables
in the program incorrectly. Go back over the documentation that explains
setting the variables paying particular attention to the absolute paths. Also
confirm whether the documentation says to end the absolute paths with or
without a trailing "/" slash.
- Next, check to see if the script calls for the full URL to the program,
if it does, make sure you entered it correctly. Most programs will be able
to determine that for itself via Environment Variables.
- Check and make sure that you CHMODed all the data files, data directories
and parent directories to the correct permission setting. Most scripts will ask you
to CHMOD these to 766 or 777 with the occasional "read-only" file of 744.
If you are running on an Apache server, change this CHMOD to 777 and the
program will probably work. If you don't know if your on an Apache server or
not, then change the CHMOD to 777 on the data files/directories anyways and try running
it again. If it still doesn't work, leave the CHMOD to 777 until the program
is running then you can go back and try resetting it to 766.
- Check and make sure that you created all the necessary directories for
the program. Some will require that you make sub directories in the data
directory that you created first. These sub directories must all be CHMOD the
same as the data directory you created first.
- This will take a bit longer. Go through each script in the program, checking
all the OPEN commands for reading from/writing to files and make sure that all
paths are reflected correctly and that there wasn't a typo in any of the paths.
I learned this one the hard way on a program that I downloaded from a site.
- If it still doesn't work, it's most likely a logic error in the program.
Examine sections 12,
13,
14,
15,
16.
Top
- I run the program and it appears to work
but no data is being stored or it won't
print out the data.
- It appears to work. I guess this means that you receive some HTML content
on the browser that was generated by the program. This is great! It means that
the error has been narrowed down to either an absolute path is wrong in one
of the variables you configured, a typo in one of the OPEN commands or a
permission is incorrect. See more on these in the section above!
Top
- Wrong path
- One of the most common mistakes in setting up a program is incorrectly
entering the absolute path to a file/directory in one of the configurable
variables. Here are some hints:
- Check the program documentation carefully to see whether or not
they want the absolute paths to end in a trailing slash "/" or not. Once you
have done this, check each of the variables to make sure they are entered
correctly.
- Make sure that the absolute path is complete. The absolute path must be the
absolute path from the top level directory on the server and not just from
the Root levle directory for your website !
- Carefully check the spelling of everyword in the absolute path in each
of the variables. Windows is not usually Case Sensitive but Unix machines are
always cAsE sEnSItIvE.
Top
- Relative Path vs. Absolute Path vs. Full URL
- Confusing the type of path you need to provide is an absolute guarantee
that the program won't work. Use the following guidelines if the documentation
of the program doesn't seem to be very clear about which of these three
you are providing:
- Absolute Path - An absolute path will always be called for
in a variable that is referencing a data file, data directory, sendmail or
the location of the Perl interpretor on the server. You will also be required
to provide an absolute path if the program is asking you to add information
to the @INC array near the top of the program. None of these things will
ever require a relative path or full URL.
- Relative Path - Relative paths are used all the time in HTML documents
for links to sites, links to programs, links to sound files, links to images/movies
and links to e-mail forms. There is only one instance in Perl programming
where you will be asked to provide a Relative Path and that is in the
call for a Server Side Include. Check to make sure relative path is absolutely
correct. If it is, then check with the System Administrator/ISP to make sure
that you have written the actual call itself correctly.
- Full URL - You may be asked from time to time, in addition to an
absolute path, to provide the URL to a file or directory in a programs variables.
As with absolute paths, check to see if the varialbe wants a trailing slash
at the end, whether the spelling of the full URL is correct and if there is a
document name in the variable you are setting, make sure the extension is correct.
If the extension is supposed to be .html and you put .htm, you will get a
404 Error.
Top
- Binary vs. ASCII
- The second most common mistake setting up a program on a server is that
you mistakenly transfered it as a Binary file and not an ASCII file. It's
easy to do accidentally. If you do this, however, you should get an error that
says something like:
Illegal character \015 (carriage return)
at notebook.pl line 2.
Top
- Too Many Slashes
- Sometimes, while typing a URL, Abs-Path, etc. your fingers will get
carried away. While looking at all your coding it blends in but what has
happened is you have double typed a slash mark. For example, the following
two paths are almost identical except for one doulbe tapped slash mark:
/home/name/public_html/logs/prog/eftd/says
/home/name/public_html/logs/prog//eftd/says
Top
- Require this! (a.k.a. @INC this!)
- If you are using/setting up/coding a program that has more than one
file with it, you most likely will have to require one or more of the files
into one or more of the other files.
Requiring a file is simply the Perl
way of saying "Pssst,....whatcha got bub?". Requiring a file allows the file making
the require call to use the contents of the file it required. If you need
to use the content from another file but forget to "Require" that file, the
program will fail. When this happens, the error that the Perl Interpretor
usually generates will be very close to:
Failed to find subroutine package Main::SomeSubroutineName
at program_name.pl line 347
If this happens to you, check all your require statements. If they are all present, check
to make sure you didn't forget to write a whole subroutine. (Yep, another hard learned lesson).
Top
- Let the Tail wag the dog.
- I found a program that has since proved invaluable to me. It
is called "tail.cgi" and what it does is print out the error log for your
servers Perl interpretor for your domain. I use it whenever I can't get the
program to run to a point where it returns anything. So long as I keep
getting server errors, it is "tail.cgi" that I have to run to to see what
is causing the problem. You can see "tail.cgi" in action on our domain at:
http://www.perlservices.net/cgi-bin/tail.cgi
If you don't have this program running on your server, download it now
and install it. We also have our own version of this program that allows a couple
extra options. We'll be developing this one more in the future:
http://www.perlservices.net/cgi-bin/errorlog.cgi
You will have to obtain the absolute path to your error log
from your virtual hosts support department to set up the program. Once you have that
value in place, load and CHMOD the script to 755 then call it by entering
the full URL to the program in the address line of your browser.
Top
- It won't work.
- This is an easy one. You've been starring at the program/screen for hours on end, maybe
you've been debugging this one for a few days. No matter what you do it still won't work.
Your spouse and kids are afraid to enter the room your in for the blueness of the epiphets
and the dog is considering turning himself into the pound just to get away from your murderous
glare. What if I tell you we can probably fix the program tomorrow morning???
YOU NEED A BREAK ! ! !
Get away from the damn computer! Turn it off, go for a walk, watch a movie, do anything. Stay right
the heck away from the computer for the next 24-48 hrs. Once the time has gone by
and you are sufficiently refreshed and rejuvenated, come back to the computer. Open the file
with the program and 95% of the time you'll spot the error and have it fixed within ten minutes!
Don't believe me? Next time you get stuck, try it.
Top
- Run it through Perl to check it.
- Your writing Perl programs. You obviously have Perl installed on your
desk top computer (IBM or Mac). If you don't have Perl installed, go do it
now. That's someone else's tutorial so I can't help you do it.
Dum de dum, dum.....dah-dah-dah-de-dum......
Oh! Your back, great!!!!
Now, launch your Perl program (DOS window) and assuming the program is
called burp_count.pl, type this in the DOS window:
perl -c burp_count.pl
What the Perl interpretor does is go through the program line by line and statement
by statement checking for errors. It prints out all these errors for you!
On your first pass through, fix as many as you can see, then on your next pass through
fix as many as you can still see! Keep on going like this until you see the
reverent message "Perl Syntax OK". When you see this, the program is error free! (Ahhh,
that would be Syntax error free.....not logic error free).
Just so you know, if I'm debugging a large program, 1500-2000 lines of code, I'll run
the program through the interpretor in this manner maybe fifty to seventy times or even more
before I get all the bugs worked out.
Top
- Ask a friend.
- It's still not working? It's time for an old trick. Give the program to a friend/co-worker/colleague and
let them have a look at it. Your probably just so wound up in it now you couldn't see the error if it did a
hoochie-coochie dance right in front of you. Sometimes all it takes is a fresh set of eyes to see what your
missing.
I remember one night I was beyonbd hope, having spent six hours trying to debug a program that the
client was yammering for. I had to have it delivered by the next a.m. and still had half way to go because
this one error was holding up the whole debugging process.
Just then my wife came in and leaned over my shoulder (her computer savvy extends to being able to turn the computer
on and that's about it) and said "Why do you have those two slash marks together?". Yep, double tapped slash marks
in an absolute path.
If you don't have someone else to look at it, go work on another project for a while then come back to it and look
at it fresh. Again.
Top
- Print Statements. The Programmers Best Friend!!!
- The most common error that causes problems with a program is that
logical processes don't perform as expected or variables don't
contain the values expected. This is as a result of missed math processes
or logical errors or just about a hundred-gazillion other things you can
do wrong but not see till afterwards.
One of the most common sets of
mistakes is that you fail to end a print statement correctly (you forget the
\n"; at the end of the line) or you forget to escape an '@' symbol, quote or hash mark
when you want it printed out. If you don't escape them ( \', \", \#, \@) then
the program will read them as part of the program and an error will occur.
Other times you just can't figure out why the program isn't working just
the way you want it to. There is a fairly easy solution for all this.
- Move your print header to the top of the program, so that it comes
before any of the logical processes.
print "Content-type: text/html\n\n";
- Now, at every logical junction, process, step, variable assignment, computation, etc. put a print statement!
Print out everything that you may think might be affected by or affecting the
inconsistency. This way when you run the program, on the resulting page
you will see what values are being returned. Here are what some of my print statments in a debug look like:
print "\$var is $var<BR>\n";
print "\@array is @array<BR>\n";
print "Subroutine \&CheckDoc accessed<BR>\n";
I know trying to interpret what I'm doing is hard from the above example so I
have included a more complete one below. What you will be seeing is a subroutine
from one of my programs. You will see, within this subroutine, many print statments
similar to above showing exactly how I debugged this subroutine. I can't explain
this any better than the example shows you. Note in this example, however, that
it is only a few lines long but you will get the idea of how I'm using the print statements
and what applies here also applies to a program 3000 lines long. Only thing is I debug one
section/sub-routine at a time:
sub RemoveFile {
print "RemoveFile sub accessed<BR>\n";
print "\$FORM{'file_number'} is $FORM{'file_number'}<BR>\n";
&GetConfigs;
if(open(FILES, "<$Data/admin/files.list")) {
print "Admin Files list open for reading<BR>\n";
flock(FILES, '2');
@get_files = <FILES>;
close(FILES);
chomp(@get_files);
$num_files = @get_files;
print "\$num_files is $num_files<BR>\n";
open(FILES, ">$Data/admin/files.list");
print "Admin Files list open for writing<BR>\n";
flock(FILES, '2');
for($a = 0; $a < $num_files; $a++) {
unless($get_files[$a] =~ /^$FORM{'file_number'}/) {
print FILES "$get_files[$a]\n";
print "Return to file list line $a<BR>\n";
}
}
opendir(READ, "$Data/logs/$FORM{'file_number'}");
@dir_files = readdir(READ);
print "\@dir_files is", @dir_files, "<BR>\n";
foreach $dir_file (@dir_files) {
print "\$dir_file is $dir_file<BR>\n";
unlink("$Data/logs/$FORM{'file_number'}/$dir_file");
}
rmdir("$Data/logs/$FORM{'file_number'}");
$dos_file_num = $FORM{'file_number'};
unlink("$FileDirAbs/$DOS{$dos_file_num}");
&PrintHead('Successful Addition');
print "<P><B>The file was successfully removed.</B><BR><BR><BR><BR>\n";
print "<FORM ACTION=\"$ScriptURL?admin\" METHOD=\"POST\">\n";
print "<INPUT TYPE=\"HIDDEN\" NAME=\"user\" VALUE=\"$FORM{'user'}\">\n";
print "<INPUT TYPE=\"HIDDEN\" NAME=\"pass\" VALUE=\"$FORM{'pass'}\">\n";
print "<INPUT TYPE=\"SUBMIT\" VALUE=\"Return To Admin Page\"></FORM><P>\n";
&PrintFoot;
} else {
$Problem = "the program was unable to open the main list of files to remove this file.";
&Error($Problem);
}
}
Play with the print statments and determine the best way for you to use them.
If I'm working on a live script, I will still use the print statements but I
will instead direct them to print to STDERR instead of to the screen. To make
a print statement go to STDERR use it thus:
print STDERR "\$var is $var<BR>\n";
print STDERR "\@array is @array<BR>\n";
print STDERR "Subroutine \&CheckDoc accessed<BR>\n";
Once this is done, you can then check the Perl interpretors error log to
view the results of your debug.
Top
|