Skip to content

Commit

Permalink
Update to latest (#2)
Browse files Browse the repository at this point in the history
* English translation

* Updated readmes

* Fixed link

* Little fixes of disposable

* New chaper started: entities lifetime

* Update chapter 1-Entities

* Compare with different

* fixes in chapters: style and е/ё letters

* About stages of object's lifetime

* Fixes in 1-EntitiesLifetime chapter

* Finished with basic results in 1-entities

* ReadMe changed

* Add files via upload

* мелочь

* Update Readme.md

* added new chapter

* added links to ToC

* ToC upd

* Introduction to memory management

* Additional adoptation done

* Writing new sent-s about memory mngmnt

* about architects choose

* Arch review ready

* additional edits in book

* Russian part restructured

* ToC fixed

* Updating introduction to the book

* MM Intro changes

* text updated

* sidristij#102 Making text cleaner

* Continue after gc basics

* sidristij#102 added link to the next chapter

* Reading order

* fixed relative path

* Book restructured

* Adding subchapters links

* TOC styles

* Adding subchapters links

* Adding subchapters links

* remove cover

* upd release
  • Loading branch information
BratSin authored Sep 16, 2019
1 parent 633df61 commit 80c0796
Show file tree
Hide file tree
Showing 50 changed files with 2,018 additions and 69 deletions.
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[![](https://habrastorage.org/webt/m6/y8/g6/m6y8g69h1spogkxkjibwb9t0cgu.jpeg)](https://habr.com/ru/company/clrium/blog/460635/)
# This book is available in:

- **English**: If you want to show that you like this book or to express your gratitude to author, Star this project, Fork it and Pull Requests to it.
Expand Down
Binary file modified bin/CLR book.docx
Binary file not shown.
Binary file modified bin/CLR book.pdf
Binary file not shown.
534 changes: 534 additions & 0 deletions book/en/ExceptionalFlow/4-Exceptions-Types.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions book/en/Links.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Links and references

1. [CLR via C#](https://www.amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454) by [Jeffrey Richter](https://github.com/JeffreyRichter)
1. [Matt Warren blog](https://mattwarren.org/)
1. [JetBrains Lifetime](https://www.jetbrains.com/help/resharper/sdk/Platform/Lifetime.html)
1. [Pro .NET Memory Management](https://prodotnetmemory.com/) by [Konrad Kokosa](https://twitter.com/konradkokosa)
632 changes: 632 additions & 0 deletions book/en/ThreadStack.md

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions book/en/readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
![](../../bin/BookCover.png)


# Table of contents

1. Common Language Runtime
Expand Down Expand Up @@ -33,7 +32,7 @@
1. [Introduction to exceptional situations](./ExceptionalFlow/1-Exceptions-Intro.md)
2. [Architecture](./ExceptionalFlow/2-Exceptions-Architecture.md)
3. [Exceptions events](./ExceptionalFlow/3-Exceptions-Events.md)
4. Types of exceptional situations
4. [Types of exceptional situations](./ExceptionalFlow/4-Exceptions-Types.md)

# License

Expand Down
File renamed without changes.
6 changes: 5 additions & 1 deletion book/ru/Links.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@

1. [CLR via C#](https://www.amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454) by [Jeffrey Richter](https://github.com/JeffreyRichter)
2. [Matt Warren blog](https://mattwarren.org/)
3. [JetBrains Lifetime](https://www.jetbrains.com/help/resharper/sdk/Platform/Lifetime.html)
3. [JetBrains Lifetime](https://www.jetbrains.com/help/resharper/sdk/Platform/Lifetime.html)
4. [Pro .NET Memory Management](https://prodotnetmemory.com/) by [Konrad Kokosa](https://twitter.com/konradkokosa)
5. [Konrad Kokosa blog](http://tooslowexception.com)
5. [Yi Zhang](https://yizhang82.dev/)
6. [.NET official blog](https://devblogs.microsoft.com/dotnet/)
File renamed without changes.
167 changes: 167 additions & 0 deletions book/ru/Memory/01-02-MemoryManagement-Basics.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void Method2(int arg)

Те же самые процессы можно посмотреть на изображении:

![](../imgs/ThreadStack/AnyMethodCall.png)
![](./imgs/ThreadStack/AnyMethodCall.png)

Также замечу, что стек "растёт", начиная со старших адресов и заканчивая младшими, т.е. в обратную сторону.

Expand Down Expand Up @@ -173,27 +173,27 @@ ThreadPool -> MakeFork

Итак, как будет выглядеть стек потока, когда наш код вызовет MakeFork, который вызовет CloneThread, который уйдёт в unmanaged мир CLI/C++ и вызовет метод клонирование (саму реализацию) - там? Давайте посмотрим на схему (ещё раз напомню, что стек растёт от старших адресов к младшим. Справа налево):

![](../imgs/ThreadStack/step1.png)
![](./imgs/ThreadStack/step1.png)

Ну а для того чтобы не тащить всю простыню со схемы на схему, упростим, отбросив то, что нам не нужно:

![](../imgs/ThreadStack/step2.png)
![](./imgs/ThreadStack/step2.png)

Когда мы создадим поток либо возьмём готовый из пула потоков, в нашей схеме появляется ещё один стек, пока ещё ничем не проинициализированный:

![](../imgs/ThreadStack/step3.png)
![](./imgs/ThreadStack/step3.png)

Теперь наша задача - сымитировать запуск метода `Fork.CloneThread()` в новом потоке. Для этого мы должны в конец его стека потока дописать серию кадров: как будто из делегата, переданного ThreadPool'у был вызван `Fork.CloneThread()`, из которого через враппер C++ кода managed обёрткой был вызван CLI/C++ метод. Для этого мы просто скопируем необходимый участок стека в массив (замечу, что со склонированного участка на старый "смотрят" копии регистров EBP, обеспечивающих построение цепочки кадров):

![](../imgs/ThreadStack/step4.png)
![](./imgs/ThreadStack/step4.png)

Далее чтобы обеспечить целостность стека после операции копирования склонированного на предыдущем шаге участка, мы заранее рассчитываем, по каким адресам будут находиться поля `EBP` на новом месте, и сразу же исправляем их, прямо на копии:

![](../imgs/ThreadStack/step5.png)
![](./imgs/ThreadStack/step5.png)

Последним шагом, очень аккуратно, задействуя минимальное количество регистров, копируем наш массив в конец стека дочернего потока, после чего сдвигаем регистры ESP и EBP на новые места. С точки зрения стека мы сымитировали вызов всех этих методов:

![](../imgs/ThreadStack/step6.png)
![](./imgs/ThreadStack/step6.png)

Но пока не с точки зрения кода. С точки зрения кода нам надо попасть в те методы, которые только что создали. Самое простое - просто сымитировать выход из метода: восстановить `ESP` до `EBP`, в `EBP` положить то, на что он указывает и вызвать инструкцию `ret`, инициировав выход из якобы вызванного C++ метода клонирования потока, что приведёт к возврату в реальный wrapper CLI/C++ вызова, который вернёт управление в `MakeFork()`, но в дочернем потоке. Техника сработала.

Expand Down Expand Up @@ -516,11 +516,11 @@ RestorePointAfterClonnedExited:

Проверим? Это - скриншот до вызова клонирования потока:

![](../imgs/ThreadStack/ForkBeforeEnter.png)
![](./imgs/ThreadStack/ForkBeforeEnter.png)

И после:

![](../imgs/ThreadStack/ForkAfterEnter.png)
![](./imgs/ThreadStack/ForkAfterEnter.png)

Как мы видим, теперь вместо одного потока внутри ForkImpl мы видим два. И оба - вышли из этого метода.

Expand Down
Loading

0 comments on commit 80c0796

Please sign in to comment.