Как работает "Редактировать и продолжить" в Visual Studio?
Я всегда считал, что это очень полезная функция в Visual Studio. Для тех, кто не знает об этом, он позволяет редактировать код во время отладки запущенного процесса, повторно компилировать код, в то время как бинарный файл все еще работает, и продолжать использовать приложение без проблем с новым кодом, без необходимости перезапустите его.
Как эта функция реализована? Если код, который я модифицирую, находится в DLL, загруженной приложением, приложение просто выгружает DLL и перезагружает его снова? Мне кажется, что это будет связано с проблемами нестабильности, поэтому я предполагаю, что это было бы умнее этого. Любые идеи?
Ответы
Ответ 1
Я понимаю, что когда приложение скомпилировано с поддержкой редактирования и продолжения, компилятор оставляет дополнительную комнату вокруг функций в двоичном образе, чтобы добавить дополнительный код. Затем отладчик может скомпилировать новую версию функции, заменить существующую версию (используя при необходимости пробел), исправить стек, установить указатель инструкции и продолжить работу. Таким образом, вам не нужно фиксировать указатели перехода, если у вас достаточно отступов.
Обратите внимание, что Edit и Continue обычно не работают с кодом в библиотеках libs/dll, только с основным исполняемым кодом.
Ответ 2
Я предполагаю, что он перекомпилирует приложение (и для небольших изменений это не означает, что очень много пришлось бы перекомпилировать). Затем, поскольку Microsoft делает как компилятор, так и отладчик, они могут делать гарантии о том, как выкладываются память и т.д. Таким образом, они могут использовать API отладки для повторной записи сегментов кода с новыми, если изменения достаточно малы.
Если изменения перенаправляются на совершенно новый код, это, очевидно, может быть загружено в память в том же стиле, что и библиотеки DLL.
Microsoft также имеет механизм для "горячего исправления". Функции имеют двухбайтную инструкцию no-op, как правило, что-то вроде "mov edx, edx" перед любым реальным кодом. Это позволяет им перенаправлять выполнение функции чисто. Это может быть и вариант.
Главное, что нужно помнить, это то, что приложение не работает, все его потоки находятся в остановленном состоянии. Что касается процесса, то любые изменения, которые делает отладчик, являются полностью атомными.
Конечно, это все предположения;)
Ответ 3
Моя догадка - все объекты привязаны к границе памяти 4096 байт. Поэтому, если вы вносите небольшие изменения в какой-либо код, тогда объекты все равно будут находиться в пределах этих границ и, следовательно, будут выполняться по-прежнему.
У меня были экземпляры, в которых изменение пары строк вызовет полную перекомпиляцию и ссылку и другие, где довольно существенный рефакторинг функции будет очень хорош.