Разделы презентаций


.NET code hot reload Асадуллин Тимур Directum, Уфа

Содержание

Что за «Code hot reload»?Обновление кода приложения без перезапуска этого приложения..NET Framework (4.6 +) Надеюсь такие слова вас не пугают: CLR, MSIL, Assembly, указатель.

Слайды и текст этой презентации

Слайд 1.NET code hot reload
Асадуллин Тимур
Directum, Уфа

.NET code hot reload Асадуллин ТимурDirectum, Уфа

Слайд 2Что за «Code hot reload»?
Обновление кода приложения без перезапуска этого

приложения.

.NET Framework (4.6 +)
Надеюсь такие слова вас не пугают: CLR, MSIL,

Assembly, указатель.
Что за «Code hot reload»?Обновление кода приложения без перезапуска этого приложения..NET Framework (4.6 +) Надеюсь такие слова

Слайд 3DirectumRX – ECM-система

DirectumRX – ECM-система

Слайд 4DirectumRX Development Studio

DirectumRX Development Studio

Слайд 5Прикладная разработка DirectumRX
Development Studio (IDE)
Локальный сервер приложений
Код платформы (framework)
Прикладной код
Новый

прикладной код
Deploy (dll)
compile
restart

Прикладная разработка DirectumRXDevelopment Studio (IDE)Локальный сервер приложенийКод платформы (framework)Прикладной кодНовый прикладной кодDeploy (dll)compilerestart

Слайд 6Зачем нам HotReload
Development Studio (IDE)
Локальный сервер приложений
Код платформы (framework)
Прикладной код
Новый

прикладной код
Deploy
compile
restart

Зачем нам HotReloadDevelopment Studio (IDE)Локальный сервер приложенийКод платформы (framework)Прикладной кодНовый прикладной кодDeploycompilerestart

Слайд 7Дополнительные ограничения и пожелания
Если поменялась структура БД, одним HotReload не

обойтись.
HotReload и отладка в Dev Studio (breakpoints, watch).
Подходит и для

серверного, и для клиентского кода (у нас есть Desktop-клиент).

Дополнительные ограничения и пожеланияЕсли поменялась структура БД, одним HotReload не обойтись. HotReload и отладка в Dev Studio

Слайд 8Основная идея
Избавиться от перезапуска сервера.
Встраивать код напрямую в работающее приложение.
Development

Studio (IDE)
Локальный сервер приложений
Код платформы
Прикладной код
Новый прикладной код
Исходник или Assembly
inject

Основная идеяИзбавиться от перезапуска сервера.Встраивать код напрямую в работающее приложение.Development Studio (IDE)Локальный сервер приложенийКод платформыПрикладной кодНовый прикладной

Слайд 9Решения в лоб
Reflection – LoadAssembly (Shadow Copy Assemblies)

Managed Extensibility Framework (MEF,

VS-MEF)

Mono.Cecil

Решения в лобReflection – LoadAssembly (Shadow Copy Assemblies)Managed Extensibility Framework (MEF, VS-MEF)Mono.Cecil

Слайд 10Решения в лоб. Проблемы
Не повлияем на уже существующие в памяти

объекты.

Новые объекты, создаваемые через new будут ссылаться на старые типы.

В

случае с MEF прикладной код придётся переписать особым образом (атрибуты, интерфейсы).

Решения в лоб. ПроблемыНе повлияем на уже существующие в памяти объекты.Новые объекты, создаваемые через new будут ссылаться

Слайд 11Emit
CodeDom – компиляция С# в Assembly сразу в память в

AppDomain.
Emit – генерация IL-кода.
Development Studio (IDE)
Локальный сервер приложений
Платформа
Прикладной код
Новые прикладные

исходники

C#

compile

emit

EmitCodeDom – компиляция С# в Assembly сразу в память в AppDomain. Emit – генерация IL-кода.Development Studio (IDE)Локальный

Слайд 12Emit. Проблемы
Emit работает только с DynamicAssembly. А при компиляции CodeDom’a мы

получаем обычную Assembly.

Чтобы «завести» динамический класс, нужно вызвать у него CreateType(). Это

блокирует его дальнейшие модификации.
Emit. ПроблемыEmit работает только с DynamicAssembly. А при компиляции CodeDom’a мы получаем обычную Assembly.Чтобы «завести» динамический класс,

Слайд 13Edit and Continue
Встроенный в Visual Studio хитрый механизм, генерирующий некоторые

дельты.

Общедоступного API нет.

Даже в самой VS механизм не работает в

ряде случаев.
Edit and ContinueВстроенный в Visual Studio хитрый механизм, генерирующий некоторые дельты.Общедоступного API нет.Даже в самой VS механизм

Слайд 15Method Inject v1

Method Inject v1

Слайд 16­Method Inject v1
Суть – замена указателя на метод.
MethodInfo methodToReplace =

… ; MethodInfo methodToInject = … ;

unsafe { long* target

= (long*) methodToReplace.MethodHandle.Value.ToPointer();
long* inject = (long*) methodToInject.MethodHandle.Value.ToPointer();
*target = *inject; }


В реальности чуток сложнее, потому что надо учесть x86/x64, Debug/Release.

­Method Inject v1Суть – замена указателя на метод.MethodInfo methodToReplace = … ; MethodInfo methodToInject = … ;

Слайд 17Как хранятся описания классов в .NET
Заголовок

MethodTable ptr

Field value 1
Field value

2

ObjectInstance


ToString() ptr
Equals() ptr
….
MyMethod1() ptr


MethodTable
{
Console.WriteLine(1);
}

На самом деле тут IL, конечно

Как хранятся описания классов в .NETЗаголовокMethodTable ptrField value 1Field value 2…ObjectInstance…ToString() ptrEquals() ptr….MyMethod1() ptr…MethodTable{ Console.WriteLine(1);}На самом деле

Слайд 18Method Inject v1. Суть
Заголовок

MethodTable ptr

Field value 1
Field value 2

ObjectInstance


ToString()

ptr
Equals() ptr
….
MyMethod1() ptr


MethodTable
{
Console.WriteLine(1);
}

{
Console.WriteLine(2);
}

Method Inject v1. Суть ЗаголовокMethodTable ptrField value 1Field value 2…ObjectInstance…ToString() ptrEquals() ptr….MyMethod1() ptr…MethodTable{ Console.WriteLine(1);}{ Console.WriteLine(2);}

Слайд 19Method Inject v1. Проверяем на практике
Есть два класса…
Target

TargetMethod()
Injection

InjectionMethod()
Injector

Method Inject v1. Проверяем на практикеЕсть два класса…TargetTargetMethod()InjectionInjectionMethod()Injector

Слайд 20Method Inject v1. Проверяем на практике
Исходный MethodTable

TestClasses.Target.Test()
TestClasses.Target.TargetMethod()
TestClasses.Target.get_Value()
TestClasses.Target..ctor (System.String)
WinDbg + SOS

Method Inject v1. Проверяем на практикеИсходный MethodTableTestClasses.Target.Test()TestClasses.Target.TargetMethod()TestClasses.Target.get_Value()TestClasses.Target..ctor (System.String)WinDbg + SOS

Слайд 21Method Inject v1. Проверяем на практике
MethodTable после Inject

TestClasses.Target.Test()
TestClasses.Injection.InjectionMethod()
TestClasses.Target.get_Value()
TestClasses.Target..ctor (System.String)

Method Inject v1. Проверяем на практикеMethodTable после InjectTestClasses.Target.Test()TestClasses.Injection.InjectionMethod()TestClasses.Target.get_Value()TestClasses.Target..ctor (System.String)

Слайд 22Method Inject v1. Дополнительные работы
Сравнить прикладные исходники и найти изменившиеся

методы.

Передать исходники методов на сервер.

Создать новый класс, засунуть в него

методы и скомпилировать в память.

Найти старый метод и сделать MethodInject на новый.
Method Inject v1. Дополнительные работыСравнить прикладные исходники и найти изменившиеся методы.Передать исходники методов на сервер.Создать новый класс,

Слайд 23Method Inject v1. ПРОБЛЕМА!
Прекрасно работает
пока мы не вызвали подменяемый метод.

Method Inject v1. ПРОБЛЕМА!Прекрасно работаетпока мы не вызвали подменяемый метод.

Слайд 24Method Inject v1. ПРОБЛЕМА!
….
Code ptr




….
MyMethod1() ptr


MethodTable
{
Console.WriteLine(1);
}

MethodDesc
Stub
PreJitStub
native machine code
Write jmp to

jitted code
compileMethod

Method Inject v1. ПРОБЛЕМА!….Code ptr……….MyMethod1() ptr…MethodTable{ Console.WriteLine(1);}MethodDescStubPreJitStubnative machine codeWrite jmp to jitted codecompileMethod

Слайд 25Method Inject v2

Method Inject v2

Слайд 26Method Inject v2
public static class InjectionHelper
{
...

public static void

Initialize()

public static void UpdateILCodes(MethodInfo method, byte[] ilCodes)

...
}

Method Inject v2public static class InjectionHelper{ ... public static void Initialize() public static void UpdateILCodes(MethodInfo method, byte[]

Слайд 27Method Inject v2
….
Code ptr




….
MyMethod1() ptr


MethodTable
IL
MethodDesc
Stub
PreJitStub
machine code
Write jmp to jitted code
compileMethod

Method Inject v2….Code ptr……….MyMethod1() ptr…MethodTableILMethodDescStubPreJitStubmachine codeWrite jmp to jitted codecompileMethod

Слайд 28Injector
….
Code ptr




….
MyMethod1() ptr


MethodTable
IL
MethodDesc
Stub
PreJitStub
machine code
MethodDesc.Reset()
Method Inject v2
Write jmp to jitted code
compileMethod
hook

Injector….Code ptr……….MyMethod1() ptr…MethodTableILMethodDescStubPreJitStubmachine codeMethodDesc.Reset()Method Inject v2Write jmp to jitted codecompileMethodhook

Слайд 29Method Inject v2. Проблемки
Нормально заработало только на .NET Framework 2.0 -

4.0

Inline маленьких методов.

Лезем внутрь CLR. Слишком рискованно для продакшена.

Method Inject v2. ПроблемкиНормально заработало только на .NET Framework 2.0 - 4.0Inline маленьких методов.Лезем внутрь CLR. Слишком

Слайд 30Давайте вспомним, с чего мы начали
Есть платформа.

Она исполняет прикладной код.

Мы

хотим подменять прикладной код.

Давайте вспомним, с чего мы началиЕсть платформа.Она исполняет прикладной код.Мы хотим подменять прикладной код.

Слайд 31Что за прикладной код?
Document

Name
Author
Created

ServerHandlers

BeforeSave()
AfterSave()

ServerFunctions

ServerFoo()

ClientHandlers

Showing()

ClientFunctions

ClientFoo()

Этот класс генерируется платформой

Что за прикладной код?DocumentNameAuthorCreated…ServerHandlersBeforeSave()AfterSave()…ServerFunctionsServerFoo()…ClientHandlersShowing()…ClientFunctionsClientFoo()…Этот класс генерируется платформой

Слайд 32Class swap
Платформенный код создаёт прикладные объекты (Dependency Injection).
Не возимся с методами

– заменяем сразу весь объект.
Document1

Name

IDocument1ServerFunctions

Foo()

Document1ServerFunctions

Foo()

IDocument1ServerFunctions

Class swapПлатформенный код создаёт прикладные объекты (Dependency Injection).Не возимся с методами – заменяем сразу весь объект.Document1Name…IDocument1ServerFunctionsFoo()…Document1ServerFunctionsFoo()…IDocument1ServerFunctions

Слайд 33Class swap
Document1
Document1ServerFunctions

Foo()
IDocument1ServerFunctions
AppTypesManager
Implementation
Create ServerFunctions ()

Class swapDocument1Document1ServerFunctionsFoo()IDocument1ServerFunctionsAppTypesManagerImplementationCreate ServerFunctions ()

Слайд 34Class swap

Document1
Document1ServerFunctions

Foo()
IDocument1ServerFunctions
AppTypesManager
Create ServerFunctions ()
Injector
Create type
C# sources

Class swap…Document1Document1ServerFunctionsFoo()IDocument1ServerFunctionsAppTypesManagerCreate ServerFunctions ()InjectorCreate typeC# sources

Слайд 35Class swap
Document1
Document1ServerFunctions

Foo()
IDocument1ServerFunctions
Document1ServerFunctions

Foo()
IDocument1ServerFunctions
AppTypesManager
Implementation
Create ServerFunctions ()
Injector
Create type
Register
C# sources

Class swapDocument1Document1ServerFunctionsFoo()IDocument1ServerFunctionsDocument1ServerFunctionsFoo()IDocument1ServerFunctionsAppTypesManagerImplementationCreate ServerFunctions ()InjectorCreate typeRegisterC# sources

Слайд 36Заключение
В продакшен это не пошло :( Деплой мы ускорили иначе –

оптимизации.

Исследования – круто.

Погружение в детали инструмента – интересно.

ЗаключениеВ продакшен это не пошло :( Деплой мы ускорили иначе – оптимизации.Исследования – круто.Погружение в детали инструмента

Слайд 37()
.net core
JIT disable
Custom .NET CLR

().net core JIT disable Custom .NET CLR

Слайд 38THE END
Асадуллин Тимур
Directum, Уфа
timonik@bk.ru

THE ENDАсадуллин ТимурDirectum, Уфаtimonik@bk.ru

Слайд 39Ссылочки
MethodInject v1 https://www.codeproject.com/Articles/37549/CLR-Injection-Runtime-Method-Replacer
MethodInject v2 https://www.codeproject.com/Articles/463508/NET-CLR-Injection-Modify-IL-Code-during-Run-time
EasyHook https://easyhook.github.io
Отладка WinDbg + SOS https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-managed-code


.net core «How to use and debug assembly unloadability in .NET

Core» https://docs.microsoft.com/ru-ru/dotnet/standard/assembly/unloadability
СсылочкиMethodInject v1 https://www.codeproject.com/Articles/37549/CLR-Injection-Runtime-Method-Replacer  MethodInject v2 https://www.codeproject.com/Articles/463508/NET-CLR-Injection-Modify-IL-Code-during-Run-time  EasyHook https://easyhook.github.io  Отладка WinDbg + SOS https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-managed-code

Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика