- PVSM.RU - https://www.pvsm.ru -
Перейду сразу к делу =) Задача: в любой точке кода путем вызова спец. метода создать второй поток, который начнет выполнение с точки вызова этого метода в родительском потоке, сохранив возможность отладки и значения всех локальных переменных на всех уровнях вызовов методов.
Реализация не зависит от конечной платформы (.Net/Java), т.к. написана на C++/Asm, однако пользовательский код сделан на C#, т.к. на нем пишу я.
Теперь, когда я наконец стабилизировал пример для 32-разрядных систем, набравшись храбрости, готов показать его общественности как полностью готовый. И, да, повторюсь: при адаптации будет работать на любой платформе
Целью работы является построение функционала, связанного с потоками, которое не предусмотрено операционной системой. Для примера был взят метод Fork() операционной системы Linux, исправленный для реалий OC Windows.
Итак, если у нас есть метод Original, внутри которого в некоторой его части вызывается метод Fork.CloneThread(), должен возникнуть второй поток исполнения, начало которого будет равным точке вызова метода Fork.CloneThread() и исполнение которого будет закончено на выходе из метода Original таким образом, чтобы во втором потоке исполнения были сохранены все значения локальных переменных исходного потока. Другими словами, чтобы вызов CloneThread() разделил текущий поток на два.
Материалы на подготовку:
Что у нас есть изначально? Есть наш поток. Также есть возможность создать новый поток либо запланировать задачу в пул потоков, выполнив там свой код. Также мы понимаем, что информация по вложенным вызовам хранится в стеке вызовов и что при желании мы можем ей манипулировать (например, используя C++/CLI). Причем, если следовать соглашениям и вписать в верхушку стека значение регистра EBP, адрес возврата для иснтрукции ret и выделить место под локальные (если необходимо), таким образом можно имитировать вызов метода.
Что же необходимо сделать чтобы склонировать поток?
Самое важное, для чего это делается — для закрепления понимания, как все работает и что если знать, можно этим начать манипулировать.
Ресурсы
Автор: sidristij
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/nenormal-noe-programmirovanie/70755
Ссылки в тексте:
[1] Call Stack (wiki): https://en.wikipedia.org/wiki/Call_stack
[2] Соглашения о вызове (wiki): https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%B3%D0%BB%D0%B0%D1%88%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B5
[3] GitHub проект DotNetEx: https://github.com/mumusan/dotnetex
[4] Источник: http://habrahabr.ru/post/238947/
Нажмите здесь для печати.