Note: This blog post is from 2006. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
I was originally planning to dive into the features and use of FusionDebug, but if you followed the comments to my entry last night
you will have noticed that there was quite a discussion from some arguing "why should I bother with or care about step debugging? I can get all I need with CFDUMP."
I'd like to address that sentiment in this entry, showing the many ways (13, to start) that interactive step debugging can indeed be a valuable tool in the arsenal of a CFML developer, to solve problems they might otherwise find very difficult.
(I fear that if I instead proceeded with taking the time to first show the tool, some would stop listening because they have preconceived notions of what it is and can--or can't--do. More than that, I bet some will be surprised that it does things they never expected were possible, whether that perspective was formed by their work with debuggers in other languages or in the CF4/5 debugger.)
You can't always do a CFOUTPUT/CFDUMP
As others have commented, a first reaction some may have is that they can do all the debugging they need by using judicious (or indeed copious) CFOUTPUTs and CFDUMPs, or perhaps CFTRACE or CFLOG.
One problem, though, is that there are places where you can't create output.
For example, within a CFC or method where OUTPUT="no" has been set, CFDUMP and CFOUTPUT create no output. Now, you may think, "well I can just disable it," but there are times when doing so will introduce errors or otherwise unexpected results.
Another situation in which you can't create output is within CFSILENT. No output is rendered to the browser. Especially in complex apps and most frameworks, it's common for CFSILENT to be used, and you will have to find and edit the file that sets that to disable it while you do your debugging. There may be a negative impact by disabling the CFSILENT as all the code between there and what you're looking at executes.
Finally, you'll also need to remember to set all those changes back. (More on that later.)
You don't always have a browser to output to (Flex, Ajax, Web Services)!
The point above was about whether you could or could not use CFOUTPUT/CFDUMP. Beyond that, what if you're writing CFML code that is called by a Flex or Ajax client, or that's called as a web service? You can't then always reasonably add debugging output--and you certainly can't do a CFDUMP, if the client is expecting XML, since CFDUMP creates a big HTML table.
FusionDebug can indeed be used for debugging requests from Flex, Ajax, or web services apps. Indeed, it can intercept a call from any kind of client that requests a CFML page or CFC. More on that in a moment.
Now, some may point out that you could in such a case use CFTRACE or CFLOG to write out such output to a log file, and that's so, but it's certainly not as simple as dumping output to the screen.
You can intercept and debug a request from any user, not just the developer
This is a very important point, and actually is an extension of the point above. Unlike the CF4/5 debugger, FusionDebug is NOT limited to only debugging what you as a developer can browse yourself. It can intercept and show to the debugging developer the step-by-step execution of any template or CFC (or custom tag or included file) run by anyone in any manner. So you can use it to debug when someone else is running the request (where writing output to the browser would go to someone other than the developer). I know that may sound a warning bell to some. Hold that thought for a moment, and through the next couple of points.
You can debug a remote machine!
This may be the most powerful feature to some. FusionDebug can do debugging against any CFMX server for which it's been configured. It doesn't need to be just a CF server on the same machine running Eclipse. Not at all.
In a comment in my last entry, developer Tony Petruzzi said, "I believe that if FD had a remote debug like VS.net does, then it would be more appealing. Most of the time you need a step debugger when something totally whacky is happening and usually this occurs when the application is in production."
Well it does indeed do that, and his comment leads to yet another benefit.
You can debug against production!
As stated above, often the challenges you face are ones that you can't recreate in your development environment. Because of its design, there's absolutely no reason you couldn't do debugging against a remote server (production) and with the real end user running the request that's causing the problem you want to debug.
Of course, the above three points represent a two-edged sword. You can't currently limit the debugging to take place only for a given user, so if indeed you are using it on a server being used by multiple users, it will impact anyone who makes the request while you have debugging enabled.
Again, there's much we've not yet discussed on using the tool, so let me be clear: for this to happen, a) a developer would have to have opened Eclipse with FusionDebug, b) turned on debugging against that application/project, c) enabled a breakpoint for a given template, and d) the user would need to request that page and run through that code that would hit that breakpoint. (I'll discuss the details of enabling the debugger and setting a breakpoint in future entries, or it's discussed on the FusionDebug web site).
In such a case, a user would see the page appear to hang until the developer with debugging enabled responded to let the page proceed. I don't say this to scare you: it's just a responsibility to be aware of that comes with the power of the tool. (There's also some modest impact in configuring the server's JVM config to support debugging, so you may want to think carefully about leaving it enabled all the time in production. Again, I'll discuss this point in more detail in a later entry.)
There's no need to change code to get debugging info
With the previous points focusing on some of the unusual and surprising aspects of where and when you can use the tool, I don't want to lose sight of a very important point, perhaps too easy to miss. While some would argue they could just throw some CFOUTPUT/CFDUMP tags in to the code to do debugging, that's clearly less palatable to do in production.
Or perhaps you are doing debugging against some code that someone has ruled that it should not be touched (edited), or it may well be in a directory where you don't have access to edit the code to add any debugging tags. Or, as was discussed in one of the first points, even if you DO disable CFSILENT or the OUTPUT attribute of a CFFUNCTION of CFC, you have to remember to re-enable those when done debugging.
This calls for clarifying a key point: FusionDebug does not require that you edit the code. Again, we're a little ahead of ourselves if you've never seen a debugger and don't understand what setting breakpoints is about. Take my word: it's trivial.
You don't need to be able to enable CF's debugging output
Related to the above points, it's worth noting that by using FusionDebug, you don't need to enable CF's debugging output. Again, whether in production or simply on a server where you've not got control to get debugging turned on, this can be a valuable benefit.
You can change the value of variables on the fly during execution
Still another cool feature of step debuggers (in general) is that they permit you to change the values of variables within the code being debugged, such that on the fly, while the code is running, you can change the behavior of the app should you need to. This sort of thing can be easier than changing the code to effect that changed value (recall the previous point about how you may not even be able to edit the code to change a variable manually).
Sometimes a simple CFOUTPUT/CFDUMP will not suffice to solve a problem
Since we haven't shown how to use the tool, you'll also have to take this on faith: the features for viewing the current state of the application are also very powerful. While you're stopped at a breakpoint, you can view the value of ALL variables in ALL scopes. FD presents a very easy to use tree view to traverse and view the scopes. This also includes query resultsets (with still more unique features) and more.
And since you can view them all, you may be able to see information or make connections that you might not have thought to dump or output with traditional approaches.
You can use the debugger to understand the flow of execution of the request
Still another truly unique feature of a step debugger, that has nothing at all to do with outputting variables, is that they give you a clearly visual representation of the flow of a request. If you're ever wondering whether the code went into one IF statement or loop, or indeed if it included a file or called a custom tag or called a method in a CFC, these are all things that you can readily see in FusionDebug. Again, we haven't showed it in use yet, but we will in later entries see how it visually shows as you step from line to line or into nested tags, include files, custom tags, CFCs, and so on.
Further, the tool opens each such file as it is requested, so you may not even readily think of or see what files you would need to open if you did want to put manual debugging statements into them. That leads to one last point...
You can debug in situations where you don't even know where in a complex app to try to do CFOUTPUT or CFDUMP
That aforementioned feature of opening files as you step through them, and following the flow of execution, can be especially valuable in very complex applications. Let's consider (just as one example) a Model Glue application. When I run the modelgluesamples/legacysamples/contactmanager/index.cfm and view the files in the debugging output (showing all the files that were used to render the request, including CFM and CFC files and methods), there are nearly 150 shown. If something's amiss, you may be hard pressed to think where to begin.
For now, FusionDebug lacks something that the CF 4/5 debugger had that would make this last point especially valuable. That tool had a wildcard breakpoint, or what may be considered a conditional breakpoint: it would stop when a given condition was met. That's SO valuable. You can use it to find out when some condition arises (such as when some variable obtains or exceeds some value, or is set at all, or when some query exceeds a given executiontime--using cfquery.executiontime, and so on.) I have requested this latter feature of the FD team, and we can hope it may make it in the future. I have some other wishlist items which I will list in a future entry.
You can view the stack trace during execution
Following on to the previous point, while the traditional CF debugging output shows at the end of the page request what files were called to run the entire request, it doesn't really help you to know which were opened just to get a a particular point within a given template or CFC method. In FusionDebug, while you're sitting at a breakpoint, you will readily see the stack trace showing what files were opened to get to that point.
You can view the Java classes called to execute your code
Called the "java detail mode" in FusionDebug, it's an option which (if enabled) will show you all the java classes and methods called both to get to that point and which represent the kind of data in variables currently set. Indeed, if you double-click on a java class shown, it will show you any variables that were created from that object. For more info, including a screenshot with quick and easy explanations, see the FD site page for this feature.
That's a long list of reasons and benefits, and it's not even all of them. I just came up with these off the top of my head, wanting to help address the concerns of some who would dismiss the value of step debugging. There will surely be comments from folks on both sides of the fence (supporting it, dismissing it), and perhaps more info will be shared by others elsewhere. Let's get the conversation started.
So again, here is a summary of 13 things you can do with FusionDebug that I argue can't be done easily otherwise:
- can debug when a CFOUTPUT/CFDUMP may not be possible (CFCOMPONENT/CFFUNCTION OUTPUT=false, CFSILENT)
- can debug without having to rely on finding the output of CFLOG or CFTRACE (or enabling the latter)
- can debug requests from Flex, Ajax, or as web service
- can debug when someone besides the developer is calling a template
- can debug against production
- can debug on remote machine
- can debug without needing to change code
- can change the value of variables on the fly during execution
- can debug in situations where a simple CFOUTPUT/CFDUMP would not suffice
- can use the debugger to understand the flow of execution of the request
- can debug in situations where you don't even know where in a complex app to try to do CFOUTPUT or CFDUMP
- can view call stack during execution
- can view the Java classes called to execute your code