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.
Related
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
In LINQPad, Debug.Assert() and Trace.Assert() from the System.Diagnostics namespace don't work as expected.
Instead of breaking - i.e. popping up a message box or whatever else happens to be configured for <trace> - they simply print "Fail:" or "Fehler:" to the output window and let the program continue on its merry way. In other words, instead of a noisy, unignorable explosion there are only near invisible micro-farts that intersperse "Fail:" into the textual output.
Is there any way of getting Assert() to revert to the default behaviour under LINQPad?
Alternatively, is there a simple way of mocking a Trace.Assert() so that failure results in a noisy explosion (i.e. exception, message box, whatever) and the source of the failure is pinpointed in the form of a line number or similar?
My unit tests are based on Trace.Assert(), which makes them totally useless if the function cannot break the program at the point of failure.
In Visual Studio everything works normally but not in LINQPad. I haven't fiddled with any system-wide settings but I did install Mono at some point in time. I went through all settings in LINQPad with a fine comb but to no avail. The LINQPad version is 4.57.02 (non-free), running on Windows 7 Pro (German) and Windows 8.1 Pro (English).
I googled high and wide but the only thing I could find is the topic Trace.Assert not breaking, neither showing the message box here on Stack Overflow. Its title certainly looks promising but the answers therein don't.
P.S.: I tried mocking by adding
class Trace
{
public static void Assert (bool condition)
{
if (!condition)
throw new Exception("FAIL!");
}
}
to the LINQ script and setting a breakpoint on the throw statement. Clicking on the relevant call stack entry in LINQPad's debugger takes me to the relevant source line, so this sort of works. However, I couldn't find an equivalent to FoxPro's SET DEBUG ON for invoking the debugger directly from the source code instead of having to set a breakpoint on the throw...
To answer the second half of your question, i.e., how do you get the LINQPad debugger to break when an exception is thrown, the answer is to click either of the 'Bug' icons on the toolbar.
Click Break when exception is unhandled (red bug) to make your query break whenever an unhandled exception is thrown.
Click Break when exception is thrown (blue bug) to make your query break whenever an exception is thrown, whether or not it is handled.
You can get LINQPad to make either setting the default by right-clicking and choosing Set as default. (Doing so forces the debugger to always attach to your queries, which incurs a small performance cost.)
As to why Debug.Assert(false) doesn't display a dialog, this is because this behavior hasn't been implemented in LINQPad. You could implement this easily as an extension, by adding the following code to My Extensions:
public class NoisyTracer : TextWriterTraceListener
{
public static void Install()
{
Trace.Listeners.Clear();
Trace.Listeners.Add (new NoisyTracer (Console.Out));
}
public NoisyTracer (TextWriter writer) : base (writer) { }
public override void Fail (string message, string detailMessage)
{
base.Fail (message, detailMessage);
throw new Exception ("Trace failure: " + message);
}
}
Then, to enable, write your query as follows:
NoisyTracer.Install();
Debug.Assert (false);
I have a strange problem with Asserts being ignored. You can reproduce it with this minimal example. I am wondering why this problem occurs and how to face it:
public class TestAssert
{
public string EmptyString
{
get
{
System.Diagnostics.Debug.Assert(false);
return string.Empty;
}
}
Dictionary<string, object> dict = new Dictionary<string, object>();
public void ShowAssertIgnored()
{
var foo = dict[EmptyString];
}
}
You can see that the Debug.Assert(false) is ignored even though the property is evaluated. Just call
var test = new TestAssert();
test.ShowAssertIgnored();
and you should see what I mean (also shown on the image).
The code is compiled and run in Debug (other asserts work fine!), 32 bit, x86 + AnyCPU, VS2012 professional, .Net Framework 4
Edit:
The project is a console application and I was running it for several times in a row. Having a breakpoint before System.Diagnostics.Debug.Assert(false); most often a messagebox appears. But not always: When I just retry the same situation several times I sometimes see the result in the console.
To say it again: I can reproduce non-deterministic behaviour in the VS2012 debugger!
If you read the docs, you'll see that Debug.Assert isn't designed to throw.
Typically, the Assert(Boolean) method is used to identify logic errors during program development. Assert evaluates the condition. If the result is false, it sends a failure message to the Listeners collection. You can customize this behavior by adding a TraceListener to, or removing one from, the Listeners collection.
When the application runs in user interface mode, it displays a message box that shows the call stack with file and line numbers. The message box contains three buttons: Abort, Retry, and Ignore. Clicking the Abort button terminates the application. Clicking Retry sends you to the code in the debugger if your application is running in a debugger, or offers to open a debugger if it is not. Clicking Ignore continues with the next instruction in the code.
If running in an UI environment, it may trigger throw-like behaviour that is defined in the listeners that the UI environment/test-runner sets up.
So, in short, Debug.Assert(false) won't halt your application but its listeners might.
Assuming that there is no UI here... If you want your code to fail, then you'll need to write your own TraceListener:
public class MyTraceListener : TraceListener
{
public override void Write(string msg)
{
throw new Exception(msg);
}
public override void WriteLine(string msg)
{
throw new Exception(msg);
}
}
and add it to the listeners collection:
Debug.Listeners.Add(new MyTraceListener());
Have you checked your project settings to define the DEBUG constant? The Debug.Assert() methods have the [ConditionalAttribute("DEBUG")] attribute, which means, they will by ignored during compilation, if the "DEBUG" constant is not defined.
That's an expected behaviour, Debug.Assert() works in debug build only:
By default, the Debug.Assert method works only in debug builds. Use
the Trace.Assert method if you want to do assertions in release
builds. For more information, see Assertions in Managed Code.
https://msdn.microsoft.com/en-us/library/kssw4w7z(v=vs.110).aspx
use Trace.Assert() if you want it working in release as well.
Ok. The problem I'm having is a little difficult to explain, but essentially my issue is the method that is responsible for filling a dataset is being skipped. The debugger hits the line of code in question, but skips right over it. No chance of stepping into or what not.
// Class A
private myTableDS _dsTable; // myTableDS.xsd
private classB _clsB;
protected override void OnLoad(EventArgs e)
{
if (_dsTable == null)
{
_dsTable = _clsB.LoadThisTable(); // The culprit
}
// More logic here. Mindblowing. It is.
}
// Class B
public myTableDS LoadThisTable()
{
// Magic here
}
So the debugger hits the line _dsTable = _clsB.LoadThisTable(); and jumps out. Taking me back to the next line in the code that invoked "onload" in the first place. So any and all logic beneath _dsTables = _ASIO.LoadASTables(); is skipped.
Thoughts?
Typically, when the debugger is skipping code, it has something to do with threading (which doesn't appear to be the case here), a type load exception (missing assembly), or a different version of the code being deployed than what is being debugged.
If the latter cases are the problem, the solution is making sure the very latest assemblies are actually deployed to the environment you're debugging.
Also, try putting a Debbugger.Launch() statement in myTableDS.LoadThisTable() and setting Visual Studio up so that the debugger breaks when exceptions are thrown (not just unhandled).
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.