Being a programmer by nature (and by degree) and I have dabbled with a lot of different computer languages. Some I fluently code in, others are nice for rapid development, and some are for someone else. I have been working on moving some Perl web applications to a new server. Typically this wouldn’t be too big of a deal. You make sure you have all the modules, make sure you have the correct permissions, make sure you have Apache configured to do CGI, and then you move the files and everything should work. In this instance, someone forgot to read ‘Modular Programming and Best Practices for the Perl language,’ a book surely someone has written. The code I am working on does not make very much use of the CGI-BIN directory, it has Perl scattered all through out HTML files, and there are not any comments or direction. The worst part is that the programmer chose to use Microsoft Visual C++ variable names to name Perl variables. For example, a string in this script is $m_lpszData… This is wrong on so many levels. The only thing I am going to point out is that Perl doesn’t explicitly use pointers, that’s all I’m going to say. If this last piece doesn’t make sense to you, then you have had a very sheltered programming career.
Now the main point of adding this entry is to have somethings in here that have been major breakthroughs for me. The first is understanding that Internal Error 500 doesn’t mean anything at all. In fact, it has to be the worst error message ever created. Who would create a serious error message and then not give any detail as to why the error happened. I understand on a production server, but offer some options to spew debugging madness.
After much research it is apparent that the Internal Error doesn’t receive any data that would help with debugging. Which is a sort of safe guard for the webserver. As soon as the fatal error happens, it nukes the script and then spew that information. Most of the time, the information in the logs (/var/log/apache/user/default.log if using virtualhosts or ISPCP) is not very helpful and quite vague.
Despite the lack of information I figured I would use an old C trick to print out each line and variable to see where the issue was. The problem is that with Internal Error 500, you don’t get any return at all. So I did one better, I was able to use Carp, a debugging framework for Perl. That with randomly place ‘die’ statements I was able to follow the flow of code execution. The issue is that I wasn’t able to track down the real reason for the software bug. Finally I stumbled upon CGI::Debug. This module rules. It figured out a way to supersede the Apache Internal error and it gave me all the information about the running script and exactly where it died. With this information I was able to see that I was never printing the header information out, which was never creating a proper webpage for Apache to serve up. I added a few print statements and was able to get the expected functionality.
Now as I continue on my journey of Perl debugging, I found a few other tips that are very helpful, use perl -wc [script name] to compile the script and check it. Use perl -d [script name] to start the Perl debugger which allows you to step through code. Lastly, you can use rm * -f if you get stuck… Just kidding, don’t do that unless you have a backup copy or know how to recover deleted files. Hopefully I am able to wrap this project up, I am ready to be done with Perl. In my opinion, PHP is much more flexible, intuitive, and powerful.
Mike