Conditionally call a private method based on caller's debug configuration - c#

My current code situation is that I have in assembly A the following code:
public class Foo
{
public Foo()
{
CreateDebugMessage();
}
[Conditional("DEBUG")]
[DebuggerStepThrough]
private void CreateDebugMessage()
{
AddMessageType(MessageType.Debug, "Debug",
"/Company.App.Class;component/Images/image.png", Brushes.Green, false);
}
}
Some extra information is that I am using MEF and this method is called from the constructor. I have an assembly B (where I am importing assembly A) which depending on whether I am on DEBUG or RELEASE mode I want the Debug message to be created when I instantiate the class:
var foo = new Foo();
If I am on Debug mode I want the debug message to be created.
If I am on Release mode I DO NOT want the debug message to be created.
I thought the Conditional attribute would be better than the #iF DEBUG statement. This question showed me how WRONG I was! Since on runtime the method is never reached.
At this point I understand that the "#iF Debug" and "[Conditional("DEBUG")]" statements won't cut it for what I want to achieve.
Therefore my question is, how to make this scenario work?

The attribute works as it should, see Conditional Compilation in Referenced Assemblies. The attribute depends on the compilation symbols of the calling assembly. I tested and confirmed this: a method in an assembly with [Conditional("DEBUG")], compiled on Release, will only get called if the calling assembly is compiled in Debug. If this isn't the case for you, your code does not match your description.
The relevant part in your question is of course "This method is called from the constructor.". The attribute works for the direct caller, which in your case is the constructor of the containing class, which is Release.
You'll have to make it public and explicitly call the method:
public class Foo
{
public Foo()
{
}
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void CreateDebugMessage()
{
AddMessageType(MessageType.Debug, "Debug",
"/Company.App.Class;component/Images/image.png", Brushes.Green, false);
}
}
var foo = new Foo();
foo.CreateDebugMessage();

Related

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

Weird Access Violation Exception

I'm puzzled with an occurance of AccessViolationException. It's quite impossible (see answer) to have a clean reproduction but here goes the general idea:
class MyClass
{
public List<SomeType> MyMethod(List<string> arg)
{
// BREAKPOINT here
// Simple stuff here, nothing fancy, no external libs used
}
}
delegate List<SomeType> MyDelegate(List<string> arg);
...
var myObject = new MyClass();
Func<List<string>, List<SomeType>> myFunc = myObject.MyMethod;
MyDelegate myDelegate = myObject.MyMethod;
myFunc(null) // works fine
myDelegate(null) // works fine
myObject.MyMethod(null) // throws AccessViolationException
The weird part is I'm not using any unsafe code. I don't have any dependencies on external libraries anywhere close (and anywhere in the whole program execution AFAIK).
The weirdest part is this is 100% reproducable and even after refactoring the code slightly, moving the method invocation elsewhere, putting extra code before it etc. - in all cases AccessViolationException is still thrown on that particular method invocation. The method is never entered when invoked directly (breakpoint is not hit). Invoking it through delegate or Func<> works fine.
Any clues as to what could cause it or how to debug it?
UPDATE
Following antiduh's question: There is no call to a virtual method from a constructor anywhere close. The actual stack trace when this happens is very simple, just two static methods and a simple instance one.
The only clue seems to be threading. There is Parallel.ForEach() and Thread.Sleep() invoked before this in program execution (not in call stack). Any clues as to how mishandled threading (with regular, managed classes) could cause AVE?
UPDATE
Narrowed it down to a VS bug, see my answer.
This seems to be a VS bug. Have a look at this full solution. Code is simple:
using System;
using System.Collections.Generic;
namespace Foo
{
public class MyClass
{
public virtual object Foo(object o1, object o2, object o3, object o4)
{
return new object();
}
}
public sealed class Program
{
public static void Main(string[] args)
{
var myClass = new MyClass();
object x = new object();
myClass.Foo(null, null, null, new object()); // put a breakpoint here and once it stops, step over (F10) - AccessViolationException should be thrown in VS
}
}
}
The important fact I have missed before is that the code actually works fine when ran normally. Only when that particular line is being stepped over in VS (F10), the Access Violation occurs and it actually occurs in VS hosting process (even though the final stack frame is my code). It's possible to continue execution fine.
The issue happens for me on VS 2013, version 12.0.21005.1 REL. It also happens on 3 other machines I tested this on.
UPDATE
Installing .NET Framework 4.5.2 solves this.

Debug Log mess up my code

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.

Storing assembly Version readonly

this is a follow on from this question I asked a while ago:
Assembly.GetExecutingAssembly() performance
this solution seemed perfect. Now I've just gottent around to implementing it and it doesn't work. I get a System.TypeInitializationException thrown, the inner exception is the good old, Object reference not set to an instance of an object. Now I'm not sure why it's not working. My guess is that the static readonly property is instanticating before the Assembly class or something?
Can anybody shed any light on why this is happening, any fixes, other than not use a readonly as this is obvious, would also be welcome though not necessarily expected!
Here's the code:
public class VersionHelper
{
private static readonly Version _applicationVersion = Assembly.GetEntryAssembly().GetName().Version;
public static string GetVersionText()
{
return string.Format("Version: {0}-{1}", _applicationVersion, Environment.MachineName.Substring(5));
}
}
Called:
protected void Page_Load(object sender, EventArgs e)
{
lblVersion.Text = VersionHelper.GetVersionText();
}
Just to explain if I do it this way it works:
public class VersionHelper
{
public static string GetVersionText()
{
Assembly web = Assembly.GetExecutingAssembly();
AssemblyName webName = web.GetName();
return string.Format("Version: {0}-{1}", webName.Version, Environment.MachineName.Substring(5));
}
}
The exception doesn't have anything to do with the fact that the property is readonly or not. The problem is that you are calling Assembly.GetEntryAssembly() in a ASP.NET context, and apparently that doesn't work well together.
The other option that you have also does not use this method, it uses Assembly.GetExecutingAssembly. If you change your first sample so it uses Assembly.GetExecutingAssembly, than you will see that it runs fine.
I do not have any real references, but you can check this question, and in particular the comments beneath the question.
It also has a solution on how to get an entry assembly in a ASP.NET context.
Assembly.GetEntryAssembly is not reliable, specifically it will return NULLif the application started in an unmanaged context instead of a managed context. The result must be null checked..
For example, if an unmanaged application creates an instance of a COM component written in C#, a call to the GetEntryAssembly method from the C# component returns NULL, because the entry point for the process was unmanaged code rather than a managed assembly.
whereas GetExecutingAssembly just gets the assembly that contains the code that is currently executing.
while To get the assembly that contains the method that called the currently executing code, you should use GetCallingAssembly.

Categories