Concepts
Debugging CGI programs is a pain in the ass. Generally speaking, it's voodoo and looking at the HTTPD error logs. Unless you're into a lot of pain, it's essentially impossible to sneak a look at the state of a program, let alone control it. That's what the CGI debugger deals with. Invoking the debugger does the necessary rigamaroll to actually run gdb (and hopefully other gdb like debuggers) on your program. Eventually, I hope to have support for debugging Perl and Java based CGI programs too, but for now it's just gdb.The debugger is really in two separate halves: the browser side debugger, which is a Java Applet, and the backend programs cgidbg and cgife which do the necessary plumbing to insert the debugger in front of the CGI program. In order to invoke the debugger, you simply invoke the debugger with the parameters set to to be debugged program, ie:
/cgi-bin/yourprogram would become /debug/cgidbg?/cgi-bin/yourprogramWhen invoked, a debugger window will be popped up, the applet will be loaded and you'll be on your way.Operation
Generally speaking, all the hard work to use this is in the setup. Once you have the debugging directories properly configured with your httpd, it is simply a matter of calling the debugger with your program by executing it first with the program as its parameter. Cgidbg will then pop up a new browser window to capture the output of your program. The debugger window will start up the Java applet. This applet behaves essentially like a terminal window with input taken from the text entry window.At this point you can specify breakpoint, etc to stop execution of your program. In order to run your program, you simply need to type "run" to gdb.
Caveates
There had to be a few catches, right? Yup.
- The program exited, but I don't see output!
- Given the way the plumbing is done, you must quit the program. Yes, this is unhappy, but not quite as bad as it may sound. In order to rerun the program, you can hit the reload button on the browser.
- The output window sometimes times out!
- Yep, there's nothing that can be done about that. It doesn't really hurt anything though, your program's output will just not be displayed. The browser timeout is pretty long, so you don't normally hit up against this.
- Why can't I see my source?
- Because the path to your sources is screwed up? Getting the URL->Source path set up is somewhat of a pain. You can always cd to the proper directory, but a better solution is to create an executable directory ala cgi-bin, and map your build directory to it. See the explanation in the setup section of this page.
- Why can't I interrupt the program and stay in the debugger?
- I haven't figured this part out. Running gdb as an inferior emacs process is still attached to a terminal, and thus ^C's work. There is no controlling terminal in this scenario, so it's more problematic. Since gdb is the one forking the shell to run the program, I don't know what its pid is to send the SIGINT -- an unfortunate problem. Someday I'll get around to it, but at least you can kill the entire shebang off now.
- Why is the interface so lame?
- Uh, because I've not gotten around to making it pretty?
Setup
The setup of the Debugger is a pain in the butt, but it's getting better so don't whine.
- A Word About Security
- The debugger is a huge potential security hole! Don't just assume that what is here is in accordance with your site's security policies! Allowing an outsider, or even somebody behind your firewall to debug CGI programs means they can gain access to your server and potentially do damage. The default's I've set up are to limit debugger access to all machines within the same domain, but you may want to limit it further to one or two specific machines.
In all cases, it would probably be a wise idea to stage your development on a separate machine from your public web server, and release debugged executables onto your public server when you're done.
- HTTPD setup
- Currently, the debugger expects to be in two top level URL's /debug and /debughtml, and which correspond to SERVERROOT/debug/bin and SERVERROOT/debug/html respectively on your HTTPD server's filesystem. These directories are created for you with the installation script below, but you will need to do some mucking with your HTTPD configuration. If you're using the Apache or NCSA HTTPD's, it's fairly straightforward:
- In the srm.conf for the site add the following lines:
ScriptAlias /debug/ /user/httpd/debug/bin/ Alias /debughtml/ /user/httpd/debug/html/This has the effect of telling your httpd that the top level directories at SERVERROOT are visiable to the world.
- In the access.conf for the site add these lines.
<Directory /user/httpd/debug> Options <Limit GET POST> order deny,allow deny from all allow from .mtcc.com </Limit> </Directory>Note: this assumes that your SERVERROOT is set to /user/httpd and that your server's local domain is .mtcc.com. See the section on security to see if you might want to tighten your security further.
- How do I get source line information?
The debugger is sort of lame about where your source is stored at. The main problem is that it doesn't know what the correspondence between where your program lies in URL space, and where the program is in file system space. The way I got around this problem is create a top level directory which you can execute CGI scripts from which is insulated from the outside world like in access.conf:<Directory /home/mike/cgi> Options <Limit GET POST> order deny,allow deny from all allow from .mtcc.com </Limit> </Directory>and in srm.conf:ScriptAlias /mike/ /home/mike/cgiThis is or something similar is what you should be doing anyway to develop CGI programs. However, this doesn't solve the source code problem, however. In order to get that to work, I created a symbolic link from SERVERROOT/mike to /home/mike/cgi. This has the effect of syncing up the file system /mike to the URL space /mike. Suggestions here are welcome, but I suspect that this is just another unpleasant problem of mapping URL space to file system space. Maybe someday I'll parse the srm.conf to get the poop on this sort of thing, but for now it's lame.
- Restart your HTTPD.
- Installation
- Once you've followed the steps above, you are ready to actually install the debugger. First, you need to set SERVERROOT in Configuration to the path where your HTTPD lives. After changing it, return the top level of the libht package and type :
make install_debugAnd you should be on your way.
- Running the Debugger
- To run the debugger, you need to insert the debugger into the execution path. See the Concepts and Operation sections of this page for further details. To test out the configuration, however, you can open the following url:
http://your.host.name/debug/cgidbgIf the debugger is installed properly, it will pop up a new window (the output of the debugged program) and a window with the applet running. You can actually debug a file (any file!) from here by using the "file" command in gdb.
- Other Debuggers
- I have tested this on a Mips Risc OS beast running dbx with not great results. The main problem is that the debugging front end needs to feed the debugger with pipes to redirect the output from the application back to the browser along with being able to pre supply the redirection. Other debuggers may be more intelligent, but I suspect that getting GDB is probably the easiest overall solution. This problem will undoubtably be revisited when I try to get jdb and the perl debugger to work.