问题 为什么具有PEVerified Stack Overflow Scenario(maxstack)的程序不会崩溃CLR?


我可以编写,编译并成功运行以下IL程序,其.maxstack大小设置为1,这太低了,因为程序在一个时间点在堆栈上有两个值(即2 + 2 == 4)。这个计划 才不是 在CLR中崩溃,并以“Hello World”的所有预期输出结束执行,后跟数字4。

但是,该程序(正确地)不会传递PEVerify,它指出了堆栈溢出异常,并带有以下消息:

Microsoft(R).NET Framework PE Verifier。版本4.0.30319.18020   版权所有(c)Microsoft Corporation。版权所有。

[IL]:错误:[C:\ tmp \ hello.exe:HelloWorld1.Program :: Main] [偏移量   0x00000011]堆栈溢出。 1错误验证hello.exe

为什么它不会在CLR中崩溃?

.assembly extern mscorlib {}
.assembly SampleIL {
    .ver 1:0:1:0
}

.class private auto ansi beforefieldinit HelloWorld1.Program
    extends [mscorlib]System.Object
{
    // Methods
    .method private hidebysig static 
        void Main (
            string[] args
        ) cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 13 (0xd)
        .maxstack 1 // **** NOTE THIS LINE *****
        .entrypoint

        IL_0000: nop
        IL_0001: ldstr "hello world"
        IL_0006: call void [mscorlib]System.Console::WriteLine(string)
        IL_000b: nop

        ldc.i4 2
        ldc.i4 2
        add
        call void [mscorlib]System.Console::WriteLine(int32)

        IL_000c: ret
    } // end of method Program::Main

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x205e
        // Code size 7 (0x7)
        .maxstack 8    

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    } // end of method Program::.ctor

} // end of class HelloWorld1.Program

1123
2018-05-29 01:16


起源

.maxstack声明方法使用的CLR堆栈的最大深度。这与CPU堆栈的最大大小不同。它们都被称为堆栈,但它们不是相同的堆栈。特别是,CLR堆栈是虚构的。它是虚拟机的理论构造。 - Raymond Chen
@RaymondChen为什么你不能在我写完我假设后者的答案之前发布这个帖子? :-) - Jonathon Reinhart
@JonathonReinhart,如果您删除的答案包含有价值的技术信息以补充学习,您可以取消删除它。我不确定你是否删除了它,因为你认为它包含错误的信息,或者是因为你认为你与+ RaymondChen的评论重叠。 - John K
@JohnK这是不正确的。雷蒙德表示 .maxstack 与我的答案所指的实际CPU堆栈无关。 - Jonathon Reinhart
“这个值主要用于IL代码验证和某些想要预先了解IL堆栈深度的JIT编译器“。 - Raymond Chen


答案:


通过@RaymondChen从问题评论中得出的答案

公共语言基础结构(CLI)
分区III
CIL指令集
最终草案,2005年4月

1.7.4必须提供maxstack

[...剪...]
  [注意: Maxstack与。有关   分析程序,而不是运行时堆栈的大小。它   没有指定堆栈帧的最大字节数,但是   而是分析工具应跟踪的项目数。   结束说明]


9
2018-05-29 03:22