标签: il

如何捕获一个int

我正在使用IL来抛出一个Int32并捕获它.这只是出于好奇,我不想做任何事情,所以请不要告诉我抛出异常而不是int.

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       40 (0x28)
  .maxstack  2
  .locals init (object V_0,
       int32 V_1)
  IL_0000:  nop
  .try
  {
    IL_0001:  nop
    IL_0002:  ldsfld     int32 ConsoleApplication3.Program::i
    IL_0007:  throw
  }  // end .try
  catch [mscorlib]System.Object 
  {
    IL_0008:  stloc.0
    IL_0009:  nop
    IL_000a:  ldstr      "In Object catch"
    IL_000f:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_0014:  nop
    IL_0015:  ldloc.0
    IL_0016:  unbox.any  [mscorlib]System.Int32
    IL_001b:  stloc.1
    IL_001c:  ldloc.1
    IL_001d:  call       void [mscorlib]System.Console::WriteLine(int32)
    IL_0022:  nop
    IL_0023:  nop
    IL_0024:  leave.s    IL_0026
  } …
Run Code Online (Sandbox Code Playgroud)

.net il exception-handling

8
推荐指数
1
解决办法
206
查看次数

每个.NET类的最大方法数是多少

标题实际上是要求所有,但为了完整起见:

嗨,我正在.NET平台上编写一个小的后编译工具,在尝试优化它时,我遇到了一个问题,我不能轻易找到ECMA标准的公共语言基础结构的答案(CLI).

单个类可以拥有的最大方法数是多少?有限制吗?

编辑:

感谢Kelsey指出真实的测试.虽然我仍然会关心实际限制是什么,但对于我的实际目的,我想知道它是否是2 ^ 16/2 ^ 32 - 或 - 2 ^ 31-1,正如他所指出的,它出现了显然高于每级64K方法..

.net standards il command-line-interface

8
推荐指数
1
解决办法
805
查看次数

这段代码中有什么不安全的?

我正在学习CLR中的托管和非托管代码.所以我用C#中的C风格指针编写了这个例子:

unsafe  static void Main(string[] args)
{
    int x;
    int* y;
    y = &x;
    *y = 50;
    Console.WriteLine(*y);
    Console.WriteLine(((int)y).ToString());
}
Run Code Online (Sandbox Code Playgroud)

所以我想知道我从上面的代码得到的IL代码中真正不安全的是什么?

.assembly extern mscorlib
{}
.assembly UnsafePointers
{}
.module UnsafePointers.exe
.class private auto ansi beforefieldinit UnsafePointers.Program
extends [mscorlib]System.Object
{
    .method private hidebysig static void  Main(string[] args) cil managed
    {
        .entrypoint
        // Code size       34 (0x22)
        .locals init (int32 x,
        int32* y)
        IL_0001:  ldloca     x
        IL_0003:  conv.u
        IL_0004:  stloc      y
        IL_0005:  ldloc  y 
        IL_0006:  ldc.i4   50
        IL_0008:  stind.i4
        IL_0009:  ldloc      y …
Run Code Online (Sandbox Code Playgroud)

c# clr il pointers unsafe

8
推荐指数
3
解决办法
1228
查看次数

使类型的实例不可存储

  • 有没有办法标记一个类型(甚至更好,一个接口),以便它的任何实例都不能存储在一个字段中(以类似的方式TypedReferenceArgIterator?)?
  • 以同样的方式,有没有办法防止实例通过匿名方法传递 - 通常 - 模仿上面两种类型的行为?
  • 这可以通过ILDasm或更一般地通过IL编辑来完成吗?由于UnconstrainedMelody通过编译程序集的二进制编辑实现了通常无法获得的结果,因此可能有一种方法可以通过相同的方法"标记"某些类型(甚至更好的,抽象的或标记接口).

我怀疑它在编译器中是硬编码的,因为错误CS0610文档指出:

有些类型不能用作字段或属性.这些类型包括......

在我看来哪些类型可以扩展 - 但我可能是错的.

我在SO上搜索了一下,虽然我明白以编程方式抛出编译器错误无法完成,但我找不到任何来源说明某些"特殊"类型的行为无法复制.

即使问题主要是学术问题,也可能会有一些答案.例如,有时可以确保某个对象的生命周期被约束到创建它的方法块.

编辑: RuntimeArgumentHandle是一种(未提及)不可存储的类型.

编辑2:如果它可以有任何用途,似乎CLR也以不同的方式处理这些类型,如果不仅仅是编译器(仍然假设类型与其他类型没有任何区别).例如,以下程序将提出一个TypeLoadException问题TypedReference*.我已经对它进行了调整以缩短它,但你可以随心所欲地解决它.例如,void*将指针的类型更改为不会抛出异常.

using System;

unsafe static class Program
{
    static TypedReference* _tr;

    static void Main(string[] args)
    {
        _tr = (TypedReference*) IntPtr.Zero;
    }
}
Run Code Online (Sandbox Code Playgroud)

c# il compiler-errors ildasm

8
推荐指数
1
解决办法
278
查看次数

即使没有参数,也使用CIL OpCode(Ldarg_0)

我有以下C#代码.

public void HelloWorld()
{
    Add(2, 2);
}

public void Add(int a, int b)
{
    //Do something
}
Run Code Online (Sandbox Code Playgroud)

它产生以下CIL

.method public hidebysig instance void  HelloWorld() cil managed
{
  // Code size       11 (0xb)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldc.i4.2
  IL_0003:  ldc.i4.2
  IL_0004:  call       instance void ConsoleApplication3.Program::Add(int32,
                                                                      int32)
  IL_0009:  nop
  IL_000a:  ret
} // end of method Program::HelloWorld
Run Code Online (Sandbox Code Playgroud)

现在,我不明白的是偏移0001处的线:

ldarg.0

我知道那个操作码的用途是什么,但我真的不明白为什么它在这个方法中使用,因为没有参数,对吧?

有人知道为什么吗?:)

c# clr il cil

8
推荐指数
2
解决办法
2211
查看次数

如何识别阵列类型?

我有一个OutOfMemoryException,我想分析应该创建的数组的大小和类型.

我为这种情况创建了一个演示目的转储,我能够获得以下信息:

0:000> !pe
Exception object: 023f389c
Exception type: System.OutOfMemoryException
Message: <none>
InnerException: <none>
StackTrace (generated):
    SP       IP       Function
    0015EE44 0099007F OOM2!OOM2.Program.Main()+0xf

StackTraceString: <none>
HResult: 8007000e

0:000> !u 0099007F 
Normal JIT generated code
OOM2.Program.Main()
Begin 00990070, size 22
00990070 baffffff7f      mov     edx,7FFFFFFFh
00990075 b90241a478      mov     ecx,offset mscorlib_ni+0x4102 (78a44102)
0099007a e8192194ff      call    002d2198 (JitHelp: CORINFO_HELP_NEWARR_1_VC)
>>> 0099007f 8bc8            mov     ecx,eax
...
Run Code Online (Sandbox Code Playgroud)

所以我可以看到创建了一个新数组,大小为7FFFFFFF,这是20亿个项目.(请忽略这样一个事实:您甚至无法在32位.NET应用程序中创建该大小的byte [],因此在此示例中类型可能根本不重要.)

我现在已经读过数组的类型在ECX寄存器中,但遗憾的mscorlib_ni+0x4102 (78a44102)是不是很有帮助.

我尝试过!mln,!mdt甚至不切实际!ip2mt,但没有一个显示预期bytebyte[]输出.有没有办法从mscorlib的原生图像中获取类型?

.net il windbg sos sosex

8
推荐指数
1
解决办法
334
查看次数

从IL创建方法的副本

我试图在运行时使用反射创建方法的副本.

我有以下代码.

public static R CopyMethod<T, R>(Func<T, R> f, T t)
{
    AppDomain currentDom = Thread.GetDomain();
    AssemblyName asm = new AssemblyName();
    asm.Name = "DynamicAssembly";
    AssemblyBuilder abl = currentDom.DefineDynamicAssembly(asm, AssemblyBuilderAccess.Run);
    ModuleBuilder mbl = abl.DefineDynamicModule("Module");
    TypeBuilder tbl = mbl.DefineType("Type");
    var info = f.GetMethodInfo();
    MethodBuilder mtbl = tbl.DefineMethod(info.Name, info.Attributes, info.CallingConvention, info.ReturnType, info.GetParameters().Select(x => x.ParameterType).ToArray());

    byte[] il = f.Method.GetMethodBody().GetILAsByteArray();

    mtbl.CreateMethodBody(il, il.Length);
    Type type = tbl.CreateType();
    Func<T, R> method = type.GetMethod(info.Name).CreateDelegate(typeof(Func<T, R>)) as Func<T, R>;
    return method(t);
}
Run Code Online (Sandbox Code Playgroud)

最后一行抛出一条带有消息的异常:

Common Language Runtime检测到无效程序.

还有另一种方法吗?我希望能够获得方法的解析树而不是直接使用IL.

编辑1: …

c# reflection il reflection.emit .net-assembly

8
推荐指数
1
解决办法
1258
查看次数

你对.NET CLR和CIL的好书有什么建议?

您是否知道有关CLR,.NET FrameworkCIL的工作方式的任何好书,而不是任何特定的.NET语言?

.net clr il cil

7
推荐指数
2
解决办法
3029
查看次数

关闭一个错误和变异测试

在为我最喜欢的突变测试框架(NinjaTurtles)编写"Off By One"变异测试程序的过程中,我编写了以下代码,以便提供检查我的实现的正确性的机会:

public int SumTo(int max)
{
    int sum = 0;
    for (var i = 1; i <= max; i++)
    {
        sum += i;
    }
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

现在这看起来很简单了,并没有让我觉得尝试改变IL中的所有文字整数常量会有问题.毕竟,只有3(the 0,the 1,and ++).

错误!

在第一次运行中它变得非常明显,它在这个特定的实例中永远不会起作用.为什么?因为将代码更改为

public int SumTo(int max)
{
    int sum = 0;
    for (var i = 0; i <= max; i++)
    {
        sum += i;
    }
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

只在总和上加0(零),这显然没有效果.不同的故事,如果它是多组,但在这种情况下,它不是.

现在有一个相当简单的算法来计算整数之和

sum = max * (max + 1) / 2;
Run Code Online (Sandbox Code Playgroud)

我可以轻易地使突变失败,因为从任一常数中加1或减1会导致错误.(鉴于此max >= …

c# algorithm il mutation-testing ninja-turtles

7
推荐指数
1
解决办法
932
查看次数

在C#中使用静态方法实现接口

假设我有以下ILAsm代码:

    .class public interface abstract ITest
    {
        .field public static int32 counter

        .method public static void StaticMethod(string str)
        {
            ldarg.0
            call void [mscorlib]System.Console::WriteLine(string)
            ret
        }

        .method public virtual abstract void InstMethod(string) { }
    }
Run Code Online (Sandbox Code Playgroud)

是否可以在C#中定义实现此ITest接口的类?

我可以在ILAsm中实现这个接口:

    .class public TestImpl extends [mscorlib]System.Object implements ITest
    {
        .method public virtual void InstMethod(string str)
        {
            ldarg.1
            call void ITest::StaticMethod(string)
            ret
        }

        .method public specialname rtspecialname instance void .ctor()
        {
            ldarg.0
            call instance void .base::.ctor()
            ret
        }
    }
Run Code Online (Sandbox Code Playgroud)

并成功使用C#代码中实现的类:

        var testImpl = new …
Run Code Online (Sandbox Code Playgroud)

.net c# clr il

7
推荐指数
1
解决办法
2867
查看次数