Я всегда считал это очень полезной функцией в Visual Studio. Для тех, кто не знает об этом, он позволяет редактировать код во время отладки запущенного процесса, повторно компилировать код пока двоичный файл все еще работает и продолжать беспрепятственно использовать приложение с новым кодом без необходимости его перезапуска.
Как реализована эта функция? Если код, который я изменяю, находится в DLL, загруженной приложением, приложение просто выгружает DLL и перезагружает ее снова? Мне может показаться, что это может вызвать проблемы с нестабильностью, поэтому я предполагаю, что это будет умнее этого. Есть идеи?





Мой угадать заключается в том, что он перекомпилирует приложение (и для небольших изменений это не означает, что придется перекомпилировать очень многое). Затем, поскольку Microsoft создает и компилятор, и отладчик, они могут гарантировать, как размещена память и тому подобное. Таким образом, они могут использовать API отладки для перезаписи сегментов кода новыми, если изменения достаточно малы.
Если изменения перенаправляют на совершенно новый код, он, очевидно, может быть загружен в память в том же стиле, что и библиотеки DLL.
У Microsoft также есть механизм «горячего исправления». Функции имеют двухбайтовую инструкцию no-op, обычно что-то вроде "mov edx, edx" перед любым реальным кодом. Это позволяет им чисто перенаправить выполнение функции. Это тоже может быть вариантом.
Главное помнить, что приложение не «запущено», все его потоки находятся в остановленном состоянии. Итак, что касается процесса, любые модификации, которые делает отладчик, полностью атомарны.
Конечно, это все домыслы;)
Согласно dumpbin, раздел ".textbss" помечен как неинициализированный и имеет права чтения + записи + выполнения, что делает его идеальным для хранения и выполнения динамически сгенерированного кода =)
Я предполагаю, что все объекты выровнены по границе памяти в 4096 байт. Поэтому, если вы внесете небольшие изменения в какой-либо код, объекты по-прежнему будут в этих границах и, следовательно, будут работать как раньше.
У меня были случаи, когда изменение пары строк приводило к полной перекомпиляции и линковке, и другие, когда довольно существенный рефакторинг функции работал нормально.
Просмотр кода с помощью отладчика, такого как ollydbg, показывает, что они не выровнены по границам страницы. Тем не менее, вероятно, добавлен некоторый отступ (небольшой), чтобы сделать возможными изменения большего размера.
Насколько я понимаю, когда приложение скомпилировано с включенной поддержкой Edit и Continue, компилятор оставляет дополнительное пространство вокруг функций в двоичном образе, чтобы можно было добавить дополнительный код. Затем отладчик может скомпилировать новую версию функции, заменить существующую версию (используя пространство для заполнения по мере необходимости), исправить стек, установить указатель инструкции и продолжить работу. Таким образом, вам не нужно исправлять указатели перехода, если у вас достаточно отступов.
Обратите внимание, что Edit and Continue обычно не работает с кодом в libs / dll, только с основным исполняемым кодом.
Мне нравится идея перенаправить выполнение функции во внешнее место. Когда я создаю exe с помощью «/ ZI», я вижу новый раздел «.textbss» в исполняемом файле, возможно, он используется для хранения отредактированного кода.