Debug Log mess up my code - c#

I am trying to add debug log to my C#.net code.
But it messes up my code, it looks like a hell.
Is there anything that log every code with its values automatically ?
Now it looks like this
#if DEBUG
debuglogger("The functionstarted");
#endif
someCode1();
#if DEBUG
debuglogger("SomeCode1 Finished");
#endif
someCode2();
#if DEBUG
debuglogger("SomeCode2 Finished");
#endif
someCode3();
#if DEBUG
debuglogger("SomeCode3 Finished");
#endif
#if DEBUG
debuglogger("Function End");
#endif

You should use the ConditionalAttribute. It allows you to define conditional methods that will be removed at build time if the condition doesn't match:
[Conditional("DEBUG")]
void DebugLog(string message)
{
// Do some logging...
}
calls to this method will be stripped out in builds without DEBUG defined. Just like
#if DEBUG
DebugLog("Testing...");
#endif
This has the added benefit of not cluttering up the stack traces as opposed to moving the #if inside the method.

Pretty late answer but I leave for future reference. In my opinion you should consider Aspect Oriented Programming for tasks like this. That said if you don't need to add such complexity for a small task you may move preprocessor conditions to your log method:
public static void Log(string message)
{
#if DEBUG
// Do logging
#endif
}
Do not worry to leave an empty method, JIT will optimize it away and it won't even be called. It's almost equivalent to:
[Condition("DEBUG")]
public static void Log(string message)
Warning: I say almost because with a method with [Condition] attribute arguments won't even be evaluated then given this code in release:
Log(String.Format("Index: {0}", index++));
index variable won't ever be incremented, because JIT compiler won't emit call to Log and even its arguments won't be evaluated. This is not true if you keep your method body empty with #if directive inside it. Call won't be emitted (because of empty body) but its arguments will be evaluated.
Problem of this solution is that it'll clutter your normal program flow. With log calls, parameters dumping and stuff like that. What can you do?
Refactor your log
If you call SomeCode1() method many times you shouldn't log at each call site, much better is to move logging inside called method. Log only at beginning and end of each function, log will still be in your code but it'll be spanned across multiple functions.
void SomeCode1() {
Log("Starting SomeCode1");
// Do something
Log("SomeCode1 completed");
}
Your calling site will then be clean:
SomeCode1();
SomeCode2();
SomeCode3();
Expressions
If performance aren't an issue (measure, don't guess) you may use Expressions to do the trick for you. You can log parameters too (or fields, object status, diagnostic informations, invariants and whatever else you may need), everything controlled by diagnostic switches (to enable them only when required). No logging code in your LOB classes but price to pay is execution speed (and LoggedOperation function complexity).
This code is (to be polite with myself) very naive, a decent implementation will be much more complex so just think about it as an idea more than an implementation.
static void LoggedOperation(Expression<Action> expression)
{
MethodCallExpression methodCall = expression.Body as MethodCallExpression;
if (methodCall != null)
Log("Calling {0}", methodCall.Method.Name);
expression.Compile()();
if (methodCall != null)
Log("{0} completed", methodCall.Method.Name);
}
It'll be then used like this:
LoggedOperation(() => SomeCode1());
LoggedOperation(() => SomeCode2());
LoggedOperation(() => SomeCode3());
You'll get:
Calling SomeCode1
SomeCode1 completed
Calling SomeCode2
SomeCode2 completed
Calling SomeCode3
SomeCode3 completed
AOP will give you a much cleaner code but this may be enough in many situations.

You can either move the preprocessor directives to the debuglogger function, or use a configurable logging framework that lets you configure when to log rather than relying on preprocessor statements at build time. That way you can "turn on" logging without having to rebuild the application.

You can use AOP for this, although I've not tried it myself.
Alternatively there are a number of things you can do to help improve the readability of your code such as using the Conditional attribute
Marking the debuglogger method with the Conditional attribute removes the need for the #if DEBUG code
[Conditional("DEBUG")]
public void debuglogger(string message)
{
// Logging code goes here
}
debuglogger("The functionstarted");
someCode1();
debuglogger("SomeCode1 Finished");
someCode2();
debuglogger("SomeCode2 Finished");
someCode3();
debuglogger("SomeCode3 Finished");
debuglogger("Function End");
Personally I would also have the someCodeN methods log the "SomeCodeN Finished" messages, which further simplifies your code
debuglogger("The functionstarted");
someCode1();
someCode2();
someCode3();
debuglogger("Function End");
public void someCode1()
{
// Do something
debuglogger("someCode1 Finished");
}

Mark Gravell recently posted an interesting idea utilizing partial classes. Link to his plog post
Project structure:
-Foo.cs
-Foo.debug.cs
And here the classes:
// Foo.debug.cs
#if DEBUG
partial class Foo
{
partial void Trace(string value)
{
Console.WriteLine("The value is: {0}", value);
}
}
#endif
// Foo.cs
partial class Foo
{
partial void Trace(string value);
public void MethodWithTracing()
{
Trace("This is traced");
}
}
Debug / Trace logic is separated from the normal code and when changing build options, it won't be compiled.

Related

Silence specific Exception

I have a lot of throw new NotImplementedExceptions() throughout my whole application. For now I want to silence them and to show a custom Message Dialog instead.
For catching them I'm using:
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
if(eventArgs.Exception is NotImplementedException) {
return;
}
}
But the problem is that the exception is still threw.
How can I silence the throw when I catch this type of Exception within this piece of code?
It sounds like what you want to do is to do something nicer than exploding when a method you haven't implemented is invoked. I don't believe that is possible using AppDomain.FirstChanceException or the related UnhandledException. There's a good answer here that talks a bit about why simply suppressing exceptions is undesirable.
What you could do instead is use something besides raising an exception to mark methods as not implemented, like calling a helper that displays your message, when you haven't implemented something yet. You could use #if pragmas or the ConditionalAttribute to switch to actually throwing exceptions in non-DEBUG builds, if that's desirable. It's not that uncommon to use helpers for throwing exceptions anyway (see for example ThrowHelper in the BCL, or Throw in one of my own projects), as there are some benefits to avoiding throws.
This would look like:
public void UnImplementedMethod()
{
// rather than "throw new NotImplementedException("some message")"
MyHelper.NotImplemented("some message");
}
// ....
static class MyHelper
{
[Conditional("DEBUG")]
public static void NotImplemented(string msg)
{
#if DEBUG // can use whatever configuration parameter
MessageBox.Show("Not Implemented: "+ msg);
#else
throw new NotImplementedException(msg);
#endif
}
}
You can use generic parameters to handle unimplemented methods that have non-void returns, though you have to decide what to actually return if you don't throw an exception. With this pattern you can do whatever you'd like, and still easily find places that haven't been implemented.

StackTrace.GetFrame throws NullReferenceException in Release build but works in Debug build

I wrote a class which is intended to provide robust logging messages. One of the features I want to include is to include the class and method from which a call to generate a log message originated.
The problem I'm having is that StackTrace.GetFrame behaves inconsistently between debug and release builds. As far as I can tell, it behaves as expected when I execute programs from VS in debug. When I execute a release build deliverable, StackTrace.GetFrame throws a NullReferenceException.
Here's a simplified example of my code:
using Logging;
namespace MyApp
{
class Program
{
public static void Main(string[] args)
{
Logger Log = new Log(Level.INFO);
Log.Info(#"Hello, world!");
}
}
}
namespace Logging
{
class Logger
{
//Assume a constructor
public void Info(string message)
{
//We will need to go 3 method calls back from StandardEntry()
//to get the name of the method which called Log.Info
StandardEntry(text, Level.INFO, 3);
}
//This method is called by Logger.Info, Logger.Error, etc
private void StandardEntry(string message, Level entryLevel, int frameCount)
{
if (entryLevel >= this.level)
{
string message = $"[{CallingMethod(frameCount)}] {<entryLevel.ToString()>} {message}\r\n";
File.AppendText(this.LogPath, message);
}
}
private string CallingMethod()
{
string retVal;
StackTrace st = new StackTrace();
StackFrame sf = st.GetFrame(frameCount);
MethodBase callingMethod = sf.GetMethod();
return $"{callingMethod.ReflectedType.Name}.{callingMethod.Name}";
}
}
}
I've tried playing around with the value I'm passing in for frameCount, but a lower number returns a method call that is still within the Logger class. I need the method that actually called Log.Info
When running a release deliverable, Log.Info() in Program.Main throws a NullReferenceException, which leads me to believe that it's trying to access a stack frame index that is beyond the scope of the invoked executable.
When I debug in Visual Studio, there is no exception and CallingMethod() returns the expected expression.
In release builds, one of the optimizations the JIT compiler performs is inlining methods, i.e. inserting the code of a called method directly into the method calling it. This means that some methods may simply disappear from the stack trace you're seeing.
What you can do instead is add parameters to the Info method together with the caller information attributes which are made for scenarios like this. The C# compiler will automatically fill in the information for those parameters at compile time, so they're not affected by runtime optimizations.
It seems that class CallerMemberNameAttribute is what you actually needs.

Do pre-processor directives protect server code from the client?

I'm developing a client-server library. Some of the classes can be used by either the client or the server but are executed differently and yield slightly different results for each. As well, the server code may contain additional methods that will not be called from the client build.
A class may look like this:
public class StuffDoer {
public void DoStuff(object msg)
{
ServerDoStuff(msg);
ClientDoStuff(msg);
}
[Conditional("SERVER")]
private void ServerDoStuff(object msg)
{
// Do secret server stuff...
}
[Conditional("CLIENT")]
private void ClientDoStuff(object msg)
{
// Do client sutff...
}
[Conditional("SERVER")]
public void DoCoolStuff(object msg)
{
// server does cool stuff...
}
}
I've read that the Conditional attribute still compiles the code and would therefore be in the build, unlike pre-processor directives which would completely remove the code and not even compile it.
I'm concerned that a dishonest client may hack the product by unobfuscating the source code and figure out how the server works.
Are my fears unfounded or would I need to place pre-processor directives in order to hide the source code?
According to the documentation:
Applying ConditionalAttribute to a method indicates to compilers that
a call to the method should not be compiled into Microsoft
intermediate language (MSIL) unless the conditional compilation symbol
that is associated with ConditionalAttribute is defined.
When you compile with CLIENT defined, the code to call a method marked with SERVER will not be present in the final assembly. But the code for the method will be present. You cannot achieve what you need in this way.
When "SERVER" is not defined, The method be marked as "SERVER" will always compile to the final assembly but all of callings to the method will be removed.
This is code
This is decompiled result

Compilter Directives - Suggestion - Run code in Debug mode only

I need to Log messages only when application is running in debug mode. I have found 2 ways:
First: Need to write 3 lines everywhere when logging is needed. But, Logger statement is disabled at compile time only which is exactly I need. Logger.Log will not be executed at all.
#if DEV_ENV
Logger.Log("Application started !"); // This line is grayed. Perfect !
#endif
public static void Log(string message)
{
Debug.WriteLine(message);
}
Second: Very neat. Only one line of code wherever logging is required. Not sure, whether Logger.Log statement is executed or not. If function call is removed at compile time only (same as first approach. But, now sure as line of code is not greyed out), I want to go with this.
Logger.Log("Application started !"); // This line is not grayed out. But, function is not called. So, confused whether its removed at compile time.
[Conditional("DEV_ENV")]
public static void Log(string message)
{
Debug.WriteLine(message);
}
I am concerned about the performance differences.
From the MSDN page for the ConditionalAttribute:
Applying ConditionalAttribute to a
method indicates to compilers that a
call to the method should not be
compiled into Microsoft intermediate
language (MSIL) unless the conditional
compilation symbol that is associated
with ConditionalAttribute is defined.
So, as it says, the method call is removed at compile time, same as the #if.
Depending on your compile settings, you could use:
if (System.Diagnostics.Debugger.IsAttached)
Logger.Log("Application started !");
or,
#if DEBUG
Logger.Log("Application started !");
#endif
As George points out, the method call will not be compiled if the Conditional attribute is applied. This also means (as with removing the code directly using #If DEV_ENV) that any side effects included in the method call will also not occur - as always, the warning about having side effects in logging code are well founded:
public static void Main(String[] args)
{
int i = 92;
Log(string.Format("{0} became {1}", i++, i));
Console.WriteLine(i);
Console.ReadLine();
}
[Conditional("SKIP")]
private static void Log(string msg)
{
Console.WriteLine(msg);
}
If SKIP is not defined, this code prints out 92. If SKIP is defined, it prints 92 became 93 and 93.

Can I enable/disable breaking on Exceptions programmatically?

I want to be able to break on Exceptions when debugging... like in Visual Studio 2008's Menu Debug/Exception Dialog, except my program has many valid exceptions before I get to the bit I wish to debug.
So instead of manually enabling and disabling it using the dialog every time is it possible to do it automatically with a #pragma or some other method so it only happens in a specific piece of code?
The only way to do something close to this is by putting the DebuggerNonUserCodeAttribute on your method.
This will ensure any exceptions in the marked method will not cause a break on exception.
Good explanation of it here...
This is an attribute that you put against a method to tell the debugger "Nothing to do with me guv'. Ain't my code!". The gullible debugger will believe you, and won't break in that method: using the attribute makes the debugger skip the method altogether, even when you're stepping through code; exceptions that occur, and are then caught within the method won't break into the debugger. It will treat it as if it were a call to a Framework assembly, and should an exception go unhandled, it will be reported one level up the call stack, in the code that called the method.
Code example:
public class Foo
{
[DebuggerNonUserCode]
public void MethodThatThrowsException()
{
...
{
}
What about conditional breakpoints? If I understand correctly, you can have a breakpoint fire only when the value of a certain variable or expression is true.
Wrap your try catch blocks in #if DEBUG
public void Foo()
{
#if DEBUG
try
#endif
{
//Code goes here
}
#if DEBUG
catch (Exception e)
{
//Execption code here
}
#endif
}
I like to keep the curly braces outside of the #if that way it keeps the code in the same scope if inside or outside of debug.
If you still want the execption handeling but want more detail you can do this
try
{
//code
}
catch (FileNotFoundException e)
{
//Normal Code here
#if DEBUG
//More Detail here
#endif
}
#if DEBUG
catch (Exception e)
{
//handel other exceptions here
}
#endif
This is a bit of too late for you, but this is the biggest reason I often try to teach people to use exceptions conservatively. Only use exceptions when something catastrophic has happened and your ability to reasonably continue is gone.
When debugging a program I often flip on First Chance Exceptions (Debug -> Exceptions) to debug an application. If there are a lot of exceptions happening it's very difficult to find where something has gone "wrong".
Also, it leads to some anti-patterns like the infamous "catch throw" and obfuscates the real problems. For more information on that see a blog post I made on the subject.
In terms of your problem, you can turn on first chance debugging for only a specific type of exception. This should work well unless the other exceptions are of the same type.
You could also use asserts instead of breakpoints. For instance, if you only want to breakpoint on the 5th iteration of a loop on the second time you call that function, you could do:
bool breakLoop = false;
...
Work(); // Will not break on 5th iteration.
breakLoop = true;
Work(); // Will break on 5th iteration.
...
public void Work() {
for(int i=0 ; i < 10 ; i++) {
Debug.Assert (!(breakLoop && i == 5));
...
}
}
So in the first call to Work, while breakLoop is false, the loop will run through without asserting, the second time through the loop will break.

Categories