SharpCrafters Forum – Fast and comprehensive logging

SharpCrafters Support Forum

        

««12

Fast and comprehensive logging Expand / Collapse
Author
Message
Posted 9/4/2009 9:46:06 AM


Community Member
I now mapped the IL in PostSharp 1:1, but I am getting the following error during compilation:

Unhandled exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
  at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 278
  at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199
  at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199
  at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199
  at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199
  at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199
  at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199
  at PostSharp.ModuleWriter.PreparingInstructionEmitter.Prepare(AddressRange[]& instructionSequenceRanges, Boolean[]& localVariableHasMissingSymbol, Boolean[]& localVariableHasReference) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 163
  at PostSharp.CodeModel.MethodBodyDeclaration.WriteILDefinition(ILWriter writer) in p:\branches\1.5\Core\PostSharp.Core\CodeModel\MethodBodyDeclaration.cs:line 518
  at PostSharp.CodeModel.MethodDefDeclaration.WriteILDefinition(ILWriter writer, GenericMap genericMap) in p:\branches\1.5\Core\PostSharp.Core\CodeModel\MethodDefDeclaration.cs:line 1310
  at PostSharp.CodeModel.TypeDefDeclaration.WriteILDefinition(ILWriter writer) in p:\branches\1.5\Core\PostSharp.Core\CodeModel\TypeDefDeclaration.cs:line 1207
  at PostSharp.CodeModel.ModuleDeclaration.WriteILDefinition(ILWriter writer) in p:\branches\1.5\Core\PostSharp.Core\CodeModel\ModuleDeclaration.cs:line 706
  at PostSharp.Extensibility.Tasks.CompileTask.Execute() in p:\branches\1.5\Core\PostSharp.Core\Extensibility\Tasks\CompileTask.cs:line 451
  at PostSharp.Extensibility.Project.ExecutePhase(String phase) in p:\branches\1.5\Core\PostSharp.Core\Extensibility\Project.cs:line 1224
  at PostSharp.Extensibility.Project.Execute() in p:\branches\1.5\Core\PostSharp.Core\Extensibility\Project.cs:line 1267
  at PostSharp.Extensibility.PostSharpObject.ExecuteProjects() in p:\branches\1.5\Core\PostSharp.Core\Extensibility\PostSharpObject.cs:line 616
  at PostSharp.Extensibility.PostSharpObject.InvokeProject(ProjectInvocation projectInvocation) in p:\branches\1.5\Core\PostSharp.Core\Extensibility\PostSharpObject.cs:line 547
  at PostSharp.MSBuild.PostSharpRemoteTask.Execute(PostSharpTaskParameters parameters, TaskLoggingHelper log) in p:\branches\1.5\Core\PostSharp.MSBuild\PostSharpRemoteTask.cs:line 113 HK.Logging.Tests


The IL I want to replicate looks like this:

L_0002: ldstr "Category"
   L_0007: ldstr "Tracing"
   L_000c: ldstr "TracedMethod(string)"
   L_0011: ldc.i4.1
   L_0012: newarr [HK.Logging]HK.Logging.NameAndValue
   L_0017: stloc.0
   L_0018: ldloc.0
   L_0019: ldc.i4.0
   L_001a: ldstr "param1"
   L_001f: ldarg.1
   L_0020: newobj instance void [HK.Logging]HK.Logging.NameAndValue::.ctor(string, string)
   L_0025: stelem.ref
   L_0026: ldloc.0
   L_0027: call void [HK.Logging]HK.Logging.Log::MethodEntry(string, string, string, class [HK.Logging]HK.Logging.NameAndValue[])



The mapped PostSharp code looks like this:
           writer.EmitInstructionString(OpCodeNumber.Ldstr, "Category");
           writer.EmitInstructionString(OpCodeNumber.Ldstr, "Tracing");
           writer.EmitInstructionString(OpCodeNumber.Ldstr, "TracedMethod");
           writer.EmitInstruction(OpCodeNumber.Ldc_I4_1);
           writer.EmitInstructionType(OpCodeNumber.Newarr, _task.NameAndValueType);
           writer.EmitInstruction(OpCodeNumber.Stloc_0);
           writer.EmitInstruction(OpCodeNumber.Ldloc_0);
           writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
           writer.EmitInstructionString(OpCodeNumber.Ldstr, "param1");
           writer.EmitInstruction(OpCodeNumber.Ldarg_1);
           writer.EmitInstructionMethod(OpCodeNumber.Newobj, _task.NameAndValueConstructor);
           writer.EmitInstruction(OpCodeNumber.Stelem_Ref);
           writer.EmitInstruction(OpCodeNumber.Ldloc_0);
           writer.EmitInstructionMethod(OpCodeNumber.Call, _task.MethodEntryMethod);


The code matches perfectly, so I do not understand the error. Maybe a bug in PostSharp?
Post #3652
Posted 9/4/2009 9:55:29 AM


Gael Fraiteur

SharpCrafters
This means that you have put a wrong index somewhere. The exception occurs with delay, when PostSharp compiles back the assembly, which makes it more difficult to debug.

Generally speaking, using strongly-typed instructions (for instance EmitInstructionLocalVariable(OpCodeNumber.Ldloc,variable) instead of EmitInstructionInt16(Ldloc,1), both are valid) is safer since checks happen immediately.

As I said before, PostSharp Core and MSIL are matter for a couple of weeks of learning. It's an advanced low-level API and you can't expect the same level of usability than with high-level APIes.

-gael
Post #3653
Posted 9/4/2009 9:59:01 AM


Gael Fraiteur

SharpCrafters
More concretely to your code: you are using Stloc_0, but did you define a variable? If yes, are you sure its index is 0?
Post #3654
Posted 9/4/2009 10:14:00 AM


Community Member
The IL was generated by the C# compiler based on the code I want to generate, so technically it must be correct. Just in case, this is what the C# code looks like:
Log.MethodEntry("Category", "Tracing", "TracedMethod(string)", new NameAndValue[] { new NameAndValue("param1", param1) });
But with regards to your question, based on my understanding, Stloc_0 pops the reference to the created array from the stack and saves it in variable 0, Ldloc_0 then pushes the array to the stack again and Ldc_I4_0 specifies the array index of where to put the NameValue instance, which is created later on. The array index is 0 since the size of the array is only 1.
Post #3655
Posted 9/4/2009 10:17:47 AM


Gael Fraiteur

SharpCrafters
Sorry, I can't assist you with this. It's complex, you are going to have a difficult time, but I cannot help you every 30 minute.
Post #3656
« Prev Topic | Next Topic »

««12

All times are GMT +1:00, Time now is 11:44am

Powered By InstantForum.NET v4.1.4 © 2010
Execution: 0.024. 8 queries. Compression Disabled.