Создание отладки CLR/.NET

Каковы некоторые ресурсы для отладки CLR/.NET? Я разрабатываю компилятор ActionScript 3 в IL, который использует DLS CallSites и CallSiteBinders для обработки динамических аспектов статического языка программирования. Я ищу любую информацию о том, как сделать испущенную карту IL обратно исходному коду, и я также хотел бы знать, как я могу сделать динамические сайты вызовов обратно.

Итак, это в конечном счете два вопроса:

  • Как я могу отлаживать IL?
  • Как я могу отлаживать сайты вызовов DLR?

Любая помощь будет принята с благодарностью!

Что я ищу в терминах "debuggabilty"

Внутри встроенного экземпляра Visual Studio:

  • Шаг через код
  • Просмотр локальных жителей
  • Просмотр трассировки стека

Ответ 1

Чтобы сделать отладку IL, вам необходимо скомпилировать код в отладочную сборку. Также существует немедленный недостаток в том, что сборка не будет собираться GC. Для этого выполните AppDomain.CurrentDomain.DefineDynamicAssembly, затем вы вызываете DefineDynamicModule и определяете модуль в сборке. Чтобы сделать его отлаживаемым, вам нужно установить некоторые атрибуты:

DebuggableAttribute.DebuggingModes attrs =
    DebuggableAttribute.DebuggingModes.Default |
    DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints |
    DebuggableAttribute.DebuggingModes.DisableOptimizations;

Type[] argTypes = new Type[] { typeof(DebuggableAttribute.DebuggingModes) };
Object[] argValues = new Object[] { attrs };

_myAssembly.SetCustomAttribute(new CustomAttributeBuilder(
   typeof(DebuggableAttribute).GetConstructor(argTypes), argValues)
);

_myModule.SetCustomAttribute(new CustomAttributeBuilder(
    typeof(DebuggableAttribute).GetConstructor(argTypes), argValues)
);

Наконец, при испускании IL вы вызываете MarkSequencePoint, чтобы отметить строки для следующих инструкций IL.

Создание отлаживаемых сайтов вызовов DLR кажется странным для меня - обычно ваш сайт вызова не будет содержать какой-либо код пользователя. Скорее, он будет содержать код для выполнения операции, и исходный код, связанный с этим кодом, отсутствует. Но позвольте сказать, что вы действительно хотите что-то сделать, чтобы связать с деревьями выражений, которые вы генерируете для сайта вызова. Для этого вам нужно сделать две вещи. Сначала хранится информация об отладке в дереве выражений - вы делаете это с помощью DebugInfoExpression. Следующим является компиляция метода в метод отладки и предоставление этого делегата DLR.

Для компиляции метода вам необходимо использовать LambdaExpression<T>.CompileToMethod. MethodBuilder, который вам нужно предоставить, должен быть статическим методом, определенным в типе создаваемой ранее отлаживаемой сборки.

Для предоставления этому делегату DLR у вас есть два варианта. Вероятно, самым легким было бы фактически вернуть выражение, которое вызывает скомпилированный отлаживаемый делегат (просто удерживая его через константу). Более сложным, но в некотором смысле более элегантным способом было бы переопределить BindDelegate<T> на сайте вызова и вернуть скомпилированный делегат. Это начинает вступать в создание соответствующего аргумента Expression и вызывает методы Bind* для создания дерева выражений, но вы сами.

Все это делается в внешнем слое DLR/IronPython/IronRuby - все доступно на ironpython.codeplex.com. Вы можете посмотреть CompilerHelpers.CompileToMethod как пример выполнения компиляции, класса Snippets (и связанных классов AssemblyGen/TypeGen/ILGen) для создания отлаживаемых сборок и даже компилятора дерева выражений DLR ( в Runtime\Microsoft.Scripting.Core\Compiler) для примера испускания информации о линии.