<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.0.2" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: Which is more effective: Debuggers vs. Print Statements</title>
	<link>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/</link>
	<description>A hindsight perspective on the everlasting trail of improvement.</description>
	<pubDate>Fri, 05 Dec 2008 08:49:14 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.2</generator>

	<item>
		<title>by: Kim Greenlee</title>
		<link>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-961</link>
		<pubDate>Mon, 12 Jun 2006 20:32:05 +0000</pubDate>
		<guid>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-961</guid>
					<description>I agree with the idea of debugger first, but many multithreaded problems are timing related.  This means that you may only see the problem after a very long execution time on a multiprocessor box or the problem only manifests in the release build.  Under these circumstances the debugger is not an option.  While I’ve used print statements (to the screen) for quick and dirty debugging in both multithreaded and distributed applications, I generally like to build a logging system into the application and then use the generated information as a starting point to identify the problem.  The information in the log file is only a clue to point the developer to the areas of interest in the application.  Once I’ve identified the areas of interest I go back into the debugger and step through that code with an eye to potential threading mistakes.  

I have also used debugging tricks such as inserting an “int 3” either in my code or into the actual assembler code of loaded 3rd party DLLs.  (This is platform specific).  Something I only do when all other methods don’t work.

And keep in mind that the applications running inside of a debugger inherit the debugger’s application space so that some types of bugs, such as bugs related to system resource consumption, can be masked by the debugger.  (Again this may be platform specific)  With these types of problems it’s necessary to fall back on log files and external system monitoring tools.</description>
		<content:encoded><![CDATA[<p>I agree with the idea of debugger first, but many multithreaded problems are timing related.  This means that you may only see the problem after a very long execution time on a multiprocessor box or the problem only manifests in the release build.  Under these circumstances the debugger is not an option.  While I’ve used print statements (to the screen) for quick and dirty debugging in both multithreaded and distributed applications, I generally like to build a logging system into the application and then use the generated information as a starting point to identify the problem.  The information in the log file is only a clue to point the developer to the areas of interest in the application.  Once I’ve identified the areas of interest I go back into the debugger and step through that code with an eye to potential threading mistakes.  </p>
<p>I have also used debugging tricks such as inserting an “int 3” either in my code or into the actual assembler code of loaded 3rd party DLLs.  (This is platform specific).  Something I only do when all other methods don’t work.</p>
<p>And keep in mind that the applications running inside of a debugger inherit the debugger’s application space so that some types of bugs, such as bugs related to system resource consumption, can be masked by the debugger.  (Again this may be platform specific)  With these types of problems it’s necessary to fall back on log files and external system monitoring tools.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Valentin</title>
		<link>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-960</link>
		<pubDate>Mon, 12 Jun 2006 20:13:54 +0000</pubDate>
		<guid>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-960</guid>
					<description>I do prefer print statements in a very generic way, but actually I never wrote print statements in production code as it looks bad and might not be very efficient. What I use is logging, which is pretty much like print but can be fancier. 

Logging is IMHO, a must for any program, unless performance suffers. I think most of the software can have logging with pretty much no performance penalty, especially if logging is done correctly. I personally prefer using log4(cxx, j, ..) libraries for logging since the performance is pretty good and recently they've became a standard for logging. 
I can structure logging for different levels so when my program runs in production little or no logging is produced but when I want to debug an issue I can just ask for more logging just by changing an env variable. For this I don't need to take the library out of production environment or to change the library. 

As for debuggers, I still use them, although I've never used an IDE base one, and I think during the development they are nice, and might save some time in identifying simple problems. There are situation when using debuggers is very hard and could take longer to find a bug (e.g. a Fibonacci like algorithm that crashes when it riches 8921 iteration). 

Another problem with debuggers and C/C++ is that debuggers are platform/compiler dependent where as logging is pretty much independent of the platform or compiler. 

In conclusion I think any software developer should know how to use any of the two methods to find bugs, but I would weight the print/logging method more than knowing how to use a debugger for a certain compiler/language/platform, as more benefit can be drawn from logging.</description>
		<content:encoded><![CDATA[<p>I do prefer print statements in a very generic way, but actually I never wrote print statements in production code as it looks bad and might not be very efficient. What I use is logging, which is pretty much like print but can be fancier. </p>
<p>Logging is IMHO, a must for any program, unless performance suffers. I think most of the software can have logging with pretty much no performance penalty, especially if logging is done correctly. I personally prefer using log4(cxx, j, ..) libraries for logging since the performance is pretty good and recently they&#8217;ve became a standard for logging.<br />
I can structure logging for different levels so when my program runs in production little or no logging is produced but when I want to debug an issue I can just ask for more logging just by changing an env variable. For this I don&#8217;t need to take the library out of production environment or to change the library. </p>
<p>As for debuggers, I still use them, although I&#8217;ve never used an IDE base one, and I think during the development they are nice, and might save some time in identifying simple problems. There are situation when using debuggers is very hard and could take longer to find a bug (e.g. a Fibonacci like algorithm that crashes when it riches 8921 iteration). </p>
<p>Another problem with debuggers and C/C++ is that debuggers are platform/compiler dependent where as logging is pretty much independent of the platform or compiler. </p>
<p>In conclusion I think any software developer should know how to use any of the two methods to find bugs, but I would weight the print/logging method more than knowing how to use a debugger for a certain compiler/language/platform, as more benefit can be drawn from logging.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Jonathan Allen</title>
		<link>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-955</link>
		<pubDate>Mon, 12 Jun 2006 18:30:54 +0000</pubDate>
		<guid>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-955</guid>
					<description>I think sprinkling print statements throughout your code is no better than guessing. 

Any decent IDE should have an interactive debugger that can run the application directly in debug mode. The good ones can also attach to an existing process, automatically pulling in the correct debug symbols and source code listings. Since I know how to use my debugger, it takes me less time to run it than it does to add print statements and recompile. 

I also have the advantage in that once I find the bad value, I can actually examine it. I can see exactly how it flows through the program. This lends me a level of true understanding that no one can get just looking at static code listings and printouts. 

With a really good IDE, I can even correct and rerun that portion of the code. This is crucial in larger applications where it can take 20+ minutes just to get back to the same place. 

As for multi-threaded applications, this is where a debugger can really help. Once I think I know the cause of the race condition, I can attempt to recreate by carefully controlling the threads. Since race conditions are intermittent by definition, this is often the only way to reliably prove a theory. 

Jonathan Allen

Some people program with rocks. Others use a hammer. I prefer a contractors’-grade pneumatic nail gun with a belt-fed magazine. Have fun &quot;becoming one with the metal&quot;, I’ve got real work to do.</description>
		<content:encoded><![CDATA[<p>I think sprinkling print statements throughout your code is no better than guessing. </p>
<p>Any decent IDE should have an interactive debugger that can run the application directly in debug mode. The good ones can also attach to an existing process, automatically pulling in the correct debug symbols and source code listings. Since I know how to use my debugger, it takes me less time to run it than it does to add print statements and recompile. </p>
<p>I also have the advantage in that once I find the bad value, I can actually examine it. I can see exactly how it flows through the program. This lends me a level of true understanding that no one can get just looking at static code listings and printouts. </p>
<p>With a really good IDE, I can even correct and rerun that portion of the code. This is crucial in larger applications where it can take 20+ minutes just to get back to the same place. </p>
<p>As for multi-threaded applications, this is where a debugger can really help. Once I think I know the cause of the race condition, I can attempt to recreate by carefully controlling the threads. Since race conditions are intermittent by definition, this is often the only way to reliably prove a theory. </p>
<p>Jonathan Allen</p>
<p>Some people program with rocks. Others use a hammer. I prefer a contractors’-grade pneumatic nail gun with a belt-fed magazine. Have fun &#8220;becoming one with the metal&#8221;, I’ve got real work to do.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Retrospector</title>
		<link>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-951</link>
		<pubDate>Mon, 12 Jun 2006 16:12:32 +0000</pubDate>
		<guid>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-951</guid>
					<description>Something to consider in a multi-threaded environment is being able to figure which thread is doing what when reading through the print statements. Web apps, for example, it's helpful to prefix the statements with session id or something so you can follow step at a time for each thread.

I'm right there with you on just dumping out plenty of prints while coding though, even if the only thing to distinguish them is a number. Something I do quite a bit in my code is this:

int iDebugLine = 0;
...
System.out.println(&quot;Debug: ClassName::MethodName() - &quot; + iDebugLine++);
...

This way I can copy/paste the thing as many times through a complex method as I want to without much trouble.</description>
		<content:encoded><![CDATA[<p>Something to consider in a multi-threaded environment is being able to figure which thread is doing what when reading through the print statements. Web apps, for example, it&#8217;s helpful to prefix the statements with session id or something so you can follow step at a time for each thread.</p>
<p>I&#8217;m right there with you on just dumping out plenty of prints while coding though, even if the only thing to distinguish them is a number. Something I do quite a bit in my code is this:</p>
<p>int iDebugLine = 0;<br />
&#8230;<br />
System.out.println(&#8221;Debug: ClassName::MethodName() - &#8221; + iDebugLine++);<br />
&#8230;</p>
<p>This way I can copy/paste the thing as many times through a complex method as I want to without much trouble.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Curt</title>
		<link>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-950</link>
		<pubDate>Mon, 12 Jun 2006 15:49:20 +0000</pubDate>
		<guid>http://www.retrospector.com/2006/06/12/debuggers-vs-print-statements/#comment-950</guid>
					<description>As you mentioned, it is definitely situational and you should use the right tool for the right job.
This is getting a little more language specific, but consider debugging multi-threaded applications.  If there are issues with blocking/synchronization you may not be able to reproduce the problem using a debugger as it will disrupt the timing between the threads.  In that situation I make sure that I pepper my code with print statements - always making sure I add 'too many'.  Nothing is worse than having to add more statements, recompile, re-deploy, re-run the tests.

Curt</description>
		<content:encoded><![CDATA[<p>As you mentioned, it is definitely situational and you should use the right tool for the right job.<br />
This is getting a little more language specific, but consider debugging multi-threaded applications.  If there are issues with blocking/synchronization you may not be able to reproduce the problem using a debugger as it will disrupt the timing between the threads.  In that situation I make sure that I pepper my code with print statements - always making sure I add &#8216;too many&#8217;.  Nothing is worse than having to add more statements, recompile, re-deploy, re-run the tests.</p>
<p>Curt
</p>
]]></content:encoded>
				</item>
</channel>
</rss>
