https://github.com/apache/log4net
I am compiling log4net from the source above, but it doesn't pass verification:
[IL]: Error: [log4net.dll : log4net.Plugin.RemoteLoggingServerPlugin::Attach][offset 0x00000029] Method is not visible.
Code is ok:
public interface ILoggerRepository
{
...
}
public interface IPlugin
{
void Attach(ILoggerRepository repository);
}
public abstract class PluginSkeleton : IPlugin
{
public virtual void Attach(ILoggerRepository repository) { }
}
public class RemoteLoggingServerPlugin : PluginSkeleton
{
override public void Attach(ILoggerRepository repository)
{
base.Attach(repository);
...
}
}
https://github.com/apache/log4net/blob/trunk/src/Plugin/IPlugin.cs
https://github.com/apache/log4net/blob/trunk/src/Plugin/PluginSkeleton.cs
https://github.com/apache/log4net/blob/trunk/src/Plugin/RemoteLoggingServerPlugin.cs
Investigation shows that it fails in calling RemotingServices.Marshal():
override public void Attach(ILoggerRepository repository)
{
base.Attach(repository);
// Create the sink and marshal it
m_sink = new RemoteLoggingSinkImpl(repository);
try
{
**RemotingServices.Marshal(m_sink, m_sinkUri, typeof(IRemoteLoggingSink));**
}
catch(Exception ex)
{
LogLog.Error(declaringType, "Failed to Marshal remoting sink", ex);
}
}
But there is nothing crucial here. Moreover calling RemotingServices.Marshal() with any type leads to the same problems:
Even if I change the Attach() to this:
override public void Attach(ILoggerRepository repository)
{
RemotingServices.Marshal(null, null, typeof(int));
}
Can someone spot what is the problem?
The problem is related to the fact that with .NET 4 Level 2 transparency was introduced. (See http://msdn.microsoft.com/en-us/library/dd233102.aspx for details.)
The method override public void Attach(ILoggerRepository repository) is lacking the SecuritySafeCriticalAttribute. Adding the attribute:
#if NET_4_0
[System.Security.SecuritySafeCritical]
#endif
override public void Attach(ILoggerRepository repository)
{
// ...
}
will make the IL verification pass. (Also see: http://msdn.microsoft.com/en-us/library/bb397858.aspx for further information.)
Update: To shed some more light on why verification fails (which might not be immediately clear by just reading the articles in the links provided) here is a short explanation.
RemotingServices.Marshal has the [SecuritySafeCritical] attribute applied. So one would assume that calling the method from a transparent method would be allowed. However RemotingServices.Marshal returns an object of type System.Runtime.Remoting.ObjRef and said type is annotated with the [SecurityCritical] attribute. If the log4net code would store a reference to the returned value in a local variable, Code Analysis would detect the error and issue a CA2140 warning ("Transparent code must not reference security critical items").
Now apparently under the security transparency rules, a transparent method may not call a security safe-critical method if the called method returns a security critical type even if the transparent method does not store a reference to the returned object as the following sample demonstrates:
public class TransparencyRulesDemo
{
[SecuritySafeCritical]
public void SafeGetCritical()
{
GetCritical();
}
public void TransparentGetCritical()
{
// Below line will trigger a CA2140 warning if uncommented...
// var critical = GetCritical();
// ...the following line on the other hand will not produce any warning
// but will lead to IL verification errors and MethodAccessExceptions if
// called from transparent code.
GetCritical();
}
[SecuritySafeCritical]
public Critical GetCritical()
{
return new Critical();
}
}
[SecurityCritical]
public class Critical
{
}
This btw. makes the [SecuritySafeCritical] attribute on RemotingServices.Marshal kind of pointless.
Related
As part of a big framework (so i cant post a MCVE unfortunately) i am trying to inherit a couple of times to hide necessary initialization from the user of the class so the structure is
// internal base class
public class InternalBase
{
// declared internal to avoid subclassing by user - visibility
// is handled in AssemblyInfo.cs so library can subclass
internal InternalBase()
{
}
public virtual void startup()
{
// perform necessary initialization
}
}
// public base class the users should inherit from
public class PublicBase : InternalBase
{
public override void startup()
{
// call base class to perform required init
base.startup();
// perform extra steps like check if init was performed correctly
}
}
// user class trying to use the provided functionaly
public class Test : PublicBase
{
public override void startup()
{
// this is put here by convention/template to ensure execution of
// required init - if this could be avoided, even better
base.startup();
// users are allowed to put their own init here
// perform user init code
}
}
Now as soon as i want to step into base.startup() in the Test class, the system behaves strange. Breakpoints in the other methods are not hit. An exception is thrown from somewhere completely different, log output suggests that the program continued a bit. When the exception (type is from the framework) is thrown, there is no callstack.
Should this work in principle, how could i provide such functionality or debug what i have?
I am writing a core API that will be used by client developer.
There are some methods that are still not developed but I need them to be in the API so the developer can see them in the intellisense.
In addition to the API documentation I am providing to the developer, I need him to know during the development that a method is not yet implemented but it exist.
Is there a way to inform the developer that the method is not yet implemented without throwing NotImplementedException and if he will try to use the method it will not compile?
For example:
public class API
{
public void PrintToPDF()
{
// do not throw NotImplementedException
}
}
public class Client
{
public void Print()
{
API api = new API();
api.PrintToPDF(); // shouldn't compiled but can be see in intellisense. It can show a tooltip that it is in being developed.
}
}
Use the obsolete attribute, it can generate both a warning or an error as you define it.
using System;
using System.Reflection;
public class Example
{
// Mark OldProperty As Obsolete.
[ObsoleteAttribute("This property is for future use", false)]
public static string OldProperty
{ get { return "The old property value."; } }
public static string NewProperty
{ get { return "The new property value."; } }
// Mark CallOldMethod As Obsolete.
[ObsoleteAttribute("This method is for future use", true)]
public static string CallOldMethod()
{
return "You have called CallOldMethod.";
}
public static string CallNewMethod()
{
return "You have called CallNewMethod.";
}
public static void Main()
{
Console.WriteLine(OldProperty);
Console.WriteLine();
Console.WriteLine(CallOldMethod());
}
}
// The attempt to compile this example produces output like the following output:
// Example.cs(31,25): error CS0619: 'Example.CallOldMethod()' is obsolete:
// 'This method is for future use'
// Example.cs(29,25): warning CS0618: 'Example.OldProperty' is obsolete:
// 'This property is for future use'
You can also create your own attribute.
[Obsolete("Reserved for future use", true)]
public class ReservedForFutureUse : System.Attribute
{
}
You can use the obsolete attribute:
public class API
{
[Obsolete("This isn't yet implemented")]
public void PrintToPDF()
{
// do not throw NotImplementedException
}
}
It won't generate an error at compile time, but it will generate a warning:
1>Example.cs(31,17,31,33): warning CS0618: 'API.PrintToPDF()' is obsolete: 'This isn't yet implemented'
I am disassembling some C# applications and I am trying to reconstruct the source code. I am disassembling the application along with the required DLLs.I keep coming across this line base..ctor(); which gives me an error. The line occurs in some voids with in some subclasses of Stream and Exception.
Does anyone have any idea what the code should be? I am thinking the disassembler messed it up some how and it is clearly invalid code.
So does anyone know what it is meant to mean and how I can change the line so it works?
Here is the code of one of the subclasses that line occurs in:
[Guid("ebc25cf6-9120-4283-b972-0e5520d0000E")]
public class ZlibException : Exception
{
public ZlibException()
{
base..ctor();
return;
}
public ZlibException(string s)
{
base..ctor();
return;
}
}
It should be :
[Guid("ebc25cf6-9120-4283-b972-0e5520d0000E")]
public class ZlibException : Exception
{
public ZlibException() : base()
{
return;
}
public ZlibException(string s) : base()
{
return;
}
}
Which calls the constructor with that signature on the base implementation of this class.
But by default the .NET CLR calls the base, blank constructor for you, so you don't actually need the : base()
It's calling the base constructor, your decompiler is just showing it strangely. In IL, constructors are called .ctor for short, so when directly reading the IL, your decompiler is apparently confused and thinks this is just another method.
The actual code would look like:
public class ZlibException : Exception
{
public ZlibException() : base();
{
return;
}
public ZlibException(string s) : base();
{
return;
}
}
I have a dll that includes:
public abstract class Module
{
internal int ID;
public abstract void ModuleStart();
}
public void function1() {}
public void function2() {}
//etc...
And then I have another dll that references the above dll and has:
class MyModule : Module
{
public override void ModuleStart()
{
function1();
}
}
What I'd like to be able to do is have function1 known the value of the calling module's ID, without it being passed in. Is there a way to do this? Basically what I'm trying to do is, the main Module DLL is loaded up, a method is run that loads in the second dll, uses reflection to make sure it has a child of Module, assigns it an ID and runs ModuleStart. MyModule can then do what it needs, calling functions from the first dll in order to access internal protected memory, but when the functions are called they need to know the ID of the Module that called them. Is this possible? MyModule has no knowledge of its ID, nor an ability to change it.
.NET 4.5 adds some functionality to do something similar to this with the CallerMemberNameAttribute. Here's a sample from the docs:
public void TraceMessage(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
Trace.WriteLine("message: " + message);
Trace.WriteLine("member name: " + memberName);
Trace.WriteLine("source file path: " + sourceFilePath);
Trace.WriteLine("source line number: " + sourceLineNumber);
}
A few people have suggested using the call stack to get the module information. If you want to get the type of object that made the call, it's not too bad. Unfortunately there is no feasible (ie: simple, portable and functional) method to extract instance information from data in the call stack. There are several reasons why, including problems with optimization inlining methods that then do not show on the stack... which can interfere with calling type detection as well.
Given this fact, the short answer is that you have to provide a Module object as a parameter to the methods you are calling in the DLL. The method suggested by #p.s.w.g is one way of achieving this, but has the disadvantage of potentially polluting the symbol space of the Module class. This can be solved by having the Module class implement a protected or public API member that exposes the functions you want to provide:
public abstract class Module
{
internal int ID;
public class APIWrapper
{
Module module;
public APIWrapper(Module module)
{
this.module = module;
}
public void method1() { apiimpl.method1(this.module); }
public int method2() { return apiimpl.method2(this.module); }
}
public readonly APIWrapper API;
public Module()
{
ID = generate_module_identity();
API = new APIWrapper(this);
}
public abstract void ModuleStart();
}
internal static class apiimpl
{
public static void method1(Module module) { ... }
public static int method2(Module module) { ... }
}
The other developers can then use it this way:
class MyModule : Module
{
public override void ModuleStart()
{
API.method1();
}
}
This encapsulates the methods that your DLL exposes, without introducing too much pollution of the symbol space of the Module class hierarchy.
[opinion type="my" value="YMMV"]
However, I suggest that you seriously reconsider using this type of abstraction. If the methods you are calling require some information about the specific Module instance that is calling them, it should be clear in the method's parameters. Encouraging your team to follow guidelines that lead to clarity can be more important than finding ways to abstract away small details.
[/opinion]
If what you really want is just to retrieve the ID at run-time, without passing any arguments into function1, you can use inherited methods:
public abstract class Module
{
internal int ID;
public abstract void ModuleStart();
protected void function1()
{
System.Console.WriteLine ("function1 called from module {0}", this.ID);
}
}
Then, from your other modules, calling function1 looks as simple as this:
class MyModule : Module
{
public override void ModuleStart()
{
this.function1(); // the 'this.' is not required
}
}
However, I get the sense from your comments that you want to make keep these functions separate from your Module class, since you are routinely adding new functions. You can do almost the exact same thing using extension methods to maintain the appearance of not passing any parameters:
public abstract class Module
{
internal int ID;
public abstract void ModuleStart();
}
public static class ModuleExtensions
{
public static void function1(this Module module)
{
innerFunction1(module.ID);
}
internal static void innerFunction1(int ID)
{
System.Console.WriteLine ("function1 called from module {0}", ID);
}
}
Then, from your other modules, calling function1 looks as simple as this:
class MyModule : Module
{
public override void ModuleStart()
{
this.function1(); // the 'this.' is required
}
}
Suppose you have an existing large project and you want to integrate Code Contracts in it. The existing code uses if-null-then-throw logic. For the given conditions, the documentation suggests to set the assembly mode to Custom Argument Validation.
I have the following classes:
class A
{
protected virtual void Foo(int a, int b)
{
if (a == null)
throw new ArgumentNullException(a);
if (b == null)
throw new ArgumentNullException(b);
Contract.EndContractBlock();
}
}
class B : A
{
protected override void Foo (int a, int b)
{
// some stuff
base.Foo(a, b);
}
}
When I compile I get the following warning:
warning CC1055: Method 'B.Foo(int, int)' should contain custom
argument validation for 'Requires(a != null)'
as it overrides 'A.Foo(int,int)' which suggests it does. If you don't
want to use custom argument validation in this assembly, change the
assembly mode to 'Standard Contract Requires'.
I don't want to repeat the preconditions on every overridden method! Is there a way around it?
It works fine if you use Contract.Requires() instead of Contract.EndContractBlock().
There is a section in the manual quoted below which suggests adding a [SuppressMessage] attribute to the method override.
From the Code Contracts user manual p.22 section 5.2.3.
Delegating Checks to Other Methods
Suppose you have a code pattern similar to the following code:
public class Base {
public virtual void Compute(string data) {
if (data == null) throw new ArgumentNullException(...);
Contract.EndContractBlock();
...
}
}
public class Derived : Base {
public override void Compute(string data) {
base.Compute(data);
...
}
}
Then the tools will issue warning CC1055 with a message of the form:
Method ’Derived.Compute’ should contain custom argument validation for
' Requires (ArgumentNullException)(data ! = null)' as it overrides
'Base.Compute' which suggests it does.
In this situation, the warning is not helpful, as the implementation
of Derived.Compute delegates the parameter validation to another
method (in this case the base method). To avoid the warning in this
situation without repeating the validation, you can add a
SuppressMessage attribute to the method:
public class Derived : Base {
[SuppressMessage("Microsoft.Contracts", "CC1055", Justification = "Validation performed in base method")]
public override void Compute(string data) {
base.Compute(data);
...
}
}