I use C# (using VS IDE) for development. I am confused about Debug/Trace statements.
Where and why do we use these statements?
I have often seen these in other developer's source code.
Can someone provide pointers?
What is Tracing? One technique that monitors software in real-time debugging is known as "tracing," which involves a specialized use of logging to record information about a program's execution. Programmers typically use this information to diagnose common problems with software and applications.
Tracing helps you isolate problems and fix them without disturbing a running system. This class provides methods to display an Assert dialog box, and to emit an assertion that will always Fail. This class provides write methods in the following variations: Write.
Debug. Write is only effective on builds where the DEBUG flag is defined, while Trace. Write is only effective when the TRACE flag is defined.
The Debug class helps us debug code, and the Trace class helps us trace the execution of code. The Debug class is intended for debug builds, and the Trace class is used for release builds. Table 21.3 describes the members of the Debug and Trace classes.
Debug statements are only present in Debug builds.
Trace statements are present in both Debug and Release builds.
You place both Debug and Trace statements where you want to output the value of something for the purpose of debugging or checking.
This MS support article might be of interest: How to trace and debug in Visual C#
The Trace class routes messages to listeners: classes that are designed to accept Trace messages and send them to an appropriate output device. The Trace.Listeners collection contains a list of the listeners that are registered with the system. Calling any of the Trace output methods will send a message to all of the registered listeners. A class called DebugTraceListener is automatically added to the Listeners collection, and routes messages to the
OutputDebugString
Win32 API function.
The SysInternals DebugView application will capture any output directed through OutputDebugString
.
Both Debug and Trace are used to output additional messages beyond normal error logging for your application. What is output is up to the programmer. Typical things that may be written are method entries/exits, method argument values, method return values, configuration information that is being used, critical performance timings etc.
The main difference between Debug and Trace is that Trace is present in release builds while Debug is not. I find Trace to be more useful as it allows you to get additional information about the functioning of your application in a production environment (assuming you added Trace to begin with). One thing to consider when adding Trace messages is to think about information that you would like to have access to if a tricky production issue popped up.
Both Debug and Trace are conditionally compiled. Debug (by default) is compiled into debug builds while Trace (by default) is compiled into release builds. The conditional compilation is determined by the compilation flags (for Trace: /d:TRACE) or preprocessor directives (for Trace: #define TRACE).
The good thing is that these statements can benefit you during development but can easily be removed for production builds by changing a compile flag.
Output
To get at the output of a Trace requires a trace listener. There is a default trace listener called (not surprisingly) DefaultTraceListener
. The DefaultTraceListener
sends the Trace messages to shared memory (via the Win32 OutputDebugString
method).
OK, but how do you see those trace messages?
The easiest way is to run a program to read the information for you. DebugView is the de facto standard to do that. Pretty much just start it up and the messages start appearing.
You can also direct the output to other locations using the TextWriterTraceListener
or EventLogTraceListener
.
You can also add trace listeners via configuration:
<configuration>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="myListener"type="System.Diagnostics.TextWriterTraceListener"initializeData="TextWriterOutput.log" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
If you are already using a logging provider (e.g. Enterprise Library, log4net) then you may want to look at using their approach since they almost always provide similar conditional logging functionality. However, they may not provide functionality similar to Assert
or WriteIf
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With