Почему программа с 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 Copyright (c) Microsoft Corporation. Все права защищены.

[IL]: Ошибка: [C:\tmp\hello.exe : HelloWorld1.Program::Main][offset 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

person John K    schedule 29.05.2014    source источник
comment
.maxstack объявляет максимальную глубину стека CLR, используемую методом. Это не то же самое, что максимальный размер стека ЦП. Они оба называются стеками, но это не один и тот же стек. В частности, стек CLR является воображаемым. Это теоретическая конструкция виртуальной машины.   -  person Raymond Chen    schedule 29.05.2014
comment
@RaymondChen Почему вы не могли опубликовать это до того, как я закончил писать свой ответ, который предполагал последнее? :-)   -  person Jonathon Reinhart    schedule 29.05.2014
comment
@JonathonReinhart, если ваш удаленный ответ содержит ценную техническую информацию для дополнения обучения, вы можете восстановить его. Я не уверен, удалили ли вы его, потому что считаете, что он содержит неверную информацию, или это потому, что вы думали, что вы пересекаетесь с комментарием +RaymondChen.   -  person John K    schedule 29.05.2014
comment
@JohnK Это неправильно. Рэймонд указал, что .maxstack не имеет ничего общего с фактическим стеком ЦП, к которому относился мой ответ.   -  person Jonathon Reinhart    schedule 29.05.2014
comment
@RaymondChen Тогда я задаюсь вопросом о полезности. Почти похоже на HTML Content-Length, благодаря чему браузеры могут правильно интерпретировать его, несмотря на отсутствие или ошибку. Считаете ли вы, что maxstack тогда относится к простой проверке стека ЦП, или, может быть, он просто практически бесполезен, но сохраняется для теоретической корректности. Например, если среда CLR была создана как аппаратная машина, ее можно было бы использовать.   -  person John K    schedule 29.05.2014
comment
@RaymondChen спасибо за ссылку. В этом потоке также упоминается Чтение спецификации CIL. Я вижу, что maxstack связан с анализом программы, а не с размером стека во время выполнения. Хорошая информация.   -  person John K    schedule 29.05.2014


Ответы (1)


Ответ получен из комментариев к вопросу через @RaymondChen

Common Language Infrastructure (CLI)
Раздел III
Набор инструкций CIL
Окончательный проект, апрель 2005 г.

1.7.4 Необходимо предоставить maxstack

[... snip ... ]
[Примечание: Maxstack связан с анализом программы, а не с размером стека во время выполнения. Он определяет не максимальный размер кадра стека в байтах, а скорее количество элементов, которые должны отслеживаться инструментом анализа. примечание в конце]

person John K    schedule 29.05.2014